Browse Source

Merge pull request #279 from rathena/revert-264-cleanup/skill_db

Revert rathena/rathena#264 -- Skill DB clean up
- Reverted until further issues in the main pull request are resolved.
Aleos 10 years ago
parent
commit
fe3fccee73

+ 0 - 5
db/const.txt

@@ -4644,10 +4644,5 @@ BSF_REM_ON_MADOGEAR	0x080
 BSF_REM_ON_DAMAGED	0x100
 BSF_REM_ON_DAMAGED	0x100
 BSF_PERMANENT	0x200
 BSF_PERMANENT	0x200
 
 
-SKILL_PERM	0
-SKILL_TEMP	1
-SKILL_TEMPLEVEL	2
-SKILL_PERM_GRANT	3
-
 false	0
 false	0
 true	1
 true	1

+ 7 - 12
db/pre-re/skill_db.txt

@@ -504,7 +504,7 @@
 357,0,6,4,0,0x1,0,5,1,no,0,0,0,weapon,0,0x0,		LK_CONCENTRATION,Concentration
 357,0,6,4,0,0x1,0,5,1,no,0,0,0,weapon,0,0x0,		LK_CONCENTRATION,Concentration
 358,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0,		LK_TENSIONRELAX,Relax
 358,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0,		LK_TENSIONRELAX,Relax
 359,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0,		LK_BERSERK,Frenzy
 359,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0,		LK_BERSERK,Frenzy
-360,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0,	LK_FURY,Fury
+//360,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0,	LK_FURY,Fury
 
 
 //****
 //****
 // High Priest
 // High Priest
@@ -553,10 +553,10 @@
 //****
 //****
 // Whitesmith
 // Whitesmith
 384,0,0,4,0,0x1,0,10,1,yes,0,0,0,weapon,0,0x4000,	WS_MELTDOWN,Shattering Strike
 384,0,0,4,0,0x1,0,10,1,yes,0,0,0,weapon,0,0x4000,	WS_MELTDOWN,Shattering Strike
-385,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0,	WS_CREATECOIN,Create Coins
-386,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0,	WS_CREATENUGGET,Create Nuggets
+//385,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0,	WS_CREATECOIN,Create Coins
+//386,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0,	WS_CREATENUGGET,Create Nuggets
 387,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x4000,		WS_CARTBOOST,Cart Boost
 387,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x4000,		WS_CARTBOOST,Cart Boost
-388,9,6,2,0,0x1,0,5,1,no,0,0,0,none,0,0x0,		WS_SYSTEMCREATE,Auto Attack System
+//388,9,6,2,0,0x1,0,5,1,no,0,0,0,none,0,0x0,		WS_SYSTEMCREATE,Auto Attack System
 
 
 //****
 //****
 // Stalker
 // Stalker
@@ -768,11 +768,6 @@
 543,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,0x0,		NJ_NEN,Soul
 543,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,0x0,		NJ_NEN,Soul
 544,-5,6,1,0,0x40,0,10,1,no,0,0,0,weapon,0,0x0,	NJ_ISSEN,Final Strike
 544,-5,6,1,0,0x40,0,10,1,no,0,0,0,weapon,0,0x0,	NJ_ISSEN,Final Strike
 
 
-572,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0,		SL_DEATHKNIGHT,SL_DEATHKNIGHT
-573,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0,		SL_COLLECTOR,SL_COLLECTOR
-574,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0,		SL_NINJA,SL_NINJA
-575,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0,		SL_GUNNER,SL_GUNNER
-
 //****
 //****
 // Additional NPC Skills (Episode 11.3)
 // Additional NPC Skills (Episode 11.3)
 653,0,8,4,0,0x6,5:7:9:11:13:5:7:9:11:13,10,1,no,0,0x2,0,magic,0,0x0,	NPC_EARTHQUAKE,Earthquake
 653,0,8,4,0,0x6,5:7:9:11:13:5:7:9:11:13,10,1,no,0,0x2,0,magic,0,0x0,	NPC_EARTHQUAKE,Earthquake
@@ -823,12 +818,12 @@
 689,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x1000,	CASH_BLESSING,Party Blessing
 689,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x1000,	CASH_BLESSING,Party Blessing
 690,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x1000,	CASH_INCAGI,Party Increase AGI
 690,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x1000,	CASH_INCAGI,Party Increase AGI
 691,0,6,4,0,0x3,-1,5,1,yes,0,0x2,0,magic,0,0x0,	CASH_ASSUMPTIO,Party Assumptio
 691,0,6,4,0,0x3,-1,5,1,yes,0,0x2,0,magic,0,0x0,	CASH_ASSUMPTIO,Party Assumptio
-692,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_CATCRY,Cat Cry
+//692,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_CATCRY,Cat Cry
 693,0,6,4,0,0x3,-1,1,1,yes,0,0x2,0,magic,0,0x0,	ALL_PARTYFLEE,Party Flee
 693,0,6,4,0,0x3,-1,1,1,yes,0,0x2,0,magic,0,0x0,	ALL_PARTYFLEE,Party Flee
 //694,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_ANGEL_PROTECT,Angel's Protection
 //694,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_ANGEL_PROTECT,Angel's Protection
-695,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_DREAM_SUMMERNIGHT,Summer Night Dream
+//695,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_DREAM_SUMMERNIGHT,Summer Night Dream
 //696,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		NPC_CHANGEUNDEAD2,Change Undead
 //696,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		NPC_CHANGEUNDEAD2,Change Undead
-697,9,6,4,0,0x1,0,1,1,yes,0,0x2,0,magic,0,0x0,	ALL_REVERSEORCISH,Reverse Orcish
+//697,9,6,4,0,0x1,0,1,1,yes,0,0x2,0,magic,0,0x0,	ALL_REVERSEORCISH,Reverse Orcish
 698,0,6,4,0,0x01,0,1,1,no,0,0x2,0,none,0,0x0,		ALL_WEWISH,Christmas Carol
 698,0,6,4,0,0x01,0,1,1,no,0,0x2,0,none,0,0x0,		ALL_WEWISH,Christmas Carol
 //699,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_SONKRAN,ALL_SONKRAN
 //699,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_SONKRAN,ALL_SONKRAN
 
 

+ 7 - 12
db/re/skill_db.txt

@@ -504,7 +504,7 @@
 357,0,6,4,0,0x1,0,5,1,no,0,0,0,weapon,0,0x0,		LK_CONCENTRATION,Concentration
 357,0,6,4,0,0x1,0,5,1,no,0,0,0,weapon,0,0x0,		LK_CONCENTRATION,Concentration
 358,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0,		LK_TENSIONRELAX,Relax
 358,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0,		LK_TENSIONRELAX,Relax
 359,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0,		LK_BERSERK,Frenzy
 359,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0,		LK_BERSERK,Frenzy
-360,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0,	LK_FURY,Fury
+//360,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0,	LK_FURY,Fury
 
 
 //****
 //****
 // High Priest
 // High Priest
@@ -553,10 +553,10 @@
 //****
 //****
 // Whitesmith
 // Whitesmith
 384,0,0,4,0,0x1,0,10,1,yes,0,0,0,weapon,0,0x4000,	WS_MELTDOWN,Shattering Strike
 384,0,0,4,0,0x1,0,10,1,yes,0,0,0,weapon,0,0x4000,	WS_MELTDOWN,Shattering Strike
-385,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0,	WS_CREATECOIN,Create Coins
-386,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0,	WS_CREATENUGGET,Create Nuggets
+//385,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0,	WS_CREATECOIN,Create Coins
+//386,0,0,4,0,0x1,0,1,1,yes,0,0,0,none,0,0x0,	WS_CREATENUGGET,Create Nuggets
 387,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x4000,		WS_CARTBOOST,Cart Boost
 387,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x4000,		WS_CARTBOOST,Cart Boost
-388,9,6,2,0,0x1,0,5,1,no,0,0,0,none,0,0x0,		WS_SYSTEMCREATE,Auto Attack System
+//388,9,6,2,0,0x1,0,5,1,no,0,0,0,none,0,0x0,		WS_SYSTEMCREATE,Auto Attack System
 
 
 //****
 //****
 // Stalker
 // Stalker
@@ -768,11 +768,6 @@
 543,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,0x0,		NJ_NEN,Soul
 543,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,0x0,		NJ_NEN,Soul
 544,-5,8,1,0,0x40,0,10,1,no,0,0,0,misc,0,0x0,	NJ_ISSEN,Final Strike
 544,-5,8,1,0,0x40,0,10,1,no,0,0,0,misc,0,0x0,	NJ_ISSEN,Final Strike
 
 
-572,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0,		SL_DEATHKNIGHT,SL_DEATHKNIGHT
-573,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0,		SL_COLLECTOR,SL_COLLECTOR
-574,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0,		SL_NINJA,SL_NINJA
-575,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0,		SL_GUNNER,SL_GUNNER
-
 //****
 //****
 // Additional NPC Skills (Episode 11.3)
 // Additional NPC Skills (Episode 11.3)
 653,0,8,4,0,0x6,5:7:9:11:13:5:7:9:11:13,10,1,no,0,0x2,0,magic,0,0x0,	NPC_EARTHQUAKE,Earthquake
 653,0,8,4,0,0x6,5:7:9:11:13:5:7:9:11:13,10,1,no,0,0x2,0,magic,0,0x0,	NPC_EARTHQUAKE,Earthquake
@@ -823,10 +818,10 @@
 689,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x0,	CASH_BLESSING,Party Blessing
 689,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x0,	CASH_BLESSING,Party Blessing
 690,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x0,	CASH_INCAGI,Party Increase AGI
 690,0,6,4,0,0x3,-1,10,1,yes,0,0x2,0,magic,0,0x0,	CASH_INCAGI,Party Increase AGI
 691,0,6,4,0,0x3,-1,5,1,yes,0,0x2,0,magic,0,0x0,	CASH_ASSUMPTIO,Party Assumptio
 691,0,6,4,0,0x3,-1,5,1,yes,0,0x2,0,magic,0,0x0,	CASH_ASSUMPTIO,Party Assumptio
-692,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_CATCRY,Cat Cry
+//692,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_CATCRY,Cat Cry
 693,0,6,4,0,0x3,-1,1,1,yes,0,0x2,0,magic,0,0x0,	ALL_PARTYFLEE,Party Flee
 693,0,6,4,0,0x3,-1,1,1,yes,0,0x2,0,magic,0,0x0,	ALL_PARTYFLEE,Party Flee
-694,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_ANGEL_PROTECT,Angel's Protection
-695,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_DREAM_SUMMERNIGHT,Summer Night Dream
+//694,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_ANGEL_PROTECT,Angel's Protection
+//695,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		ALL_DREAM_SUMMERNIGHT,Summer Night Dream
 //696,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		NPC_CHANGEUNDEAD2,Change Undead
 //696,0,0,0,0,0,0,9,0,no,0,0x2,0,none,0,0x0,		NPC_CHANGEUNDEAD2,Change Undead
 697,9,6,4,0,0x1,0,1,1,yes,0,0x2,0,magic,0,0x0,		ALL_REVERSEORCISH,Reverse Orcish
 697,9,6,4,0,0x1,0,1,1,yes,0,0x2,0,magic,0,0x0,		ALL_REVERSEORCISH,Reverse Orcish
 698,0,6,4,0,0x01,0,1,1,no,0,0x2,0,none,0,0x0,		ALL_WEWISH,Christmas Carol
 698,0,6,4,0,0x01,0,1,1,no,0,0x2,0,none,0,0x0,		ALL_WEWISH,Christmas Carol

+ 1 - 7
doc/script_commands.txt

@@ -5411,15 +5411,9 @@ Flag 2 means that the level parameter is to be interpreted as a stackable
 additional bonus to the skill level. If the character did not have that skill 
 additional bonus to the skill level. If the character did not have that skill 
 previously, they will now at 0+the level given.
 previously, they will now at 0+the level given.
 
 
-Flag 3 is the same as flag 1 in that it saves to the database.  However, these skills
+Flag 4 is the same as flag 1 in that it saves to the database.  However, these skills
 are ignored when any action is taken that adjusts the skill tree (reset/job change).
 are ignored when any action is taken that adjusts the skill tree (reset/job change).
 
 
-Flag contants:
-	0 - SKILL_PERM
-	1 - SKILL_TEMP
-	2 - SKILL_TEMPLEVEL
-	3 - SKILL_PERM_GRANT
-
 // This will permanently give the character Stone Throw (TF_THROWSTONE,152), at 
 // This will permanently give the character Stone Throw (TF_THROWSTONE,152), at 
 // level 1.
 // level 1.
     skill 152,1,0;
     skill 152,1,0;

+ 1 - 1
npc/merchants/buying_shops.txt

@@ -225,7 +225,7 @@ alberta_in,58,52,4	script	Purchasing Team#Buying	59,{
 				mes "Okay, you're now approved to open the Bulk Buyer Shop.";
 				mes "Okay, you're now approved to open the Bulk Buyer Shop.";
 				set Zeny,Zeny-10000;
 				set Zeny,Zeny-10000;
 				getitem 6377,5; //Buy_Stall_Permit
 				getitem 6377,5; //Buy_Stall_Permit
-				skill "ALL_BUYING_STORE",1,SKILL_PERM_GRANT;
+				skill "ALL_BUYING_STORE",1,4;
 				next;
 				next;
 				mes "[Mr. Hugh]";
 				mes "[Mr. Hugh]";
 				mes "Currently, only normal items ^8C2121EXCEPT^000000 equipment, certain potions, and hand-crafted items can be purchased in bulk, but this can still be very beneficial to you, depending on how you use it.";
 				mes "Currently, only normal items ^8C2121EXCEPT^000000 equipment, certain potions, and hand-crafted items can be purchased in bulk, but this can still be very beneficial to you, depending on how you use it.";

+ 2 - 2
npc/other/gympass.txt

@@ -79,7 +79,7 @@ payon,173,141,4	script	Ripped Cabus#GymPass	899,{
 				mes "training together like this.";
 				mes "training together like this.";
 				delitem 7776,1; //Max_Weight_Up_Scroll
 				delitem 7776,1; //Max_Weight_Up_Scroll
 				set gympassmemory,.@add_carry;
 				set gympassmemory,.@add_carry;
-				skill "ALL_INCCARRY",.@add_carry,SKILL_PERM_GRANT;
+				skill "ALL_INCCARRY",.@add_carry,4;
 				close;
 				close;
 			}
 			}
 			else {
 			else {
@@ -135,7 +135,7 @@ payon,173,141,4	script	Ripped Cabus#GymPass	899,{
 			mes "muscles grew back,";
 			mes "muscles grew back,";
 			mes "just like that! Try not to";
 			mes "just like that! Try not to";
 			mes "wimp out again, okay?";
 			mes "wimp out again, okay?";
-			skill "ALL_INCCARRY",gympassmemory,SKILL_PERM_GRANT;
+			skill "ALL_INCCARRY",gympassmemory,4;
 			close;
 			close;
 		}
 		}
 		else {
 		else {

+ 0 - 6
sql-files/upgrades/upgrade_20150131_skillset.sql

@@ -1,6 +0,0 @@
--- Resetting all `lv` of skills that has `flag` >= 3 (the skill that its `learned_lv` has been changed by script or special case by `learned_lv` + SKILL_FLAG_REPLACED_LV_0)
--- If there's ALL_INCCARRY and ALL_BUYING_STORE, set the `flag` to SKILL_FLAG_PERM_GRANTED (new value is 3), those are exclusive skills given in our official scripts!
-
-UPDATE `skill` SET `lv` = `flag` - 3 WHERE `flag` >= 3;
-UPDATE `skill` SET `flag` = 0 WHERE `flag` >= 3;
-UPDATE `skill` SET `flag` = 3 WHERE `id` = 681 OR `id` = 2535;

+ 26 - 25
src/char/char.c

@@ -434,6 +434,12 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
 		strcat(save_status, " memo");
 		strcat(save_status, " memo");
 	}
 	}
 
 
+	//FIXME: is this neccessary? [ultramage]
+	for(i=0;i<MAX_SKILL;i++)
+		if ((p->skill[i].lv != 0) && (p->skill[i].id == 0))
+			p->skill[i].id = i; // Fix skill tree
+
+
 	//skills
 	//skills
 	if( memcmp(p->skill, cp->skill, sizeof(p->skill)) )
 	if( memcmp(p->skill, cp->skill, sizeof(p->skill)) )
 	{
 	{
@@ -938,6 +944,7 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) {
 //=====================================================================================================
 //=====================================================================================================
 int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_everything) {
 int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_everything) {
 	int i,j;
 	int i,j;
+	char t_msg[128] = "";
 	struct mmo_charstatus* cp;
 	struct mmo_charstatus* cp;
 	StringBuf buf;
 	StringBuf buf;
 	SqlStmt* stmt;
 	SqlStmt* stmt;
@@ -947,13 +954,11 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
 	struct point tmp_point;
 	struct point tmp_point;
 	struct item tmp_item;
 	struct item tmp_item;
 	struct s_skill tmp_skill;
 	struct s_skill tmp_skill;
-	uint16 skill_count = 0;
 	struct s_friend tmp_friend;
 	struct s_friend tmp_friend;
 #ifdef HOTKEY_SAVING
 #ifdef HOTKEY_SAVING
 	struct hotkey tmp_hotkey;
 	struct hotkey tmp_hotkey;
 	int hotkey_num;
 	int hotkey_num;
 #endif
 #endif
-	StringBuf msg_buf;
 
 
 	memset(p, 0, sizeof(struct mmo_charstatus));
 	memset(p, 0, sizeof(struct mmo_charstatus));
 
 
@@ -1060,13 +1065,11 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
 		p->save_point.y = MAP_DEFAULT_Y;
 		p->save_point.y = MAP_DEFAULT_Y;
 	}
 	}
 
 
-	StringBuf_Init(&msg_buf);
-	StringBuf_AppendStr(&msg_buf, " status");
+	strcat(t_msg, " status");
 
 
 	if (!load_everything) // For quick selection of data when displaying the char menu
 	if (!load_everything) // For quick selection of data when displaying the char menu
 	{
 	{
 		SqlStmt_Free(stmt);
 		SqlStmt_Free(stmt);
-		StringBuf_Destroy(&msg_buf);
 		return 1;
 		return 1;
 	}
 	}
 
 
@@ -1085,7 +1088,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
 		tmp_point.map = mapindex_name2id(point_map);
 		tmp_point.map = mapindex_name2id(point_map);
 		memcpy(&p->memo_point[i], &tmp_point, sizeof(tmp_point));
 		memcpy(&p->memo_point[i], &tmp_point, sizeof(tmp_point));
 	}
 	}
-	StringBuf_AppendStr(&msg_buf, " memo");
+	strcat(t_msg, " memo");
 
 
 	//read inventory
 	//read inventory
 	//`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, `expire_time`, `favorite`, `unique_id`)
 	//`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, `expire_time`, `favorite`, `unique_id`)
@@ -1117,7 +1120,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
 	for( i = 0; i < MAX_INVENTORY && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
 	for( i = 0; i < MAX_INVENTORY && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
 		memcpy(&p->inventory[i], &tmp_item, sizeof(tmp_item));
 		memcpy(&p->inventory[i], &tmp_item, sizeof(tmp_item));
 
 
-	StringBuf_AppendStr(&msg_buf, " inventory");
+	strcat(t_msg, " inventory");
 
 
 	//read cart
 	//read cart
 	//`cart_inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, expire_time`, `unique_id`)
 	//`cart_inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, expire_time`, `unique_id`)
@@ -1147,34 +1150,33 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
 
 
 	for( i = 0; i < MAX_CART && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
 	for( i = 0; i < MAX_CART && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
 		memcpy(&p->cart[i], &tmp_item, sizeof(tmp_item));
 		memcpy(&p->cart[i], &tmp_item, sizeof(tmp_item));
-	StringBuf_AppendStr(&msg_buf, " cart");
+	strcat(t_msg, " cart");
 
 
 	//read storage
 	//read storage
 	storage_fromsql(p->account_id, &p->storage);
 	storage_fromsql(p->account_id, &p->storage);
-	StringBuf_AppendStr(&msg_buf, " storage");
+	strcat(t_msg, " storage");
 
 
 	//read skill
 	//read skill
 	//`skill` (`char_id`, `id`, `lv`)
 	//`skill` (`char_id`, `id`, `lv`)
 	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `id`, `lv`,`flag` FROM `%s` WHERE `char_id`=? LIMIT %d", schema_config.skill_db, MAX_SKILL)
 	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `id`, `lv`,`flag` FROM `%s` WHERE `char_id`=? LIMIT %d", schema_config.skill_db, MAX_SKILL)
-		||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
-		||	SQL_ERROR == SqlStmt_Execute(stmt)
-		||	SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_UINT16, &tmp_skill.id  , 0, NULL, NULL)
-		||	SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_UINT8 , &tmp_skill.lv  , 0, NULL, NULL)
-		||	SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UINT8 , &tmp_skill.flag, 0, NULL, NULL) )
+	||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
+	||	SQL_ERROR == SqlStmt_Execute(stmt)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_USHORT, &tmp_skill.id  , 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_UCHAR , &tmp_skill.lv  , 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UCHAR , &tmp_skill.flag, 0, NULL, NULL) )
 		SqlStmt_ShowDebug(stmt);
 		SqlStmt_ShowDebug(stmt);
 
 
 	if( tmp_skill.flag != SKILL_FLAG_PERM_GRANTED )
 	if( tmp_skill.flag != SKILL_FLAG_PERM_GRANTED )
 		tmp_skill.flag = SKILL_FLAG_PERMANENT;
 		tmp_skill.flag = SKILL_FLAG_PERMANENT;
 
 
-	for( i = 0; skill_count < MAX_SKILL && SQL_SUCCESS == SqlStmt_NextRow(stmt); i++ ) {
-		if( tmp_skill.id > 0 && tmp_skill.id < MAX_SKILL_ID ) {
-			memcpy(&p->skill[i], &tmp_skill, sizeof(tmp_skill));
-			skill_count++;
-		}
+	for( i = 0; i < MAX_SKILL && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
+	{
+		if( tmp_skill.id < ARRAYLENGTH(p->skill) )
+			memcpy(&p->skill[tmp_skill.id], &tmp_skill, sizeof(tmp_skill));
 		else
 		else
 			ShowWarning("mmo_char_fromsql: ignoring invalid skill (id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", tmp_skill.id, tmp_skill.lv, p->name, p->account_id, p->char_id);
 			ShowWarning("mmo_char_fromsql: ignoring invalid skill (id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", tmp_skill.id, tmp_skill.lv, p->name, p->account_id, p->char_id);
 	}
 	}
-	StringBuf_Printf(&msg_buf, " %d skills", skill_count);
+	strcat(t_msg, " skills");
 
 
 	//read friends
 	//read friends
 	//`friends` (`char_id`, `friend_account`, `friend_id`)
 	//`friends` (`char_id`, `friend_account`, `friend_id`)
@@ -1188,7 +1190,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
 
 
 	for( i = 0; i < MAX_FRIENDS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
 	for( i = 0; i < MAX_FRIENDS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
 		memcpy(&p->friends[i], &tmp_friend, sizeof(tmp_friend));
 		memcpy(&p->friends[i], &tmp_friend, sizeof(tmp_friend));
-	StringBuf_AppendStr(&msg_buf, " friends");
+	strcat(t_msg, " friends");
 
 
 #ifdef HOTKEY_SAVING
 #ifdef HOTKEY_SAVING
 	//read hotkeys
 	//read hotkeys
@@ -1209,21 +1211,20 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
 		else
 		else
 			ShowWarning("mmo_char_fromsql: ignoring invalid hotkey (hotkey=%d,type=%u,id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", hotkey_num, tmp_hotkey.type, tmp_hotkey.id, tmp_hotkey.lv, p->name, p->account_id, p->char_id);
 			ShowWarning("mmo_char_fromsql: ignoring invalid hotkey (hotkey=%d,type=%u,id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", hotkey_num, tmp_hotkey.type, tmp_hotkey.id, tmp_hotkey.lv, p->name, p->account_id, p->char_id);
 	}
 	}
-	StringBuf_AppendStr(&msg_buf, " hotkeys");
+	strcat(t_msg, " hotkeys");
 #endif
 #endif
 
 
 	/* Mercenary Owner DataBase */
 	/* Mercenary Owner DataBase */
 	mercenary_owner_fromsql(char_id, p);
 	mercenary_owner_fromsql(char_id, p);
-	StringBuf_AppendStr(&msg_buf, " mercenary");
+	strcat(t_msg, " mercenary");
 
 
 
 
-	if (charserv_config.save_log) ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, StringBuf_Value(&msg_buf));	//ok. all data load successfuly!
+	if (charserv_config.save_log) ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, t_msg);	//ok. all data load successfuly!
 	SqlStmt_Free(stmt);
 	SqlStmt_Free(stmt);
 	StringBuf_Destroy(&buf);
 	StringBuf_Destroy(&buf);
 
 
 	cp = idb_ensure(char_db_, char_id, char_create_charstatus);
 	cp = idb_ensure(char_db_, char_id, char_create_charstatus);
 	memcpy(cp, p, sizeof(struct mmo_charstatus));
 	memcpy(cp, p, sizeof(struct mmo_charstatus));
-	StringBuf_Destroy(&msg_buf);
 	return 1;
 	return 1;
 }
 }
 
 

+ 8 - 10
src/common/mmo.h

@@ -54,7 +54,7 @@
 #define MAX_BANK_ZENY SINT32_MAX ///Max zeny in Bank
 #define MAX_BANK_ZENY SINT32_MAX ///Max zeny in Bank
 #define MAX_FAME 1000000000 ///Max fame points
 #define MAX_FAME 1000000000 ///Max fame points
 #define MAX_CART 100 ///Maximum item in cart
 #define MAX_CART 100 ///Maximum item in cart
-#define MAX_SKILL 1200 ///Maximum skill can be hold by Player, Homunculus, & Mercenary (skill list) AND skill_db limit
+#define MAX_SKILL 5020 ///Maximum skill data
 #define GLOBAL_REG_NUM 256 ///Max permanent character variables per char
 #define GLOBAL_REG_NUM 256 ///Max permanent character variables per char
 #define ACCOUNT_REG_NUM 64 ///Max permanent local account variables per account
 #define ACCOUNT_REG_NUM 64 ///Max permanent local account variables per account
 #define ACCOUNT_REG2_NUM 16 ///Max permanent global account variables per account
 #define ACCOUNT_REG2_NUM 16 ///Max permanent global account variables per account
@@ -223,11 +223,10 @@ enum e_skill_flag
 	SKILL_FLAG_PERMANENT,
 	SKILL_FLAG_PERMANENT,
 	SKILL_FLAG_TEMPORARY,
 	SKILL_FLAG_TEMPORARY,
 	SKILL_FLAG_PLAGIARIZED,
 	SKILL_FLAG_PLAGIARIZED,
-	SKILL_FLAG_PERM_GRANTED, // Permanent, granted through someway e.g. script
-	SKILL_FLAG_TMP_COMBO, //@FIXME for homunculus combo atm
-
-	//! NOTE: This flag be the last flag, and don't change the value if not needed!
-	SKILL_FLAG_REPLACED_LV_0 = 10, // temporary skill overshadowing permanent skill of level 'N - SKILL_FLAG_REPLACED_LV_0',
+	SKILL_FLAG_REPLACED_LV_0, // temporary skill overshadowing permanent skill of level 'N - SKILL_FLAG_REPLACED_LV_0',
+	SKILL_FLAG_PERM_GRANTED, // permanent, granted through someway e.g. script
+	SKILL_FLAG_TMP_COMBO, //@FIXME for homon combo atm
+	//...
 };
 };
 
 
 enum e_mmo_charstatus_opt {
 enum e_mmo_charstatus_opt {
@@ -237,9 +236,9 @@ enum e_mmo_charstatus_opt {
 };
 };
 
 
 struct s_skill {
 struct s_skill {
-	uint16 id;
-	uint8 lv;
-	uint8 flag; // see enum e_skill_flag
+	unsigned short id;
+	unsigned char lv;
+	unsigned char flag; // see enum e_skill_flag
 };
 };
 
 
 struct global_reg {
 struct global_reg {
@@ -625,7 +624,6 @@ enum e_guild_skill {
 	GD_MAX,
 	GD_MAX,
 };
 };
 
 
-#define MAX_SKILL_ID GD_MAX
 
 
 //These mark the ID of the jobs, as expected by the client. [Skotlex]
 //These mark the ID of the jobs, as expected by the client. [Skotlex]
 enum e_job {
 enum e_job {

+ 19 - 24
src/map/atcommand.c

@@ -32,7 +32,6 @@
 #include "trade.h"
 #include "trade.h"
 #include "mapreg.h"
 #include "mapreg.h"
 #include "quest.h"
 #include "quest.h"
-#include "pc.h"
 
 
 #include <stdlib.h>
 #include <stdlib.h>
 #include <math.h>
 #include <math.h>
@@ -3251,7 +3250,7 @@ ACMD_FUNC(questskill)
 
 
 		return -1;
 		return -1;
 	}
 	}
-	if (skill_id >= MAX_SKILL_ID) {
+	if (skill_id >= MAX_SKILL_DB) {
 		clif_displaymessage(fd, msg_txt(sd,198)); // This skill number doesn't exist.
 		clif_displaymessage(fd, msg_txt(sd,198)); // This skill number doesn't exist.
 		return -1;
 		return -1;
 	}
 	}
@@ -3264,7 +3263,7 @@ ACMD_FUNC(questskill)
 		return -1;
 		return -1;
 	}
 	}
 
 
-	pc_skill(sd, skill_id, 1, ADDSKILL_PERMANENT);
+	pc_skill(sd, skill_id, 1, 0);
 	clif_displaymessage(fd, msg_txt(sd,70)); // You have learned the skill.
 	clif_displaymessage(fd, msg_txt(sd,70)); // You have learned the skill.
 
 
 	return 0;
 	return 0;
@@ -3275,7 +3274,7 @@ ACMD_FUNC(questskill)
  *------------------------------------------*/
  *------------------------------------------*/
 ACMD_FUNC(lostskill)
 ACMD_FUNC(lostskill)
 {
 {
-	uint16 skill_id = 0, sk_idx = 0;
+	uint16 skill_id;
 	nullpo_retr(-1, sd);
 	nullpo_retr(-1, sd);
 
 
 	if (!message || !*message || (skill_id = atoi(message)) <= 0)
 	if (!message || !*message || (skill_id = atoi(message)) <= 0)
@@ -3295,7 +3294,7 @@ ACMD_FUNC(lostskill)
 
 
 		return -1;
 		return -1;
 	}
 	}
-	if (!(sk_idx = skill_get_index(skill_id))) {
+	if (skill_id >= MAX_SKILL) {
 		clif_displaymessage(fd, msg_txt(sd,198)); // This skill number doesn't exist.
 		clif_displaymessage(fd, msg_txt(sd,198)); // This skill number doesn't exist.
 		return -1;
 		return -1;
 	}
 	}
@@ -3308,8 +3307,8 @@ ACMD_FUNC(lostskill)
 		return -1;
 		return -1;
 	}
 	}
 
 
-	sd->status.skill[sk_idx].lv = 0;
-	sd->status.skill[sk_idx].flag = SKILL_FLAG_PERMANENT;
+	sd->status.skill[skill_id].lv = 0;
+	sd->status.skill[skill_id].flag = SKILL_FLAG_PERMANENT;
 	clif_deleteskill(sd,skill_id);
 	clif_deleteskill(sd,skill_id);
 	clif_displaymessage(fd, msg_txt(sd,71)); // You have forgotten the skill.
 	clif_displaymessage(fd, msg_txt(sd,71)); // You have forgotten the skill.
 
 
@@ -5508,11 +5507,11 @@ ACMD_FUNC(skillid) {
 
 
 	for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) ) {
 	for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) ) {
 		int idx = skill_get_index(db_data2i(data));
 		int idx = skill_get_index(db_data2i(data));
-		if (strnicmp(key.str, message, skillen) == 0 || strnicmp(skill_db[idx]->desc, message, skillen) == 0) {
-			sprintf(atcmd_output, msg_txt(sd,1164), db_data2i(data), skill_db[idx]->desc, key.str); // skill %d: %s (%s)
+		if (strnicmp(key.str, message, skillen) == 0 || strnicmp(skill_db[idx].desc, message, skillen) == 0) {
+			sprintf(atcmd_output, msg_txt(sd,1164), db_data2i(data), skill_db[idx].desc, key.str); // skill %d: %s (%s)
 			clif_displaymessage(fd, atcmd_output);
 			clif_displaymessage(fd, atcmd_output);
-		} else if ( found < MAX_SKILLID_PARTIAL_RESULTS && ( stristr(key.str,message) || stristr(skill_db[idx]->desc,message) ) ) {
-			snprintf(partials[found++], MAX_SKILLID_PARTIAL_RESULTS_LEN, msg_txt(sd,1164), db_data2i(data), skill_db[idx]->desc, key.str);
+		} else if ( found < MAX_SKILLID_PARTIAL_RESULTS && ( stristr(key.str,message) || stristr(skill_db[idx].desc,message) ) ) {
+			snprintf(partials[found++], MAX_SKILLID_PARTIAL_RESULTS_LEN, msg_txt(sd,1164), db_data2i(data), skill_db[idx].desc, key.str);
 		}
 		}
 	}
 	}
 
 
@@ -5560,7 +5559,7 @@ ACMD_FUNC(useskill)
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if (SKILL_CHK_HOMUN(skill_id)
+	if (skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE+MAX_HOMUNSKILL
 		&& sd->hd && hom_is_active(sd->hd)) // (If used with @useskill, put the homunc as dest)
 		&& sd->hd && hom_is_active(sd->hd)) // (If used with @useskill, put the homunc as dest)
 		bl = &sd->hd->bl;
 		bl = &sd->hd->bl;
 	else
 	else
@@ -5644,7 +5643,7 @@ ACMD_FUNC(skilltree)
 	{
 	{
 		if( ent->need[j].id && pc_checkskill(sd,ent->need[j].id) < ent->need[j].lv)
 		if( ent->need[j].id && pc_checkskill(sd,ent->need[j].id) < ent->need[j].lv)
 		{
 		{
-			sprintf(atcmd_output, msg_txt(sd,1170), ent->need[j].lv, skill_db[ent->need[j].id]->desc); // Player requires level %d of skill %s.
+			sprintf(atcmd_output, msg_txt(sd,1170), ent->need[j].lv, skill_db[ent->need[j].id].desc); // Player requires level %d of skill %s.
 			clif_displaymessage(fd, atcmd_output);
 			clif_displaymessage(fd, atcmd_output);
 			meets = 0;
 			meets = 0;
 		}
 		}
@@ -9119,14 +9118,13 @@ ACMD_FUNC(unloadnpcfile) {
 	return 0;
 	return 0;
 }
 }
 ACMD_FUNC(cart) {
 ACMD_FUNC(cart) {
-#define MC_CART_MDFY(idx, x) \
-	sd->status.skill[(idx)].id = x?MC_PUSHCART:0; \
-	sd->status.skill[(idx)].lv = x?1:0; \
-	sd->status.skill[(idx)].flag = x?SKILL_FLAG_TEMPORARY:SKILL_FLAG_PERMANENT;
+#define MC_CART_MDFY(x) \
+	sd->status.skill[MC_PUSHCART].id = x?MC_PUSHCART:0; \
+	sd->status.skill[MC_PUSHCART].lv = x?1:0; \
+	sd->status.skill[MC_PUSHCART].flag = x?SKILL_FLAG_TEMPORARY:SKILL_FLAG_PERMANENT;
 
 
 	int val = atoi(message);
 	int val = atoi(message);
 	bool need_skill = (pc_checkskill(sd, MC_PUSHCART) == 0);
 	bool need_skill = (pc_checkskill(sd, MC_PUSHCART) == 0);
-	uint16 sk_idx = 0;
 
 
 	if( !message || !*message || val < 0 || val > MAX_CARTS ) {
 	if( !message || !*message || val < 0 || val > MAX_CARTS ) {
 		sprintf(atcmd_output, msg_txt(sd,1390),command,MAX_CARTS); // Unknown Cart (usage: %s <0-%d>).
 		sprintf(atcmd_output, msg_txt(sd,1390),command,MAX_CARTS); // Unknown Cart (usage: %s <0-%d>).
@@ -9139,22 +9137,19 @@ ACMD_FUNC(cart) {
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if (!(sk_idx = skill_get_index(MC_PUSHCART)))
-		return -1;
-
 	if( need_skill ) {
 	if( need_skill ) {
-		MC_CART_MDFY(sk_idx,1);
+		MC_CART_MDFY(1);
 	}
 	}
 
 
 	if( !pc_setcart(sd, val) ) {
 	if( !pc_setcart(sd, val) ) {
 		if( need_skill ) {
 		if( need_skill ) {
-			MC_CART_MDFY(sk_idx,0);
+			MC_CART_MDFY(0);
 		}
 		}
 		return -1;/* @cart failed */
 		return -1;/* @cart failed */
 	}
 	}
 
 
 	if( need_skill ) {
 	if( need_skill ) {
-		MC_CART_MDFY(sk_idx,0);
+		MC_CART_MDFY(0);
 	}
 	}
 
 
 	clif_displaymessage(fd, msg_txt(sd,1392)); // Cart Added
 	clif_displaymessage(fd, msg_txt(sd,1392)); // Cart Added

+ 6 - 7
src/map/battle.c

@@ -1883,10 +1883,10 @@ static int battle_skill_damage_skill(struct block_list *src, struct block_list *
 	struct s_skill_damage *damage = NULL;
 	struct s_skill_damage *damage = NULL;
 	struct map_data *mapd = &map[m];
 	struct map_data *mapd = &map[m];
 
 
-	if (!idx || !skill_db[idx]->damage.map)
+	if (!idx || !skill_db[idx].damage.map)
 		return 0;
 		return 0;
 
 
-	damage = &skill_db[idx]->damage;
+	damage = &skill_db[idx].damage;
 
 
 	//check the adjustment works for specified type
 	//check the adjustment works for specified type
 	if (!battle_skill_damage_iscaster(damage->caster, src->type))
 	if (!battle_skill_damage_iscaster(damage->caster, src->type))
@@ -6945,12 +6945,11 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
 		}
 		}
 	}
 	}
 	if (sd) {
 	if (sd) {
-		uint16 r_skill = 0, sk_idx = 0;
 		if( wd.flag&BF_SHORT && sc && sc->data[SC__AUTOSHADOWSPELL] && rnd()%100 < sc->data[SC__AUTOSHADOWSPELL]->val3 &&
 		if( wd.flag&BF_SHORT && sc && sc->data[SC__AUTOSHADOWSPELL] && rnd()%100 < sc->data[SC__AUTOSHADOWSPELL]->val3 &&
-			(r_skill = (uint16)sc->data[SC__AUTOSHADOWSPELL]->val1) && (sk_idx = skill_get_index(r_skill)) &&
-			sd->status.skill[sk_idx].id != 0 && sd->status.skill[sk_idx].flag == SKILL_FLAG_PLAGIARIZED )
+			sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].id != 0 && sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].flag == SKILL_FLAG_PLAGIARIZED )
 		{
 		{
-			int r_lv = sc->data[SC__AUTOSHADOWSPELL]->val2;
+			int r_skill = sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].id,
+				r_lv = sc->data[SC__AUTOSHADOWSPELL]->val2;
 
 
 			if (r_skill != AL_HOLYLIGHT && r_skill != PR_MAGNUS) {
 			if (r_skill != AL_HOLYLIGHT && r_skill != PR_MAGNUS) {
 				int type;
 				int type;
@@ -7790,7 +7789,7 @@ static const struct _battle_data {
 	{ "show_hp_sp_gain",                    &battle_config.show_hp_sp_gain,                 1,      0,      1,              },
 	{ "show_hp_sp_gain",                    &battle_config.show_hp_sp_gain,                 1,      0,      1,              },
 	{ "mob_npc_event_type",                 &battle_config.mob_npc_event_type,              1,      0,      1,              },
 	{ "mob_npc_event_type",                 &battle_config.mob_npc_event_type,              1,      0,      1,              },
 	{ "character_size",                     &battle_config.character_size,                  1|2,    0,      1|2,            },
 	{ "character_size",                     &battle_config.character_size,                  1|2,    0,      1|2,            },
-	{ "mob_max_skilllvl",                   &battle_config.mob_max_skilllvl,                MAX_MOBSKILL_LEVEL, 1, MAX_MOBSKILL_LEVEL, },
+	{ "mob_max_skilllvl",                   &battle_config.mob_max_skilllvl,                MAX_SKILL_LEVEL, 1, MAX_SKILL_LEVEL, },
 	{ "retaliate_to_master",                &battle_config.retaliate_to_master,             1,      0,      1,              },
 	{ "retaliate_to_master",                &battle_config.retaliate_to_master,             1,      0,      1,              },
 	{ "rare_drop_announce",                 &battle_config.rare_drop_announce,              0,      0,      10000,          },
 	{ "rare_drop_announce",                 &battle_config.rare_drop_announce,              0,      0,      10000,          },
 	{ "duel_allow_pvp",                     &battle_config.duel_allow_pvp,                  0,      0,      1,              },
 	{ "duel_allow_pvp",                     &battle_config.duel_allow_pvp,                  0,      0,      1,              },

+ 11 - 13
src/map/chrif.c

@@ -951,21 +951,19 @@ int chrif_changedsex(int fd) {
 		if ((sd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER) {
 		if ((sd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER) {
 			int i;
 			int i;
 			// remove specifical skills of Bard classes
 			// remove specifical skills of Bard classes
-			for(i = BA_MUSICALLESSON; i <= BA_APPLEIDUN; i++) {
-				uint16 sk_idx = skill_get_index(i);
-				if (sd->status.skill[sk_idx].id > 0 && sd->status.skill[sk_idx].flag == SKILL_FLAG_PERMANENT) {
-					sd->status.skill_point += sd->status.skill[sk_idx].lv;
-					sd->status.skill[sk_idx].id = 0;
-					sd->status.skill[sk_idx].lv = 0;
+			for(i = 315; i <= 322; i++) {
+				if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
+					sd->status.skill_point += sd->status.skill[i].lv;
+					sd->status.skill[i].id = 0;
+					sd->status.skill[i].lv = 0;
 				}
 				}
 			}
 			}
 			// remove specifical skills of Dancer classes
 			// remove specifical skills of Dancer classes
-			for(i = DC_DANCINGLESSON; i <= DC_SERVICEFORYOU; i++) {
-				uint16 sk_idx = skill_get_index(i);
-				if (sd->status.skill[sk_idx].id > 0 && sd->status.skill[sk_idx].flag == SKILL_FLAG_PERMANENT) {
-					sd->status.skill_point += sd->status.skill[sk_idx].lv;
-					sd->status.skill[sk_idx].id = 0;
-					sd->status.skill[sk_idx].lv = 0;
+			for(i = 323; i <= 330; i++) {
+				if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
+					sd->status.skill_point += sd->status.skill[i].lv;
+					sd->status.skill[i].id = 0;
+					sd->status.skill[i].lv = 0;
 				}
 				}
 			}
 			}
 			clif_updatestatus(sd, SP_SKILLPOINT);
 			clif_updatestatus(sd, SP_SKILLPOINT);
@@ -1032,7 +1030,7 @@ int chrif_divorceack(uint32 char_id, int partner_id) {
  *------------------------------------------*/
  *------------------------------------------*/
 int chrif_deadopt(int father_id, int mother_id, int child_id) {
 int chrif_deadopt(int father_id, int mother_id, int child_id) {
 	struct map_session_data* sd;
 	struct map_session_data* sd;
-	uint16 idx = skill_get_index(WE_CALLBABY);
+	int idx = skill_get_index(WE_CALLBABY);
 
 
 	if( father_id && ( sd = map_charid2sd(father_id) ) != NULL && sd->status.child == child_id ) {
 	if( father_id && ( sd = map_charid2sd(father_id) ) != NULL && sd->status.child == child_id ) {
 		sd->status.child = 0;
 		sd->status.child = 0;

+ 45 - 62
src/map/clif.c

@@ -1486,7 +1486,7 @@ int clif_homskillinfoblock(struct map_session_data *sd)
 {	//[orn]
 {	//[orn]
 	struct homun_data *hd;
 	struct homun_data *hd;
 	int fd = sd->fd;
 	int fd = sd->fd;
-	int i, len=4;
+	int i,j,len=4;
 	WFIFOHEAD(fd, 4+37*MAX_HOMUNSKILL);
 	WFIFOHEAD(fd, 4+37*MAX_HOMUNSKILL);
 
 
 	hd = sd->hd;
 	hd = sd->hd;
@@ -1498,17 +1498,15 @@ int clif_homskillinfoblock(struct map_session_data *sd)
 		int id = hd->homunculus.hskill[i].id;
 		int id = hd->homunculus.hskill[i].id;
 		if( id != 0 ){
 		if( id != 0 ){
 			int combo = (hd->homunculus.hskill[i].flag)&SKILL_FLAG_TMP_COMBO;
 			int combo = (hd->homunculus.hskill[i].flag)&SKILL_FLAG_TMP_COMBO;
-			short idx = hom_skill_get_index(id);
-			if (idx == -1)
-				continue;
+			j = id - HM_SKILLBASE;
 			WFIFOW(fd,len  ) = id;
 			WFIFOW(fd,len  ) = id;
 			WFIFOW(fd,len+2) = ((combo)?INF_SELF_SKILL:skill_get_inf(id));
 			WFIFOW(fd,len+2) = ((combo)?INF_SELF_SKILL:skill_get_inf(id));
 			WFIFOW(fd,len+4) = 0;
 			WFIFOW(fd,len+4) = 0;
-			WFIFOW(fd,len+6) = hd->homunculus.hskill[idx].lv;
-			WFIFOW(fd,len+8) = skill_get_sp(id,hd->homunculus.hskill[idx].lv);
-			WFIFOW(fd,len+10)= skill_get_range2(&sd->hd->bl, id,hd->homunculus.hskill[idx].lv);
+			WFIFOW(fd,len+6) = hd->homunculus.hskill[j].lv;
+			WFIFOW(fd,len+8) = skill_get_sp(id,hd->homunculus.hskill[j].lv);
+			WFIFOW(fd,len+10)= skill_get_range2(&sd->hd->bl, id,hd->homunculus.hskill[j].lv);
 			safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
 			safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
-			WFIFOB(fd,len+36) = (hd->homunculus.hskill[idx].lv < hom_skill_tree_get_max(id, hd->homunculus.class_))?1:0;
+			WFIFOB(fd,len+36) = (hd->homunculus.hskill[j].lv < hom_skill_tree_get_max(id, hd->homunculus.class_))?1:0;
 			len+=37;
 			len+=37;
 		}
 		}
 	}
 	}
@@ -1521,15 +1519,12 @@ int clif_homskillinfoblock(struct map_session_data *sd)
 void clif_homskillup(struct map_session_data *sd, uint16 skill_id)
 void clif_homskillup(struct map_session_data *sd, uint16 skill_id)
 {	//[orn]
 {	//[orn]
 	struct homun_data *hd;
 	struct homun_data *hd;
-	int fd;
-	short idx = -1;
+	int fd, idx;
 	nullpo_retv(sd);
 	nullpo_retv(sd);
+	idx = skill_id - HM_SKILLBASE;
 
 
-	if ((idx = hom_skill_get_index(skill_id) == -1))
-		return;
-
-	fd = sd->fd;
-	hd = sd->hd;
+	fd=sd->fd;
+	hd=sd->hd;
 
 
 	WFIFOHEAD(fd, packet_len(0x239));
 	WFIFOHEAD(fd, packet_len(0x239));
 	WFIFOW(fd,0) = 0x239;
 	WFIFOW(fd,0) = 0x239;
@@ -4822,9 +4817,8 @@ void clif_skillinfoblock(struct map_session_data *sd)
 
 
 	nullpo_retv(sd);
 	nullpo_retv(sd);
 
 
-	fd = sd->fd;
-	if (!fd)
-		return;
+	fd=sd->fd;
+	if (!fd) return;
 
 
 	WFIFOHEAD(fd, MAX_SKILL * 37 + 4);
 	WFIFOHEAD(fd, MAX_SKILL * 37 + 4);
 	WFIFOW(fd,0) = 0x10f;
 	WFIFOW(fd,0) = 0x10f;
@@ -4868,30 +4862,28 @@ void clif_skillinfoblock(struct map_session_data *sd)
 
 
 /// Adds new skill to the skill tree (ZC_ADD_SKILL).
 /// Adds new skill to the skill tree (ZC_ADD_SKILL).
 /// 0111 <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <skill name>.24B <upgradable>.B
 /// 0111 <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <skill name>.24B <upgradable>.B
-void clif_addskill(struct map_session_data *sd, int skill_id)
+void clif_addskill(struct map_session_data *sd, int id)
 {
 {
 	int fd;
 	int fd;
-	uint16 idx = 0;
 
 
 	nullpo_retv(sd);
 	nullpo_retv(sd);
 
 
 	fd = sd->fd;
 	fd = sd->fd;
-	if (!fd || !(idx = skill_get_index(skill_id)))
-		return;
+	if (!fd) return;
 
 
-	if( sd->status.skill[idx].id <= 0 )
+	if( sd->status.skill[id].id <= 0 )
 		return;
 		return;
 
 
 	WFIFOHEAD(fd, packet_len(0x111));
 	WFIFOHEAD(fd, packet_len(0x111));
 	WFIFOW(fd,0) = 0x111;
 	WFIFOW(fd,0) = 0x111;
-	WFIFOW(fd,2) = skill_id;
-	WFIFOL(fd,4) = skill_get_inf(skill_id);
-	WFIFOW(fd,8) = sd->status.skill[idx].lv;
-	WFIFOW(fd,10) = skill_get_sp(skill_id,sd->status.skill[idx].lv);
-	WFIFOW(fd,12)= skill_get_range2(&sd->bl, skill_id,sd->status.skill[idx].lv);
-	safestrncpy((char*)WFIFOP(fd,14), skill_get_name(skill_id), NAME_LENGTH);
-	if( sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT )
-		WFIFOB(fd,38) = (sd->status.skill[idx].lv < skill_tree_get_max(skill_id, sd->status.class_))? 1:0;
+	WFIFOW(fd,2) = id;
+	WFIFOL(fd,4) = skill_get_inf(id);
+	WFIFOW(fd,8) = sd->status.skill[id].lv;
+	WFIFOW(fd,10) = skill_get_sp(id,sd->status.skill[id].lv);
+	WFIFOW(fd,12)= skill_get_range2(&sd->bl, id,sd->status.skill[id].lv);
+	safestrncpy((char*)WFIFOP(fd,14), skill_get_name(id), NAME_LENGTH);
+	if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT )
+		WFIFOB(fd,38) = (sd->status.skill[id].lv < skill_tree_get_max(id, sd->status.class_))? 1:0;
 	else
 	else
 		WFIFOB(fd,38) = 0;
 		WFIFOB(fd,38) = 0;
 	WFIFOSET(fd,packet_len(0x111));
 	WFIFOSET(fd,packet_len(0x111));
@@ -4900,21 +4892,18 @@ void clif_addskill(struct map_session_data *sd, int skill_id)
 
 
 /// Deletes a skill from the skill tree (ZC_SKILLINFO_DELETE).
 /// Deletes a skill from the skill tree (ZC_SKILLINFO_DELETE).
 /// 0441 <skill id>.W
 /// 0441 <skill id>.W
-void clif_deleteskill(struct map_session_data *sd, int skill_id)
+void clif_deleteskill(struct map_session_data *sd, int id)
 {
 {
 #if PACKETVER >= 20081217
 #if PACKETVER >= 20081217
 	int fd;
 	int fd;
-	uint16 idx = 0;
 
 
 	nullpo_retv(sd);
 	nullpo_retv(sd);
-
 	fd = sd->fd;
 	fd = sd->fd;
-	if (!fd || !(idx = skill_get_index(skill_id)))
-		return;
+	if( !fd ) return;
 
 
 	WFIFOHEAD(fd,packet_len(0x441));
 	WFIFOHEAD(fd,packet_len(0x441));
 	WFIFOW(fd,0) = 0x441;
 	WFIFOW(fd,0) = 0x441;
-	WFIFOW(fd,2) = skill_id;
+	WFIFOW(fd,2) = id;
 	WFIFOSET(fd,packet_len(0x441));
 	WFIFOSET(fd,packet_len(0x441));
 #endif
 #endif
 	clif_skillinfoblock(sd);
 	clif_skillinfoblock(sd);
@@ -4923,7 +4912,7 @@ void clif_deleteskill(struct map_session_data *sd, int skill_id)
 /// Updates a skill in the skill tree (ZC_SKILLINFO_UPDATE).
 /// Updates a skill in the skill tree (ZC_SKILLINFO_UPDATE).
 /// 010e <skill id>.W <level>.W <sp cost>.W <attack range>.W <upgradable>.B
 /// 010e <skill id>.W <level>.W <sp cost>.W <attack range>.W <upgradable>.B
 void clif_skillup(struct map_session_data *sd, uint16 skill_id, int lv, int range, int upgradable) {
 void clif_skillup(struct map_session_data *sd, uint16 skill_id, int lv, int range, int upgradable) {
-	int fd;
+    int fd;
 
 
 	nullpo_retv(sd);
 	nullpo_retv(sd);
 
 
@@ -4941,22 +4930,19 @@ void clif_skillup(struct map_session_data *sd, uint16 skill_id, int lv, int rang
 
 
 /// Updates a skill in the skill tree (ZC_SKILLINFO_UPDATE2).
 /// Updates a skill in the skill tree (ZC_SKILLINFO_UPDATE2).
 /// 07e1 <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <upgradable>.B
 /// 07e1 <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <upgradable>.B
-void clif_skillinfo(struct map_session_data *sd,int skill_id, int inf)
+void clif_skillinfo(struct map_session_data *sd,int skill, int inf)
 {
 {
 	const int fd = sd->fd;
 	const int fd = sd->fd;
-	uint16 idx = skill_get_index(skill_id);
-	if (!idx)
-		return;
 
 
 	WFIFOHEAD(fd,packet_len(0x7e1));
 	WFIFOHEAD(fd,packet_len(0x7e1));
 	WFIFOW(fd,0) = 0x7e1;
 	WFIFOW(fd,0) = 0x7e1;
-	WFIFOW(fd,2) = skill_id;
-	WFIFOL(fd,4) = inf?inf:skill_get_inf(skill_id);
-	WFIFOW(fd,8) = sd->status.skill[idx].lv;
-	WFIFOW(fd,10) = skill_get_sp(skill_id,sd->status.skill[idx].lv);
-	WFIFOW(fd,12) = skill_get_range2(&sd->bl,skill_id,sd->status.skill[idx].lv);
-	if( sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT )
-		WFIFOB(fd,14) = (sd->status.skill[idx].lv < skill_tree_get_max(skill_id, sd->status.class_))? 1:0;
+	WFIFOW(fd,2) = skill;
+	WFIFOL(fd,4) = inf?inf:skill_get_inf(skill);
+	WFIFOW(fd,8) = sd->status.skill[skill].lv;
+	WFIFOW(fd,10) = skill_get_sp(skill,sd->status.skill[skill].lv);
+	WFIFOW(fd,12) = skill_get_range2(&sd->bl,skill,sd->status.skill[skill].lv);
+	if( sd->status.skill[skill].flag == SKILL_FLAG_PERMANENT )
+		WFIFOB(fd,14) = (sd->status.skill[skill].lv < skill_tree_get_max(skill, sd->status.class_))? 1:0;
 	else
 	else
 		WFIFOB(fd,14) = 0;
 		WFIFOB(fd,14) = 0;
 	WFIFOSET(fd,packet_len(0x7e1));
 	WFIFOSET(fd,packet_len(0x7e1));
@@ -11380,12 +11366,12 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
 	if (tmp&INF_GROUND_SKILL || !tmp)
 	if (tmp&INF_GROUND_SKILL || !tmp)
 		return; //Using a ground/passive skill on a target? WRONG.
 		return; //Using a ground/passive skill on a target? WRONG.
 
 
-	if( SKILL_CHK_HOMUN(skill_id) ) {
+	if( skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE + MAX_HOMUNSKILL ) {
 		clif_parse_UseSkillToId_homun(sd->hd, sd, tick, skill_id, skill_lv, target_id);
 		clif_parse_UseSkillToId_homun(sd->hd, sd, tick, skill_id, skill_lv, target_id);
 		return;
 		return;
 	}
 	}
 
 
-	if( SKILL_CHK_MERC(skill_id) ) {
+	if( skill_id >= MC_SKILLBASE && skill_id < MC_SKILLBASE + MAX_MERCSKILL ) {
 		clif_parse_UseSkillToId_mercenary(sd->md, sd, tick, skill_id, skill_lv, target_id);
 		clif_parse_UseSkillToId_mercenary(sd->md, sd, tick, skill_id, skill_lv, target_id);
 		return;
 		return;
 	}
 	}
@@ -11454,7 +11440,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
 
 
 	sd->skillitem = sd->skillitemlv = 0;
 	sd->skillitem = sd->skillitemlv = 0;
 
 
-	if( SKILL_CHK_GUILD(skill_id) ) {
+	if( skill_id >= GD_SKILLBASE ) {
 		if( sd->state.gmaster_flag )
 		if( sd->state.gmaster_flag )
 			skill_lv = guild_checkskill(sd->guild, skill_id);
 			skill_lv = guild_checkskill(sd->guild, skill_id);
 		else
 		else
@@ -11481,12 +11467,12 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin
 	if( !(skill_get_inf(skill_id)&INF_GROUND_SKILL) )
 	if( !(skill_get_inf(skill_id)&INF_GROUND_SKILL) )
 		return; //Using a target skill on the ground? WRONG.
 		return; //Using a target skill on the ground? WRONG.
 
 
-	if( SKILL_CHK_HOMUN(skill_id) ) {
+	if( skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE + MAX_HOMUNSKILL ) {
 		clif_parse_UseSkillToPos_homun(sd->hd, sd, tick, skill_id, skill_lv, x, y, skillmoreinfo);
 		clif_parse_UseSkillToPos_homun(sd->hd, sd, tick, skill_id, skill_lv, x, y, skillmoreinfo);
 		return;
 		return;
 	}
 	}
 
 
-	if( SKILL_CHK_MERC(skill_id) ) {
+	if( skill_id >= MC_SKILLBASE && skill_id < MC_SKILLBASE + MAX_MERCSKILL ) {
 		clif_parse_UseSkillToPos_mercenary(sd->md, sd, tick, skill_id, skill_lv, x, y, skillmoreinfo);
 		clif_parse_UseSkillToPos_mercenary(sd->md, sd, tick, skill_id, skill_lv, x, y, skillmoreinfo);
 		return;
 		return;
 	}
 	}
@@ -15695,18 +15681,15 @@ void clif_mercenary_skillblock(struct map_session_data *sd)
 	WFIFOW(fd,0) = 0x29d;
 	WFIFOW(fd,0) = 0x29d;
 	for( i = 0; i < MAX_MERCSKILL; i++ )
 	for( i = 0; i < MAX_MERCSKILL; i++ )
 	{
 	{
-		uint16 id;
-		short idx = -1;
+		int id, j;
 		if( (id = md->db->skill[i].id) == 0 )
 		if( (id = md->db->skill[i].id) == 0 )
 			continue;
 			continue;
-		if ((idx = mercenary_skill_get_index(id)) == -1)
-			continue;
-
+		j = id - MC_SKILLBASE;
 		WFIFOW(fd,len) = id;
 		WFIFOW(fd,len) = id;
 		WFIFOL(fd,len+2) = skill_get_inf(id);
 		WFIFOL(fd,len+2) = skill_get_inf(id);
-		WFIFOW(fd,len+6) = md->db->skill[idx].lv;
-		WFIFOW(fd,len+8) = skill_get_sp(id, md->db->skill[idx].lv);
-		WFIFOW(fd,len+10) = skill_get_range2(&md->bl, id, md->db->skill[idx].lv);
+		WFIFOW(fd,len+6) = md->db->skill[j].lv;
+		WFIFOW(fd,len+8) = skill_get_sp(id, md->db->skill[j].lv);
+		WFIFOW(fd,len+10) = skill_get_range2(&md->bl, id, md->db->skill[j].lv);
 		safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
 		safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
 		WFIFOB(fd,len+36) = 0; // Skillable for Mercenary?
 		WFIFOB(fd,len+36) = 0; // Skillable for Mercenary?
 		len += 37;
 		len += 37;

+ 3 - 3
src/map/clif.h

@@ -532,9 +532,9 @@ void clif_class_change(struct block_list *bl,int class_,int type);
 
 
 void clif_skillinfoblock(struct map_session_data *sd);
 void clif_skillinfoblock(struct map_session_data *sd);
 void clif_skillup(struct map_session_data *sd, uint16 skill_id, int lv, int range, int upgradable);
 void clif_skillup(struct map_session_data *sd, uint16 skill_id, int lv, int range, int upgradable);
-void clif_skillinfo(struct map_session_data *sd,int skill_id, int inf);
-void clif_addskill(struct map_session_data *sd, int skill_id);
-void clif_deleteskill(struct map_session_data *sd, int skill_id);
+void clif_skillinfo(struct map_session_data *sd,int skill, int inf);
+void clif_addskill(struct map_session_data *sd, int id);
+void clif_deleteskill(struct map_session_data *sd, int id);
 
 
 void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, uint16 skill_id, int property, int casttime);
 void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, uint16 skill_id, int property, int casttime);
 void clif_skillcastcancel(struct block_list* bl);
 void clif_skillcastcancel(struct block_list* bl);

+ 8 - 10
src/map/elemental.c

@@ -9,7 +9,6 @@
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
 #include "../common/random.h"
 #include "../common/random.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
-#include "../common/utils.h"
 
 
 #include "log.h"
 #include "log.h"
 #include "clif.h"
 #include "clif.h"
@@ -559,12 +558,13 @@ struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16
 	memset(&req,0,sizeof(req));
 	memset(&req,0,sizeof(req));
 
 
 	if( idx == 0 ) // invalid skill id
 	if( idx == 0 ) // invalid skill id
-		return req;
+  		return req;
 
 
-	skill_lv = cap_value(skill_lv, 1, MAX_SKILL_LEVEL);
+	if( skill_lv < 1 || skill_lv > MAX_SKILL_LEVEL )
+		return req;
 
 
-	req.hp = skill_db[idx]->require.hp[skill_lv-1];
-	req.sp = skill_db[idx]->require.sp[skill_lv-1];
+	req.hp = skill_db[idx].require.hp[skill_lv-1];
+	req.sp = skill_db[idx].require.sp[skill_lv-1];
 
 
 	return req;
 	return req;
 }
 }
@@ -815,7 +815,6 @@ void read_elementaldb(void) {
 	uint8 i;
 	uint8 i;
 
 
 	elemental_count = 0;
 	elemental_count = 0;
-	memset(elemental_db, 0, sizeof(elemental_db));
 	for(i = 0; i<ARRAYLENGTH(filename); i++){
 	for(i = 0; i<ARRAYLENGTH(filename); i++){
 		sv_readdb(db_path, filename[i], ',', 26, 26, -1, &read_elementaldb_sub, i);
 		sv_readdb(db_path, filename[i], ',', 26, 26, -1, &read_elementaldb_sub, i);
 	}
 	}
@@ -826,8 +825,7 @@ void read_elementaldb(void) {
 * ElementalID,SkillID,SkillLevel,ReqMode
 * ElementalID,SkillID,SkillLevel,ReqMode
 */
 */
 static bool read_elemental_skilldb_sub(char* str[], int columns, int current) {
 static bool read_elemental_skilldb_sub(char* str[], int columns, int current) {
-	uint16 class_ = atoi(str[0]), skill_id, skill_lv, skillmode;
-	uint8 i;
+	uint16 class_ = atoi(str[0]), i, skill_id, skill_lv, skillmode;
 	struct s_elemental_db *db;
 	struct s_elemental_db *db;
 
 
 	ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, class_ == elemental_db[i].class_);
 	ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, class_ == elemental_db[i].class_);
@@ -837,8 +835,8 @@ static bool read_elemental_skilldb_sub(char* str[], int columns, int current) {
 	}
 	}
 
 
 	skill_id = atoi(str[1]);
 	skill_id = atoi(str[1]);
-	if( !SKILL_CHK_ELEM(skill_id) ) {
-		ShowError("read_elemental_skilldb_sub: Invalid Elemental skill '%d'.\n", skill_id);
+	if( skill_id < EL_SKILLBASE || skill_id >= EL_SKILLBASE + MAX_ELEMENTALSKILL ) {
+		ShowError("read_elemental_skilldb_sub: Skill out of range, line %d.\n", current);
 		return false;
 		return false;
 	}
 	}
 
 

+ 40 - 55
src/map/guild.c

@@ -64,20 +64,6 @@ static int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data
 struct npc_data **guild_flags;
 struct npc_data **guild_flags;
 unsigned short guild_flags_count;
 unsigned short guild_flags_count;
 
 
-/**
- * Get guild skill index in guild_skill_tree
- * @param skill_id
- * @return Index in skill_tree or -1
- **/
-static short guild_skill_get_index(uint16 skill_id) {
-	if (!SKILL_CHK_GUILD(skill_id))
-		return -1;
-	skill_id -= GD_SKILLBASE;
-	if (skill_id >= MAX_GUILDSKILL)
-		return -1;
-	return skill_id;
-}
-
 /*==========================================
 /*==========================================
  * Retrieves and validates the sd pointer for this guild member [Skotlex]
  * Retrieves and validates the sd pointer for this guild member [Skotlex]
  *------------------------------------------*/
  *------------------------------------------*/
@@ -98,41 +84,44 @@ static TBL_PC* guild_sd_check(int guild_id, uint32 account_id, uint32 char_id) {
 
 
  // Modified [Komurka]
  // Modified [Komurka]
 int guild_skill_get_max (int id) {
 int guild_skill_get_max (int id) {
-	if ((id = guild_skill_get_index(id)) < 0)
+	if (id < GD_SKILLBASE || id >= GD_SKILLBASE+MAX_GUILDSKILL)
 		return 0;
 		return 0;
-	return guild_skill_tree[id].max;
+	return guild_skill_tree[id-GD_SKILLBASE].max;
 }
 }
 
 
 // Retrive skill_lv learned by guild
 // Retrive skill_lv learned by guild
 
 
 int guild_checkskill(struct guild *g, int id) {
 int guild_checkskill(struct guild *g, int id) {
-	if ((id = guild_skill_get_index(id)) < 0)
+	int idx = id - GD_SKILLBASE;
+	if (idx < 0 || idx >= MAX_GUILDSKILL)
 		return 0;
 		return 0;
-	return g->skill[id].lv;
+	return g->skill[idx].lv;
 }
 }
 
 
 /*==========================================
 /*==========================================
  * guild_skill_tree.txt reading - from jA [Komurka]
  * guild_skill_tree.txt reading - from jA [Komurka]
  *------------------------------------------*/
  *------------------------------------------*/
 static bool guild_read_guildskill_tree_db(char* split[], int columns, int current) {// <skill id>,<max lv>,<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5>
 static bool guild_read_guildskill_tree_db(char* split[], int columns, int current) {// <skill id>,<max lv>,<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5>
-	int k, skill_id = atoi(split[0]);
-	short idx = -1;
+	int k, id, skill_id;
 
 
-	if ((idx = guild_skill_get_index(skill_id)) < 0) {
-		ShowError("guild_read_guildskill_tree_db: Invalid Guild skill '%s'.\n", split[1]);
+	skill_id = atoi(split[0]);
+	id = skill_id - GD_SKILLBASE;
+
+	if( id < 0 || id >= MAX_GUILDSKILL ) 	{
+		ShowWarning("guild_read_guildskill_tree_db: Invalid skill id %d.\n", skill_id);
 		return false;
 		return false;
 	}
 	}
 
 
-	guild_skill_tree[idx].id = skill_id;
-	guild_skill_tree[idx].max = atoi(split[1]);
+	guild_skill_tree[id].id = skill_id;
+	guild_skill_tree[id].max = atoi(split[1]);
 
 
-	if( guild_skill_tree[idx].id == GD_GLORYGUILD && battle_config.require_glory_guild && guild_skill_tree[idx].max == 0 ) 	{// enable guild's glory when required for emblems
-		guild_skill_tree[idx].max = 1;
+	if( guild_skill_tree[id].id == GD_GLORYGUILD && battle_config.require_glory_guild && guild_skill_tree[id].max == 0 ) 	{// enable guild's glory when required for emblems
+		guild_skill_tree[id].max = 1;
 	}
 	}
 
 
 	for( k = 0; k < MAX_GUILD_SKILL_REQUIRE; k++ ) 	{
 	for( k = 0; k < MAX_GUILD_SKILL_REQUIRE; k++ ) 	{
-		guild_skill_tree[idx].need[k].id = atoi(split[k*2+2]);
-		guild_skill_tree[idx].need[k].lv = atoi(split[k*2+3]);
+		guild_skill_tree[id].need[k].id = atoi(split[k*2+2]);
+		guild_skill_tree[id].need[k].lv = atoi(split[k*2+3]);
 	}
 	}
 
 
 	return true;
 	return true;
@@ -142,13 +131,13 @@ static bool guild_read_guildskill_tree_db(char* split[], int columns, int curren
  * Guild skill check - from jA [Komurka]
  * Guild skill check - from jA [Komurka]
  *------------------------------------------*/
  *------------------------------------------*/
 int guild_check_skill_require(struct guild *g,int id) {
 int guild_check_skill_require(struct guild *g,int id) {
-	uint8 i;
-	short idx = -1;
+	int i;
+	int idx = id-GD_SKILLBASE;
 
 
 	if(g == NULL)
 	if(g == NULL)
 		return 0;
 		return 0;
 
 
-	if ((idx = guild_skill_get_index(id)) < 0)
+	if (idx < 0 || idx >= MAX_GUILDSKILL)
 		return 0;
 		return 0;
 
 
 	for(i=0;i<MAX_GUILD_SKILL_REQUIRE;i++)
 	for(i=0;i<MAX_GUILD_SKILL_REQUIRE;i++)
@@ -1268,41 +1257,37 @@ int guild_getexp(struct map_session_data *sd,int exp) {
 /*====================================================
 /*====================================================
  * Ask to increase guildskill skill_id
  * Ask to increase guildskill skill_id
  *---------------------------------------------------*/
  *---------------------------------------------------*/
-void guild_skillup(TBL_PC* sd, uint16 skill_id) {
+int guild_skillup(TBL_PC* sd, uint16 skill_id) {
 	struct guild* g;
 	struct guild* g;
-	short idx = guild_skill_get_index(skill_id);
-	short max = 0;
-
-	nullpo_retv(sd);
-
-	if (idx == -1)
-		return;
+	int idx = skill_id - GD_SKILLBASE;
+	int max = guild_skill_get_max(skill_id);
 
 
-	if( sd->status.guild_id == 0 || (g=sd->guild) == NULL || // no guild
-		strcmp(sd->status.name, g->master) ) // not the guild master
-		return;
+	nullpo_ret(sd);
 
 
-	max = guild_skill_get_max(skill_id);
+	if( idx < 0 || idx >= MAX_GUILDSKILL || // not a guild skill
+			sd->status.guild_id == 0 || (g=sd->guild) == NULL || // no guild
+			strcmp(sd->status.name, g->master) ) // not the guild master
+		return 0;
 
 
 	if( g->skill_point > 0 &&
 	if( g->skill_point > 0 &&
-		g->skill[idx].id != 0 &&
-		g->skill[idx].lv < max )
+			g->skill[idx].id != 0 &&
+			g->skill[idx].lv < max )
 		intif_guild_skillup(g->guild_id, skill_id, sd->status.account_id, max);
 		intif_guild_skillup(g->guild_id, skill_id, sd->status.account_id, max);
+
+	return 0;
 }
 }
 
 
 /*====================================================
 /*====================================================
  * Notification of guildskill skill_id increase request
  * Notification of guildskill skill_id increase request
  *---------------------------------------------------*/
  *---------------------------------------------------*/
 int guild_skillupack(int guild_id,uint16 skill_id,uint32 account_id) {
 int guild_skillupack(int guild_id,uint16 skill_id,uint32 account_id) {
-	struct map_session_data *sd = map_id2sd(account_id);
-	struct guild *g = guild_search(guild_id);
+	struct map_session_data *sd=map_id2sd(account_id);
+	struct guild *g=guild_search(guild_id);
 	int i;
 	int i;
-	short idx = guild_skill_get_index(skill_id);
-
-	if (g == NULL || idx == -1)
+	if(g==NULL)
 		return 0;
 		return 0;
-	if (sd != NULL) {
-		int lv = g->skill[idx].lv;
+	if( sd != NULL ) {
+		int lv = g->skill[skill_id-GD_SKILLBASE].lv;
 		int range = skill_get_range(skill_id, lv);
 		int range = skill_get_range(skill_id, lv);
 		clif_skillup(sd,skill_id,lv,range,1);
 		clif_skillup(sd,skill_id,lv,range,1);
 
 
@@ -1312,14 +1297,14 @@ int guild_skillupack(int guild_id,uint16 skill_id,uint32 account_id) {
 			case GD_GLORYWOUNDS:
 			case GD_GLORYWOUNDS:
 			case GD_SOULCOLD:
 			case GD_SOULCOLD:
 			case GD_HAWKEYES:
 			case GD_HAWKEYES:
-					guild_guildaura_refresh(sd,skill_id,g->skill[idx].lv);
+					guild_guildaura_refresh(sd,skill_id,g->skill[skill_id-GD_SKILLBASE].lv);
 				break;
 				break;
 		}
 		}
 	}
 	}
 
 
 	// Inform all members
 	// Inform all members
-	for (i = 0; i < g->max_member; i++)
-		if ((sd = g->member[i].sd) != NULL)
+	for(i=0;i<g->max_member;i++)
+		if((sd=g->member[i].sd)!=NULL)
 			clif_guild_skillinfo(sd);
 			clif_guild_skillinfo(sd);
 
 
 	return 0;
 	return 0;

+ 1 - 1
src/map/guild.h

@@ -60,7 +60,7 @@ int guild_member_withdraw(int guild_id,uint32 account_id,uint32 char_id,int flag
 	const char *name,const char *mes);
 	const char *name,const char *mes);
 int guild_expulsion(struct map_session_data *sd,int guild_id,
 int guild_expulsion(struct map_session_data *sd,int guild_id,
 	uint32 account_id,uint32 char_id,const char *mes);
 	uint32 account_id,uint32 char_id,const char *mes);
-void guild_skillup(struct map_session_data* sd, uint16 skill_id);
+int guild_skillup(struct map_session_data* sd, uint16 skill_id);
 void guild_block_skill(struct map_session_data *sd, int time);
 void guild_block_skill(struct map_session_data *sd, int time);
 int guild_reqalliance(struct map_session_data *sd,struct map_session_data *tsd);
 int guild_reqalliance(struct map_session_data *sd,struct map_session_data *tsd);
 int guild_reply_reqalliance(struct map_session_data *sd,uint32 account_id,int flag);
 int guild_reply_reqalliance(struct map_session_data *sd,uint32 account_id,int flag);

+ 24 - 24
src/map/homunculus.c

@@ -38,11 +38,10 @@ static struct view_data hom_viewdb[MAX_HOMUNCULUS_CLASS];
 * @param skill_id
 * @param skill_id
 * @return -1 if invalid skill or skill index for homunculus skill_tree
 * @return -1 if invalid skill or skill index for homunculus skill_tree
 */
 */
-short hom_skill_get_index(uint16 skill_id) {
-	if (!SKILL_CHK_HOMUN(skill_id))
+static short hom_skill_get_index(int skill_id) {
+	if (!skill_get_index(skill_id))
 		return -1;
 		return -1;
-	skill_id -= HM_SKILLBASE;
-	if (skill_id >= MAX_HOMUNSKILL)
+	if ((skill_id -= HM_SKILLBASE) < 0 || skill_id >= MAX_HOMUNSKILL)
 		return -1;
 		return -1;
 	return skill_id;
 	return skill_id;
 }
 }
@@ -125,8 +124,8 @@ int hom_class2mapid(int hom_class)
 void hom_addspiritball(TBL_HOM *hd, int max) {
 void hom_addspiritball(TBL_HOM *hd, int max) {
 	nullpo_retv(hd);
 	nullpo_retv(hd);
 
 
-	if (max > MAX_SPIRITBALL)
-		max = MAX_SPIRITBALL;
+	if (max > MAX_SKILL_LEVEL)
+		max = MAX_SKILL_LEVEL;
 	if (hd->homunculus.spiritball < 0)
 	if (hd->homunculus.spiritball < 0)
 		hd->homunculus.spiritball = 0;
 		hd->homunculus.spiritball = 0;
 
 
@@ -153,8 +152,8 @@ void hom_delspiritball(TBL_HOM *hd, int count, int type) {
 	}
 	}
 	if (count <= 0)
 	if (count <= 0)
 		return;
 		return;
-	if (count > MAX_SPIRITBALL)
-		count = MAX_SPIRITBALL;
+	if (count > MAX_SKILL_LEVEL)
+		count = MAX_SKILL_LEVEL;
 	if (count > hd->homunculus.spiritball)
 	if (count > hd->homunculus.spiritball)
 		count = hd->homunculus.spiritball;
 		count = hd->homunculus.spiritball;
 
 
@@ -269,7 +268,7 @@ void hom_calc_skilltree(struct homun_data *hd, int flag_evolve)
 	/* load previous homunculus form skills first. */
 	/* load previous homunculus form skills first. */
 	if (hd->homunculus.prev_class != 0 && (c = hom_class2index(hd->homunculus.prev_class)) >= 0) {
 	if (hd->homunculus.prev_class != 0 && (c = hom_class2index(hd->homunculus.prev_class)) >= 0) {
 		for (i = 0; i < MAX_SKILL_TREE && (skill_id = hskill_tree[c][i].id) > 0; i++) {
 		for (i = 0; i < MAX_SKILL_TREE && (skill_id = hskill_tree[c][i].id) > 0; i++) {
-			short idx = hom_skill_get_index(skill_id);
+			int idx = hom_skill_get_index(skill_id);
 			if (idx < 0)
 			if (idx < 0)
 				continue;
 				continue;
 			if (hd->homunculus.hskill[idx].id)
 			if (hd->homunculus.hskill[idx].id)
@@ -297,7 +296,7 @@ void hom_calc_skilltree(struct homun_data *hd, int flag_evolve)
 
 
 	for (i = 0; i < MAX_SKILL_TREE && (skill_id = hskill_tree[c][i].id) > 0; i++) {
 	for (i = 0; i < MAX_SKILL_TREE && (skill_id = hskill_tree[c][i].id) > 0; i++) {
 		int intimacy;
 		int intimacy;
-		short idx = hom_skill_get_index(skill_id);
+		int idx = hom_skill_get_index(skill_id);
 		if (idx < 0)
 		if (idx < 0)
 			continue;
 			continue;
 		if (hd->homunculus.hskill[idx].id)
 		if (hd->homunculus.hskill[idx].id)
@@ -332,7 +331,7 @@ void hom_calc_skilltree(struct homun_data *hd, int flag_evolve)
 */
 */
 short hom_checkskill(struct homun_data *hd,uint16 skill_id)
 short hom_checkskill(struct homun_data *hd,uint16 skill_id)
 {
 {
-	short idx = hom_skill_get_index(skill_id);
+	int idx = hom_skill_get_index(skill_id);
 	if (idx < 0) // Invalid skill
 	if (idx < 0) // Invalid skill
 		return 0;
 		return 0;
 
 
@@ -1461,9 +1460,8 @@ void read_homunculusdb(void) {
 */
 */
 static bool read_homunculus_skilldb_sub(char* split[], int columns, int current)
 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>
 {// <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>
-	uint16 skill_id;
-	uint8 i;
-	short class_idx, idx = -1;
+	int skill_id, class_idx;
+	int i, j;
 	int minJobLevelPresent = 0;
 	int minJobLevelPresent = 0;
 
 
 	if (columns == 14)
 	if (columns == 14)
@@ -1471,27 +1469,29 @@ static bool read_homunculus_skilldb_sub(char* split[], int columns, int current)
 
 
 	// check for bounds [celest]
 	// check for bounds [celest]
 	if ((class_idx = hom_class2index(atoi(split[0]))) == -1) {
 	if ((class_idx = hom_class2index(atoi(split[0]))) == -1) {
-		ShowWarning("read_homunculus_skilldb: Invalid homunculus class %d.\n", atoi(split[0]));
+		ShowWarning("read_homunculus_skilldb: Invalud homunculus class %d.\n", atoi(split[0]));
 		return false;
 		return false;
 	}
 	}
 
 
-	skill_id = atoi(split[1]);
-	if ((idx = hom_skill_get_index(skill_id)) == -1) {
-		ShowError("read_homunculus_skilldb: Invalid Homunculus skill '%s'.\n", split[1]);
+	skill_id = atoi(split[1]); //This is to avoid adding two lines for the same skill. [Skotlex]
+	// Search an empty line or a line with the same skill_id (stored in j)
+	ARR_FIND( 0, MAX_SKILL_TREE, j, !hskill_tree[class_idx][j].id || hskill_tree[class_idx][j].id == skill_id );
+	if (j == MAX_SKILL_TREE) {
+		ShowWarning("Unable to load skill %d into homunculus %d's tree. Maximum number of skills per class has been reached.\n", skill_id, atoi(split[0]));
 		return false;
 		return false;
 	}
 	}
 
 
-	hskill_tree[class_idx][idx].id = skill_id;
-	hskill_tree[class_idx][idx].max = atoi(split[2]);
+	hskill_tree[class_idx][j].id = skill_id;
+	hskill_tree[class_idx][j].max = atoi(split[2]);
 	if (minJobLevelPresent)
 	if (minJobLevelPresent)
-		hskill_tree[class_idx][idx].joblv = atoi(split[3]);
+		hskill_tree[class_idx][j].joblv = atoi(split[3]);
 
 
 	for (i = 0; i < MAX_HOM_SKILL_REQUIRE; i++) {
 	for (i = 0; i < MAX_HOM_SKILL_REQUIRE; i++) {
-		hskill_tree[class_idx][idx].need[i].id = atoi(split[3+i*2+minJobLevelPresent]);
-		hskill_tree[class_idx][idx].need[i].lv = atoi(split[3+i*2+minJobLevelPresent+1]);
+		hskill_tree[class_idx][j].need[i].id = atoi(split[3+i*2+minJobLevelPresent]);
+		hskill_tree[class_idx][j].need[i].lv = atoi(split[3+i*2+minJobLevelPresent+1]);
 	}
 	}
 
 
-	hskill_tree[class_idx][idx].intimacylv = atoi(split[13+minJobLevelPresent]);
+	hskill_tree[class_idx][j].intimacylv = atoi(split[13+minJobLevelPresent]);
 	return true;
 	return true;
 }
 }
 
 

+ 0 - 2
src/map/homunculus.h

@@ -159,8 +159,6 @@ void hom_delspiritball(TBL_HOM *hd, int count, int type);
 
 
 uint8 hom_get_intimacy_grade(struct homun_data *hd);
 uint8 hom_get_intimacy_grade(struct homun_data *hd);
 
 
-short hom_skill_get_index(uint16 skill_id);
-
 void do_final_homunculus(void);
 void do_final_homunculus(void);
 void do_init_homunculus(void);
 void do_init_homunculus(void);
 
 

+ 0 - 4
src/map/itemdb.h

@@ -325,12 +325,8 @@ enum e_item_ammo
 	AMMO_KUNAI,
 	AMMO_KUNAI,
 	AMMO_CANNONBALL,
 	AMMO_CANNONBALL,
 	AMMO_THROWABLE_ITEM, ///Sling items
 	AMMO_THROWABLE_ITEM, ///Sling items
-
-	MAX_AMMO_TYPE,
 };
 };
 
 
-#define AMMO_TYPE_ALL ((1<<MAX_AMMO_TYPE)-1)
-
 ///Item combo struct
 ///Item combo struct
 struct item_combo
 struct item_combo
 {
 {

+ 13 - 26
src/map/mercenary.c

@@ -59,20 +59,6 @@ struct view_data * mercenary_get_viewdata(int class_){
 	return &mercenary_db[i].vd;
 	return &mercenary_db[i].vd;
 }
 }
 
 
-/**
- * Get mercenary skill index for mercenary skill tree
- * @param skill_id
- * @return Index in skill_tree or -1
- **/
-short mercenary_skill_get_index(uint16 skill_id) {
-	if (!SKILL_CHK_MERC(skill_id))
-		return -1;
-	skill_id -= MC_SKILLBASE;
-	if (skill_id >= MAX_MERCSKILL)
-		return -1;
-	return skill_id;
-}
-
 /**
 /**
 * Create a new Mercenary for Player
 * Create a new Mercenary for Player
 * @param sd The Player
 * @param sd The Player
@@ -459,11 +445,14 @@ void mercenary_kills(struct mercenary_data *md){
 * @return Skill Level or 0 if Mercenary doesn't have the skill
 * @return Skill Level or 0 if Mercenary doesn't have the skill
 **/
 **/
 int mercenary_checkskill(struct mercenary_data *md, uint16 skill_id) {
 int mercenary_checkskill(struct mercenary_data *md, uint16 skill_id) {
-	short idx = mercenary_skill_get_index(skill_id);
+	int i = skill_id - MC_SKILLBASE;
 
 
-	if( !md || !md->db || idx == -1)
+	if( !md || !md->db )
 		return 0;
 		return 0;
-	return md->db->skill[idx].lv;
+	if( md->db->skill[i].id == skill_id )
+		return md->db->skill[i].lv;
+
+	return 0;
 }
 }
 
 
 /**
 /**
@@ -540,7 +529,6 @@ static bool mercenary_readdb_sub(char* str[], int columns, int current)
 void mercenary_readdb(void) {
 void mercenary_readdb(void) {
 	const char *filename[]={ "mercenary_db.txt",DBIMPORT"/mercenary_db.txt"};
 	const char *filename[]={ "mercenary_db.txt",DBIMPORT"/mercenary_db.txt"};
 	uint8 i;
 	uint8 i;
-
 	mercenary_count = 0; //Reset the counter
 	mercenary_count = 0; //Reset the counter
 	memset(mercenary_db,0,sizeof(mercenary_db));
 	memset(mercenary_db,0,sizeof(mercenary_db));
 	for(i = 0; i<ARRAYLENGTH(filename); i++){
 	for(i = 0; i<ARRAYLENGTH(filename); i++){
@@ -554,9 +542,7 @@ void mercenary_readdb(void) {
 static bool mercenary_read_skilldb_sub(char* str[], int columns, int current)
 static bool mercenary_read_skilldb_sub(char* str[], int columns, int current)
 {// <merc id>,<skill id>,<skill level>
 {// <merc id>,<skill id>,<skill level>
 	struct s_mercenary_db *db;
 	struct s_mercenary_db *db;
-	uint16 class_, skill_id, skill_lv;
-	uint8 i = 0;
-	short idx = -1;
+	uint16 i, class_, skill_id, skill_lv;
 
 
 	class_ = atoi(str[0]);
 	class_ = atoi(str[0]);
 	ARR_FIND(0, MAX_MERCENARY_CLASS, i, class_ == mercenary_db[i].class_);
 	ARR_FIND(0, MAX_MERCENARY_CLASS, i, class_ == mercenary_db[i].class_);
@@ -567,16 +553,18 @@ static bool mercenary_read_skilldb_sub(char* str[], int columns, int current)
 	}
 	}
 
 
 	skill_id = atoi(str[1]);
 	skill_id = atoi(str[1]);
-	if( (idx = mercenary_skill_get_index(skill_id)) == -1 ) {
-		ShowError("read_mercenary_skilldb: Invalid Mercenary skill '%s'.\n", str[1]);
+	if( skill_id < MC_SKILLBASE || skill_id >= MC_SKILLBASE + MAX_MERCSKILL )
+	{
+		ShowError("read_mercenary_skilldb : Skill %d out of range.\n", skill_id);
 		return false;
 		return false;
 	}
 	}
 
 
 	db = &mercenary_db[i];
 	db = &mercenary_db[i];
 	skill_lv = atoi(str[2]);
 	skill_lv = atoi(str[2]);
 
 
-	db->skill[idx].id = skill_id;
-	db->skill[idx].lv = skill_lv;
+	i = skill_id - MC_SKILLBASE;
+	db->skill[i].id = skill_id;
+	db->skill[i].lv = skill_lv;
 
 
 	return true;
 	return true;
 }
 }
@@ -587,7 +575,6 @@ static bool mercenary_read_skilldb_sub(char* str[], int columns, int current)
 void mercenary_read_skilldb(void){
 void mercenary_read_skilldb(void){
 	const char *filename[]={ "mercenary_skill_db.txt",DBIMPORT"/mercenary_skill_db.txt"};
 	const char *filename[]={ "mercenary_skill_db.txt",DBIMPORT"/mercenary_skill_db.txt"};
 	uint8 i;
 	uint8 i;
-
 	for(i = 0; i<ARRAYLENGTH(filename); i++){
 	for(i = 0; i<ARRAYLENGTH(filename); i++){
 		sv_readdb(db_path, filename[i], ',', 3, 3, -1, &mercenary_read_skilldb_sub, i);
 		sv_readdb(db_path, filename[i], ',', 3, 3, -1, &mercenary_read_skilldb_sub, i);
 	}
 	}

+ 0 - 1
src/map/mercenary.h

@@ -71,7 +71,6 @@ void mercenary_set_calls(struct mercenary_data *md, int value);
 void mercenary_kills(struct mercenary_data *md);
 void mercenary_kills(struct mercenary_data *md);
 
 
 int mercenary_checkskill(struct mercenary_data *md, uint16 skill_id);
 int mercenary_checkskill(struct mercenary_data *md, uint16 skill_id);
-short mercenary_skill_get_index(uint16 skill_id);
 
 
 /**
 /**
  * atcommand.c required
  * atcommand.c required

+ 4 - 5
src/map/mob.c

@@ -3492,9 +3492,8 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
 
 
 	//Go Backwards to give better priority to advanced skills.
 	//Go Backwards to give better priority to advanced skills.
 	for (i=0,j = MAX_SKILL_TREE-1;j>=0 && i< MAX_MOBSKILL ;j--) {
 	for (i=0,j = MAX_SKILL_TREE-1;j>=0 && i< MAX_MOBSKILL ;j--) {
-		uint16 skill_id = skill_tree[pc_class2idx(sd->status.class_)][j].id;
-		uint16 sk_idx = 0;
-		if (!skill_id || !(sk_idx = skill_get_index(skill_id)) || sd->status.skill[sk_idx].lv < 1 ||
+		int skill_id = skill_tree[pc_class2idx(sd->status.class_)][j].id;
+		if (!skill_id || sd->status.skill[skill_id].lv < 1 ||
 			(skill_get_inf2(skill_id)&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL)) ||
 			(skill_get_inf2(skill_id)&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL)) ||
 			skill_get_nocast(skill_id)&16
 			skill_get_nocast(skill_id)&16
 		)
 		)
@@ -3514,7 +3513,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
 
 
 		memset (&ms[i], 0, sizeof(struct mob_skill));
 		memset (&ms[i], 0, sizeof(struct mob_skill));
 		ms[i].skill_id = skill_id;
 		ms[i].skill_id = skill_id;
-		ms[i].skill_lv = sd->status.skill[sk_idx].lv;
+		ms[i].skill_lv = sd->status.skill[skill_id].lv;
 		ms[i].state = MSS_ANY;
 		ms[i].state = MSS_ANY;
 		ms[i].permillage = 500*battle_config.mob_skill_rate/100; //Default chance of all skills: 5%
 		ms[i].permillage = 500*battle_config.mob_skill_rate/100; //Default chance of all skills: 5%
 		ms[i].emotion = -1;
 		ms[i].emotion = -1;
@@ -4290,7 +4289,7 @@ static bool mob_parse_row_mobskilldb(char** str, int columns, int current)
 
 
 	//Skill ID
 	//Skill ID
 	j = atoi(str[3]);
 	j = atoi(str[3]);
-	if (j <= 0 || j > MAX_SKILL_ID || !skill_get_index(j)) //fixed Lupus
+	if (j <= 0 || j > MAX_SKILL_DB) //fixed Lupus
 	{
 	{
 		if (mob_id < 0)
 		if (mob_id < 0)
 			ShowError("mob_parse_row_mobskilldb: Invalid Skill ID (%d) for all mobs\n", j);
 			ShowError("mob_parse_row_mobskilldb: Invalid Skill ID (%d) for all mobs\n", j);

+ 9 - 11
src/map/npc.c

@@ -112,12 +112,12 @@ int npc_isnear_sub(struct block_list* bl, va_list args) {
 	if (skill_id > 0) { //If skill_id > 0 that means is used for INF2_NO_NEARNPC [Cydh]
 	if (skill_id > 0) { //If skill_id > 0 that means is used for INF2_NO_NEARNPC [Cydh]
 		uint16 idx = skill_get_index(skill_id);
 		uint16 idx = skill_get_index(skill_id);
 
 
-		if (idx > 0 && skill_db[idx]->unit_nonearnpc_type) {
+		if (idx > 0 && skill_db[idx].unit_nonearnpc_type) {
 			while (1) {
 			while (1) {
-				if (skill_db[idx]->unit_nonearnpc_type&1 && nd->subtype == NPCTYPE_WARP) break;
-				if (skill_db[idx]->unit_nonearnpc_type&2 && nd->subtype == NPCTYPE_SHOP) break;
-				if (skill_db[idx]->unit_nonearnpc_type&4 && nd->subtype == NPCTYPE_SCRIPT) break;
-				if (skill_db[idx]->unit_nonearnpc_type&8 && nd->subtype == NPCTYPE_TOMB) break;
+				if (skill_db[idx].unit_nonearnpc_type&1 && nd->subtype == NPCTYPE_WARP) break;
+				if (skill_db[idx].unit_nonearnpc_type&2 && nd->subtype == NPCTYPE_SHOP) break;
+				if (skill_db[idx].unit_nonearnpc_type&4 && nd->subtype == NPCTYPE_SCRIPT) break;
+				if (skill_db[idx].unit_nonearnpc_type&8 && nd->subtype == NPCTYPE_TOMB) break;
 					return 0;
 					return 0;
 			}
 			}
 		}
 		}
@@ -1687,9 +1687,8 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
 	// custom merchant shop exp bonus
 	// custom merchant shop exp bonus
 	if( battle_config.shop_exp > 0 && z > 0 && (skill = pc_checkskill(sd,MC_DISCOUNT)) > 0 )
 	if( battle_config.shop_exp > 0 && z > 0 && (skill = pc_checkskill(sd,MC_DISCOUNT)) > 0 )
 	{
 	{
-		uint16 sk_idx = skill_get_index(MC_DISCOUNT);
-		if( sd->status.skill[sk_idx].flag >= SKILL_FLAG_REPLACED_LV_0 )
-			skill = sd->status.skill[sk_idx].flag - SKILL_FLAG_REPLACED_LV_0;
+		if( sd->status.skill[MC_DISCOUNT].flag >= SKILL_FLAG_REPLACED_LV_0 )
+			skill = sd->status.skill[MC_DISCOUNT].flag - SKILL_FLAG_REPLACED_LV_0;
 
 
 		if( skill > 0 )
 		if( skill > 0 )
 		{
 		{
@@ -1851,9 +1850,8 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
 	// custom merchant shop exp bonus
 	// custom merchant shop exp bonus
 	if( battle_config.shop_exp > 0 && z > 0 && ( skill = pc_checkskill(sd,MC_OVERCHARGE) ) > 0)
 	if( battle_config.shop_exp > 0 && z > 0 && ( skill = pc_checkskill(sd,MC_OVERCHARGE) ) > 0)
 	{
 	{
-		uint16 sk_idx = skill_get_index(MC_OVERCHARGE);
-		if( sd->status.skill[sk_idx].flag >= SKILL_FLAG_REPLACED_LV_0 )
-			skill = sd->status.skill[sk_idx].flag - SKILL_FLAG_REPLACED_LV_0;
+		if( sd->status.skill[MC_OVERCHARGE].flag >= SKILL_FLAG_REPLACED_LV_0 )
+			skill = sd->status.skill[MC_OVERCHARGE].flag - SKILL_FLAG_REPLACED_LV_0;
 
 
 		if( skill > 0 )
 		if( skill > 0 )
 		{
 		{

+ 269 - 346
src/map/pc.c

@@ -934,12 +934,12 @@ bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd,
 		clif_updatestatus(b_sd, SP_JOBEXP);
 		clif_updatestatus(b_sd, SP_JOBEXP);
 
 
 		// Baby Skills
 		// Baby Skills
-		pc_skill(b_sd, WE_BABY, 1, ADDSKILL_PERMANENT);
-		pc_skill(b_sd, WE_CALLPARENT, 1, ADDSKILL_PERMANENT);
+		pc_skill(b_sd, WE_BABY, 1, 0);
+		pc_skill(b_sd, WE_CALLPARENT, 1, 0);
 
 
 		// Parents Skills
 		// Parents Skills
-		pc_skill(p1_sd, WE_CALLBABY, 1, ADDSKILL_PERMANENT);
-		pc_skill(p2_sd, WE_CALLBABY, 1, ADDSKILL_PERMANENT);
+		pc_skill(p1_sd, WE_CALLBABY, 1, 0);
+		pc_skill(p2_sd, WE_CALLBABY, 1, 0);
 
 
 		return true;
 		return true;
 	}
 	}
@@ -1248,7 +1248,6 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_
 	 * Check if player have any item cooldowns on
 	 * Check if player have any item cooldowns on
 	 **/
 	 **/
 	pc_itemcd_do(sd,true);
 	pc_itemcd_do(sd,true);
-	pc_validate_skill(sd);
 
 
 #ifdef BOUND_ITEMS
 #ifdef BOUND_ITEMS
 	// Party bound item check
 	// Party bound item check
@@ -1356,7 +1355,7 @@ void pc_reg_received(struct map_session_data *sd)
 
 
 	if ((i = pc_checkskill(sd,RG_PLAGIARISM)) > 0) {
 	if ((i = pc_checkskill(sd,RG_PLAGIARISM)) > 0) {
 		sd->cloneskill_idx = skill_get_index(pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM));
 		sd->cloneskill_idx = skill_get_index(pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM));
-		if (sd->cloneskill_idx > 0) {
+		if (sd->cloneskill_idx >= 0) {
 			sd->status.skill[sd->cloneskill_idx].id = pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM);
 			sd->status.skill[sd->cloneskill_idx].id = pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM);
 			sd->status.skill[sd->cloneskill_idx].lv = pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM_LV);
 			sd->status.skill[sd->cloneskill_idx].lv = pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM_LV);
 			if (sd->status.skill[sd->cloneskill_idx].lv > i)
 			if (sd->status.skill[sd->cloneskill_idx].lv > i)
@@ -1366,7 +1365,7 @@ void pc_reg_received(struct map_session_data *sd)
 	}
 	}
 	if ((i = pc_checkskill(sd,SC_REPRODUCE)) > 0) {
 	if ((i = pc_checkskill(sd,SC_REPRODUCE)) > 0) {
 		sd->reproduceskill_idx = skill_get_index(pc_readglobalreg(sd,SKILL_VAR_REPRODUCE));
 		sd->reproduceskill_idx = skill_get_index(pc_readglobalreg(sd,SKILL_VAR_REPRODUCE));
-		if (sd->reproduceskill_idx > 0) {
+		if (sd->reproduceskill_idx >= 0) {
 			sd->status.skill[sd->reproduceskill_idx].id = pc_readglobalreg(sd,SKILL_VAR_REPRODUCE);
 			sd->status.skill[sd->reproduceskill_idx].id = pc_readglobalreg(sd,SKILL_VAR_REPRODUCE);
 			sd->status.skill[sd->reproduceskill_idx].lv = pc_readglobalreg(sd,SKILL_VAR_REPRODUCE_LV);
 			sd->status.skill[sd->reproduceskill_idx].lv = pc_readglobalreg(sd,SKILL_VAR_REPRODUCE_LV);
 			if (i < sd->status.skill[sd->reproduceskill_idx].lv)
 			if (i < sd->status.skill[sd->reproduceskill_idx].lv)
@@ -1449,20 +1448,21 @@ void pc_reg_received(struct map_session_data *sd)
 
 
 static int pc_calc_skillpoint(struct map_session_data* sd)
 static int pc_calc_skillpoint(struct map_session_data* sd)
 {
 {
-	uint16 i, skill_point = 0;
+	uint16 i, skill_point=0;
 
 
 	nullpo_ret(sd);
 	nullpo_ret(sd);
 
 
-	for(i = 1; i < MAX_SKILL; i++) {
-		if( sd->status.skill[i].id && sd->status.skill[i].lv > 0) {
-			uint16 inf2 = skill_get_inf2(sd->status.skill[i].id);
-			if ((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) &&
+	for(i=1;i<MAX_SKILL;i++){
+		uint8 skill_lv;
+		if( (skill_lv = pc_checkskill(sd,i)) > 0) {
+			uint16 inf2 = skill_get_inf2(i);
+			if((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) &&
 				!(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) //Do not count wedding/link skills. [Skotlex]
 				!(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) //Do not count wedding/link skills. [Skotlex]
-				)
-			{
+				) {
 				if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
 				if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
-					skill_point += sd->status.skill[i].lv;
-				else if(sd->status.skill[i].flag == SKILL_FLAG_REPLACED_LV_0)
+					skill_point += skill_lv;
+				else
+				if(sd->status.skill[i].flag == SKILL_FLAG_REPLACED_LV_0)
 					skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
 					skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
 			}
 			}
 		}
 		}
@@ -1471,57 +1471,6 @@ static int pc_calc_skillpoint(struct map_session_data* sd)
 	return skill_point;
 	return skill_point;
 }
 }
 
 
-static bool pc_grant_allskills(struct map_session_data *sd, bool addlv) {
-	uint16 i = 0;
-
-	if (!sd || !pc_has_permission(sd, PC_PERM_ALL_SKILL) || !SKILL_MAX_DB())
-		return false;
-
-	/**
-	* Dummy skills must NOT be added here otherwise they'll be displayed in the,
-	* skill tree and since they have no icons they'll give resource errors
-	* Get ALL skills except npc/guild ones. [Skotlex]
-	* Don't add SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage]
-	**/
-	for( i = 0; i < MAX_SKILL; i++ ) {
-		uint16 skill_id = skill_idx2id(i);
-		if (!skill_id || (skill_get_inf2(skill_id)&(INF2_NPC_SKILL|INF2_GUILD_SKILL)))
-			continue;
-		switch (skill_id) {
-			case SM_SELFPROVOKE:
-			case AB_DUPLELIGHT_MELEE:
-			case AB_DUPLELIGHT_MAGIC:
-			case WL_CHAINLIGHTNING_ATK:
-			case WL_TETRAVORTEX_FIRE:
-			case WL_TETRAVORTEX_WATER:
-			case WL_TETRAVORTEX_WIND:
-			case WL_TETRAVORTEX_GROUND:
-			case WL_SUMMON_ATK_FIRE:
-			case WL_SUMMON_ATK_WIND:
-			case WL_SUMMON_ATK_WATER:
-			case WL_SUMMON_ATK_GROUND:
-			case LG_OVERBRAND_BRANDISH:
-			case LG_OVERBRAND_PLUSATK:
-			case WM_SEVERE_RAINSTORM_MELEE:
-			case RL_R_TRIP_PLUSATK:
-			case SG_DEVIL:
-			case MO_TRIPLEATTACK:
-			case RG_SNATCHER:
-				continue;
-			default:
-				{
-					uint8 lv = (uint8)skill_get_max(skill_id);
-					if (lv > 0) {
-						sd->status.skill[i].id = skill_id;
-						if (addlv)
-							sd->status.skill[i].lv = lv;
-					}
-				}
-				break;
-		}
-	}
-	return true;
-}
 
 
 /*==========================================
 /*==========================================
  * Calculation of skill level.
  * Calculation of skill level.
@@ -1529,8 +1478,8 @@ static bool pc_grant_allskills(struct map_session_data *sd, bool addlv) {
  *------------------------------------------*/
  *------------------------------------------*/
 void pc_calc_skilltree(struct map_session_data *sd)
 void pc_calc_skilltree(struct map_session_data *sd)
 {
 {
-	int i, flag;
-	int c = 0;
+	int i,flag;
+	int c=0;
 
 
 	nullpo_retv(sd);
 	nullpo_retv(sd);
 	i = pc_calc_skilltree_normalize_job(sd);
 	i = pc_calc_skilltree_normalize_job(sd);
@@ -1547,52 +1496,41 @@ void pc_calc_skilltree(struct map_session_data *sd)
 			sd->status.skill[i].id = 0; //First clear skills.
 			sd->status.skill[i].id = 0; //First clear skills.
 		/* permanent skills that must be re-checked */
 		/* permanent skills that must be re-checked */
 		if( sd->status.skill[i].flag == SKILL_FLAG_PERM_GRANTED ) {
 		if( sd->status.skill[i].flag == SKILL_FLAG_PERM_GRANTED ) {
-			uint16 sk_id = skill_idx2id(i);
-			if (!sk_id) {
-				sd->status.skill[i].id = 0;
-				sd->status.skill[i].lv = 0;
-				sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
-				continue;
-			}
-			switch (sk_id) {
+			switch( i ) {
 				case NV_TRICKDEAD:
 				case NV_TRICKDEAD:
 					if( (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE ) {
 					if( (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE ) {
-						sd->status.skill[i].id = 0;
-						sd->status.skill[i].lv = 0;
-						sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
+							sd->status.skill[i].id = 0;
+							sd->status.skill[i].lv = 0;
+							sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
 					}
 					}
 					break;
 					break;
 			}
 			}
 		}
 		}
 	}
 	}
 
 
-	for( i = 0; i < MAX_SKILL; i++ ) {
-		uint16 skill_id = 0;
-
-		// Restore original level of skills after deleting earned skills.
-		if( sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED ) {
+	for( i = 0; i < MAX_SKILL; i++ )
+	{
+		if( sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED )
+		{ // Restore original level of skills after deleting earned skills.
 			sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
 			sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
 			sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
 			sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
 		}
 		}
 
 
-		//Enable Bard/Dancer spirit linked skills.
-		if (!(skill_id = skill_idx2id(i)) || skill_id < DC_HUMMING || skill_id > DC_SERVICEFORYOU)
-			continue;
-
-		if( &sd->sc && sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER ) {
-			//Link Dancer skills to bard.
-			if( sd->status.sex ) {
+		if( sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER && i >= DC_HUMMING && i<= DC_SERVICEFORYOU )
+		{ //Enable Bard/Dancer spirit linked skills.
+			if( sd->status.sex )
+			{ //Link dancer skills to bard.
 				if( sd->status.skill[i-8].lv < 10 )
 				if( sd->status.skill[i-8].lv < 10 )
 					continue;
 					continue;
-				sd->status.skill[i].id = skill_id;
+				sd->status.skill[i].id = i;
 				sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill
 				sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill
 				sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
 				sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
 			}
 			}
-			//Link Bard skills to dancer.
-			else {
+			else
+			{ //Link bard skills to dancer.
 				if( sd->status.skill[i].lv < 10 )
 				if( sd->status.skill[i].lv < 10 )
 					continue;
 					continue;
-				sd->status.skill[i-8].id = skill_id - 8;
+				sd->status.skill[i-8].id = i - 8;
 				sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill
 				sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill
 				sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
 				sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
 			}
 			}
@@ -1602,84 +1540,105 @@ void pc_calc_skilltree(struct map_session_data *sd)
 	// Removes Taekwon Ranker skill bonus
 	// Removes Taekwon Ranker skill bonus
 	if ((sd->class_&MAPID_UPPERMASK) != MAPID_TAEKWON) {
 	if ((sd->class_&MAPID_UPPERMASK) != MAPID_TAEKWON) {
 		uint16 c_ = pc_class2idx(JOB_TAEKWON);
 		uint16 c_ = pc_class2idx(JOB_TAEKWON);
-
 		for (i = 0; i < MAX_SKILL_TREE; i++) {
 		for (i = 0; i < MAX_SKILL_TREE; i++) {
-			uint16 sk_id = skill_tree[c_][i].id;
-			uint16 sk_idx = 0;
-
-			if (!sk_id || !(sk_idx = skill_get_index(skill_tree[c_][i].id)))
-				continue;
-
-			if (sd->status.skill[sk_idx].flag != SKILL_FLAG_PLAGIARIZED && sd->status.skill[sk_idx].flag != SKILL_FLAG_PERM_GRANTED) {
-				if (sk_id == NV_BASIC || sk_id == NV_FIRSTAID || sk_id == WE_CALLBABY)
+			uint16 x = skill_get_index(skill_tree[c_][i].id), skid = sd->status.skill[x].id;
+			if (skid && x > 0 && sd->status.skill[x].flag != SKILL_FLAG_PLAGIARIZED && sd->status.skill[x].flag != SKILL_FLAG_PERM_GRANTED) {
+				if (skid == NV_BASIC || skid == NV_FIRSTAID || skid == WE_CALLBABY)
 					continue;
 					continue;
-				sd->status.skill[sk_idx].id = 0;
-				sd->status.skill[sk_idx].lv = 0;
-				sd->status.skill[sk_idx].flag = SKILL_FLAG_PERMANENT;
+				sd->status.skill[x].id = 0;
 			}
 			}
 		}
 		}
 	}
 	}
 
 
-	// Grant all skills
-	pc_grant_allskills(sd, false);
+	if( pc_has_permission(sd, PC_PERM_ALL_SKILL) ) {
+		for( i = 0; i < MAX_SKILL; i++ ) {
+			switch(i) {
+				/**
+				 * Dummy skills must be added here otherwise they'll be displayed in the,
+				 * skill tree and since they have no icons they'll give resource errors
+				 **/
+				case SM_SELFPROVOKE:
+				case AB_DUPLELIGHT_MELEE:
+				case AB_DUPLELIGHT_MAGIC:
+				case WL_CHAINLIGHTNING_ATK:
+				case WL_TETRAVORTEX_FIRE:
+				case WL_TETRAVORTEX_WATER:
+				case WL_TETRAVORTEX_WIND:
+				case WL_TETRAVORTEX_GROUND:
+				case WL_SUMMON_ATK_FIRE:
+				case WL_SUMMON_ATK_WIND:
+				case WL_SUMMON_ATK_WATER:
+				case WL_SUMMON_ATK_GROUND:
+				case LG_OVERBRAND_BRANDISH:
+				case LG_OVERBRAND_PLUSATK:
+				case WM_SEVERE_RAINSTORM_MELEE:
+				case RL_R_TRIP_PLUSATK:
+					continue;
+				default:
+					break;
+			}
+			if( skill_get_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL) )
+				continue; //Only skills you can't have are npc/guild ones
+			if( skill_get_max(i) > 0 )
+				sd->status.skill[i].id = i;
+		}
+		return;
+	}
 
 
 	do {
 	do {
-		uint16 skid = 0;
-
+		short skid=0;
 		flag = 0;
 		flag = 0;
-		for (i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].id) > 0; i++) {
-			bool fail = false;
-			uint16 sk_idx = skill_get_index(skid);
-
-			if (sd->status.skill[sk_idx].id)
+		for( i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].id) > 0; i++ )
+		{
+			int f;
+			if( sd->status.skill[skid].id )
 				continue; //Skill already known.
 				continue; //Skill already known.
 
 
-			if (!battle_config.skillfree) {
-				uint8 j;
+			f = 1;
+			if(!battle_config.skillfree) {
+				int j;
 				for(j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
 				for(j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
-					uint16 sk_need_id = skill_tree[c][i].need[j].id;
-					uint16 sk_need_idx = 0;
-
-					if (sk_need_id && (sk_need_idx = skill_get_index(sk_need_id))) {
-						short sk_need = 0;
-
-						if (sd->status.skill[sk_need_idx].id == 0 || sd->status.skill[sk_need_idx].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[sk_need_idx].flag == SKILL_FLAG_PLAGIARIZED)
-							sk_need = sk_need_id; //Not learned.
-						else if (sd->status.skill[sk_need_idx].flag >= SKILL_FLAG_REPLACED_LV_0) //Real learned level
-							sk_need = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
+					int k;
+					if((k=skill_tree[c][i].need[j].id))
+					{
+						if (sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED)
+							k = 0; //Not learned.
 						else
 						else
-							sk_need = pc_checkskill(sd,sk_need_id);
-
-						if (sk_need < skill_tree[c][i].need[j].lv) {
-							fail = true;
+						if (sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real learned level
+							k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
+						else
+							k = pc_checkskill(sd,k);
+						if (k < skill_tree[c][i].need[j].lv)
+						{
+							f = 0;
 							break;
 							break;
 						}
 						}
 					}
 					}
 				}
 				}
-
-				if (sd->status.job_level < skill_tree[c][i].joblv) { //We need to get the actual class in this case
+				if( sd->status.job_level < skill_tree[c][i].joblv ) { //We need to get the actual class in this case
 					int class_ = pc_mapid2jobid(sd->class_, sd->status.sex);
 					int class_ = pc_mapid2jobid(sd->class_, sd->status.sex);
 					class_ = pc_class2idx(class_);
 					class_ = pc_class2idx(class_);
 					if (class_ == c || (class_ != c && sd->status.job_level < skill_tree[class_][i].joblv))
 					if (class_ == c || (class_ != c && sd->status.job_level < skill_tree[class_][i].joblv))
-						fail = true; // job level requirement wasn't satisfied
+						f = 0; // job level requirement wasn't satisfied
 				}
 				}
 			}
 			}
 
 
-			if (!fail) {
-				int inf2 = skill_get_inf2(skid);
+			if( f ) {
+				int inf2;
+				inf2 = skill_get_inf2(skid);
 
 
-				if (!sd->status.skill[skid].lv && (
+				if(!sd->status.skill[skid].lv && (
 					(inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
 					(inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
 					inf2&INF2_WEDDING_SKILL ||
 					inf2&INF2_WEDDING_SKILL ||
 					(inf2&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
 					(inf2&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
 				))
 				))
 					continue; //Cannot be learned via normal means. Note this check DOES allows raising already known skills.
 					continue; //Cannot be learned via normal means. Note this check DOES allows raising already known skills.
 
 
-				sd->status.skill[sk_idx].id = skid;
+				sd->status.skill[skid].id = skid;
 
 
 				if(inf2&INF2_SPIRIT_SKILL) { //Spirit skills cannot be learned, they will only show up on your tree when you get buffed.
 				if(inf2&INF2_SPIRIT_SKILL) { //Spirit skills cannot be learned, they will only show up on your tree when you get buffed.
-					sd->status.skill[sk_idx].lv = 1; // need to manually specify a skill level
-					sd->status.skill[sk_idx].flag = SKILL_FLAG_TEMPORARY; //So it is not saved, and tagged as a "bonus" skill.
+					sd->status.skill[skid].lv = 1; // need to manually specify a skill level
+					sd->status.skill[skid].flag = SKILL_FLAG_TEMPORARY; //So it is not saved, and tagged as a "bonus" skill.
 				}
 				}
 				flag = 1; // skill list has changed, perform another pass
 				flag = 1; // skill list has changed, perform another pass
 			}
 			}
@@ -1687,7 +1646,7 @@ void pc_calc_skilltree(struct map_session_data *sd)
 	} while(flag);
 	} while(flag);
 
 
 	if( c > 0 && sd->status.skill_point == 0 && pc_is_taekwon_ranker(sd) ) {
 	if( c > 0 && sd->status.skill_point == 0 && pc_is_taekwon_ranker(sd) ) {
-		unsigned short skid = 0;
+		short skid=0;
 		/* Taekwon Ranker Bonus Skill Tree
 		/* Taekwon Ranker Bonus Skill Tree
 		============================================
 		============================================
 		- Grant All Taekwon Tree, but only as Bonus Skills in case they drop from ranking.
 		- Grant All Taekwon Tree, but only as Bonus Skills in case they drop from ranking.
@@ -1695,28 +1654,25 @@ void pc_calc_skilltree(struct map_session_data *sd)
 		- (sd->status.skill_point == 0) to wait until all skill points are assigned to avoid problems with Job Change quest. */
 		- (sd->status.skill_point == 0) to wait until all skill points are assigned to avoid problems with Job Change quest. */
 
 
 		for( i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].id) > 0; i++ ) {
 		for( i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].id) > 0; i++ ) {
-			uint16 sk_idx = 0;
-			if (!(sk_idx = skill_get_index(skid)))
-				continue;
 			if( (skill_get_inf2(skid)&(INF2_QUEST_SKILL|INF2_WEDDING_SKILL)) )
 			if( (skill_get_inf2(skid)&(INF2_QUEST_SKILL|INF2_WEDDING_SKILL)) )
 				continue; //Do not include Quest/Wedding skills.
 				continue; //Do not include Quest/Wedding skills.
-			if( sd->status.skill[sk_idx].id == 0 ) { //do we really want skid as index ? //Lighta
-				sd->status.skill[sk_idx].id = skid;
-				sd->status.skill[sk_idx].flag = SKILL_FLAG_TEMPORARY; // So it is not saved, and tagged as a "bonus" skill.
+			if( sd->status.skill[skid].id == 0 ) { //do we really want skid as index ? //Lighta
+				sd->status.skill[skid].id = skid;
+				sd->status.skill[skid].flag = SKILL_FLAG_TEMPORARY; // So it is not saved, and tagged as a "bonus" skill.
 			} else if( skid != NV_BASIC )
 			} else if( skid != NV_BASIC )
-				sd->status.skill[sk_idx].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[sk_idx].lv; // Remember original level
-			sd->status.skill[sk_idx].lv = skill_tree_get_max(skid, sd->status.class_);
+				sd->status.skill[skid].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[skid].lv; // Remember original level
+			sd->status.skill[skid].lv = skill_tree_get_max(skid, sd->status.class_);
 		}
 		}
 	}
 	}
 }
 }
 
 
 //Checks if you can learn a new skill after having leveled up a skill.
 //Checks if you can learn a new skill after having leveled up a skill.
-static void pc_check_skilltree(struct map_session_data *sd)
+static void pc_check_skilltree(struct map_session_data *sd, int skill)
 {
 {
-	int i, flag = 0;
-	int c = 0;
+	int i,id=0,flag;
+	int c=0;
 
 
-	if (battle_config.skillfree)
+	if(battle_config.skillfree)
 		return; //Function serves no purpose if this is set
 		return; //Function serves no purpose if this is set
 
 
 	i = pc_calc_skilltree_normalize_job(sd);
 	i = pc_calc_skilltree_normalize_job(sd);
@@ -1726,54 +1682,44 @@ static void pc_check_skilltree(struct map_session_data *sd)
 		return;
 		return;
 	}
 	}
 	c = pc_class2idx(c);
 	c = pc_class2idx(c);
-
 	do {
 	do {
-		uint16 skid = 0;
-
 		flag = 0;
 		flag = 0;
-		for (i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].id) > 0; i++ ) {
-			uint16 sk_idx = skill_get_index(skid);
-			bool fail = false;
-			uint8 j = 0;
-
-			if (sd->status.skill[sk_idx].id) //Already learned
+		for( i = 0; i < MAX_SKILL_TREE && (id=skill_tree[c][i].id)>0; i++ )
+		{
+			int j, f = 1;
+			if( sd->status.skill[id].id ) //Already learned
 				continue;
 				continue;
-
-			for (j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
-				uint16 sk_need_id = skill_tree[c][i].need[j].id;
-				uint16 sk_need_idx = 0;
-
-				if (sk_need_id && (sk_need_idx = skill_get_index(sk_need_id))) {
-					short sk_need = sk_need_id;
-
-					if (sd->status.skill[sk_need_idx].id == 0 || sd->status.skill[sk_need_idx].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[sk_need_idx].flag == SKILL_FLAG_PLAGIARIZED)
-						sk_need = 0; //Not learned.
-					else if (sd->status.skill[sk_need_idx].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level
-						sk_need = sd->status.skill[sk_need_idx].flag - SKILL_FLAG_REPLACED_LV_0;
+			for( j = 0; j < MAX_PC_SKILL_REQUIRE; j++ ){
+				int k = skill_tree[c][i].need[j].id;
+				if( k != 0 ){
+					if( sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED )
+						k = 0; //Not learned.
 					else
 					else
-						sk_need = pc_checkskill(sd,sk_need_id);
-
-					if (sk_need < skill_tree[c][i].need[j].lv) {
-						fail = true;
+					if( sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level
+						k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
+					else
+						k = pc_checkskill(sd,k);
+					if( k < skill_tree[c][i].need[j].lv )
+					{
+						f = 0;
 						break;
 						break;
 					}
 					}
 				}
 				}
 			}
 			}
-
-			if( fail )
+			if( !f )
 				continue;
 				continue;
 			if( sd->status.job_level < skill_tree[c][i].joblv )
 			if( sd->status.job_level < skill_tree[c][i].joblv )
 				continue;
 				continue;
 
 
-			j = skill_get_inf2(skid);
-			if( !sd->status.skill[sk_idx].lv && (
+			j = skill_get_inf2(id);
+			if( !sd->status.skill[id].lv && (
 				(j&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
 				(j&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
 				j&INF2_WEDDING_SKILL ||
 				j&INF2_WEDDING_SKILL ||
 				(j&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
 				(j&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
 			) )
 			) )
 				continue; //Cannot be learned via normal means.
 				continue; //Cannot be learned via normal means.
 
 
-			sd->status.skill[sk_idx].id = skid;
+			sd->status.skill[id].id = id;
 			flag = 1;
 			flag = 1;
 		}
 		}
 	} while(flag);
 	} while(flag);
@@ -1785,12 +1731,14 @@ void pc_clean_skilltree(struct map_session_data *sd)
 {
 {
 	uint16 i;
 	uint16 i;
 	for (i = 0; i < MAX_SKILL; i++){
 	for (i = 0; i < MAX_SKILL; i++){
-		if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED) {
+		if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED)
+		{
 			sd->status.skill[i].id = 0;
 			sd->status.skill[i].id = 0;
 			sd->status.skill[i].lv = 0;
 			sd->status.skill[i].lv = 0;
 			sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
 			sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
 		}
 		}
-		else if (sd->status.skill[i].flag == SKILL_FLAG_REPLACED_LV_0){
+		else
+		if (sd->status.skill[i].flag == SKILL_FLAG_REPLACED_LV_0){
 			sd->status.skill[i].lv = sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
 			sd->status.skill[i].lv = sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
 			sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
 			sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
 		}
 		}
@@ -3868,78 +3816,74 @@ void pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type
  *	2 - Like 1, except the level granted can stack with previously learned level.
  *	2 - Like 1, except the level granted can stack with previously learned level.
  *	4 - Like 0, except the skill will ignore skill tree (saves through job changes and resets).
  *	4 - Like 0, except the skill will ignore skill tree (saves through job changes and resets).
  *------------------------------------------*/
  *------------------------------------------*/
-bool pc_skill(TBL_PC* sd, uint16 skill_id, int level, enum e_addskill_type type) {
-	uint16 idx = 0;
+int pc_skill(TBL_PC* sd, int id, int level, int flag)
+{
 	nullpo_ret(sd);
 	nullpo_ret(sd);
 
 
-	if (!skill_id || !(idx = skill_get_index(skill_id))) {
-		ShowError("pc_skill: Skill with id %d does not exist in the skill database\n", skill_id);
-		return false;
+	if( id <= 0 || id >= MAX_SKILL || skill_db[id].name == NULL) {
+		ShowError("pc_skill: Skill with id %d does not exist in the skill database\n", id);
+		return 0;
 	}
 	}
-	if (level > MAX_SKILL_LEVEL) {
+	if( level > MAX_SKILL_LEVEL ) {
 		ShowError("pc_skill: Skill level %d too high. Max lv supported is %d\n", level, MAX_SKILL_LEVEL);
 		ShowError("pc_skill: Skill level %d too high. Max lv supported is %d\n", level, MAX_SKILL_LEVEL);
-		return false;
+		return 0;
 	}
 	}
-	if (type == ADDSKILL_TEMP_ADDLEVEL && sd->status.skill[idx].lv + level > MAX_SKILL_LEVEL) {
-		ShowWarning("pc_skill: Skill level bonus %d too high. Max lv supported is %d. Curr lv is %d. Set to max level.\n", level, MAX_SKILL_LEVEL, sd->status.skill[idx].lv);
-		level = MAX_SKILL_LEVEL - sd->status.skill[idx].lv;
+	if( flag == 2 && sd->status.skill[id].lv + level > MAX_SKILL_LEVEL ) {
+		ShowError("pc_skill: Skill level bonus %d too high. Max lv supported is %d. Curr lv is %d\n", level, MAX_SKILL_LEVEL, sd->status.skill[id].lv);
+		return 0;
 	}
 	}
 
 
-	switch (type) {
-		case ADDSKILL_PERMANENT: //Set skill data overwriting whatever was there before.
-			sd->status.skill[idx].id   = skill_id;
-			sd->status.skill[idx].lv   = level;
-			sd->status.skill[idx].flag = SKILL_FLAG_PERMANENT;
-			if (level == 0) { //Remove skill.
-				sd->status.skill[idx].id = 0;
-				clif_deleteskill(sd,skill_id);
+	switch( flag ){
+		case 0: //Set skill data overwriting whatever was there before.
+			sd->status.skill[id].id   = id;
+			sd->status.skill[id].lv   = level;
+			sd->status.skill[id].flag = SKILL_FLAG_PERMANENT;
+			if( level == 0 ) { //Remove skill.
+				sd->status.skill[id].id = 0;
+				clif_deleteskill(sd,id);
 			} else
 			} else
-				clif_addskill(sd,skill_id);
-			if (!skill_get_inf(skill_id)) //Only recalculate for passive skills.
+				clif_addskill(sd,id);
+			if( !skill_get_inf(id) ) //Only recalculate for passive skills.
 				status_calc_pc(sd, SCO_NONE);
 				status_calc_pc(sd, SCO_NONE);
 			break;
 			break;
-
-		case ADDSKILL_TEMP: //Item bonus skill.
-			if (sd->status.skill[idx].id != 0) {
-				if (sd->status.skill[idx].lv >= level)
-					return true;
-				if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) //Non-granted skill, store it's level.
-					sd->status.skill[idx].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[idx].lv;
+		case 1: //Item bonus skill.
+			if( sd->status.skill[id].id == id ) {
+				if( sd->status.skill[id].lv >= level )
+					return 0;
+				if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT ) //Non-granted skill, store it's level.
+					sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv;
 			} else {
 			} else {
-				sd->status.skill[idx].id   = skill_id;
-				sd->status.skill[idx].flag = SKILL_FLAG_TEMPORARY;
+				sd->status.skill[id].id   = id;
+				sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY;
 			}
 			}
-			sd->status.skill[idx].lv = level;
+			sd->status.skill[id].lv = level;
 			break;
 			break;
-
-		case ADDSKILL_TEMP_ADDLEVEL: //Add skill bonus on top of what you had.
-			if (sd->status.skill[idx].id != 0) {
-				if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT)
-					sd->status.skill[idx].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[idx].lv; // Store previous level.
+		case 2: //Add skill bonus on top of what you had.
+			if( sd->status.skill[id].id == id ) {
+				if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT )
+					sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; // Store previous level.
 			} else {
 			} else {
-				sd->status.skill[idx].id   = skill_id;
-				sd->status.skill[idx].flag = SKILL_FLAG_TEMPORARY; //Set that this is a bonus skill.
+				sd->status.skill[id].id   = id;
+				sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //Set that this is a bonus skill.
 			}
 			}
-			sd->status.skill[idx].lv += level;
-			break;
-
-		case ADDSKILL_PERMANENT_GRANTED: //Permanent granted skills ignore the skill tree
-			sd->status.skill[idx].id   = skill_id;
-			sd->status.skill[idx].lv   = level;
-			sd->status.skill[idx].flag = SKILL_FLAG_PERM_GRANTED;
-			if (level == 0) { //Remove skill.
-				sd->status.skill[idx].id = 0;
-				clif_deleteskill(sd,skill_id);
+			sd->status.skill[id].lv += level;
+			break;
+		case 4: //Permanent granted skills ignore the skill tree
+			sd->status.skill[id].id   = id;
+			sd->status.skill[id].lv   = level;
+			sd->status.skill[id].flag = SKILL_FLAG_PERM_GRANTED;
+			if( level == 0 ) { //Remove skill.
+				sd->status.skill[id].id = 0;
+				clif_deleteskill(sd,id);
 			} else
 			} else
-				clif_addskill(sd,skill_id);
-			if (!skill_get_inf(skill_id)) //Only recalculate for passive skills.
+				clif_addskill(sd,id);
+			if( !skill_get_inf(id) ) //Only recalculate for passive skills.
 				status_calc_pc(sd, SCO_NONE);
 				status_calc_pc(sd, SCO_NONE);
 			break;
 			break;
-
-		default:
-			return false;
+		default: //Unknown flag?
+			return 0;
 	}
 	}
-	return true;
+	return 1;
 }
 }
 /*==========================================
 /*==========================================
  * Append a card to an item ?
  * Append a card to an item ?
@@ -5485,8 +5429,8 @@ int pc_get_skillcooldown(struct map_session_data *sd, uint16 skill_id, uint16 sk
 	int cooldown = 0, cooldownlen = ARRAYLENGTH(sd->skillcooldown);
 	int cooldown = 0, cooldownlen = ARRAYLENGTH(sd->skillcooldown);
 	
 	
 	if (!idx) return 0;
 	if (!idx) return 0;
-	if (skill_db[idx]->cooldown[skill_lv - 1])
-		cooldown = skill_db[idx]->cooldown[skill_lv - 1];
+	if (skill_db[idx].cooldown[skill_lv - 1])
+		cooldown = skill_db[idx].cooldown[skill_lv - 1];
 
 
 	ARR_FIND(0, cooldownlen, i, sd->skillcooldown[i].id == skill_id);
 	ARR_FIND(0, cooldownlen, i, sd->skillcooldown[i].id == skill_id);
 	if (i < cooldownlen) {
 	if (i < cooldownlen) {
@@ -5499,23 +5443,24 @@ int pc_get_skillcooldown(struct map_session_data *sd, uint16 skill_id, uint16 sk
 /*==========================================
 /*==========================================
  * Return player sd skill_lv learned for given skill
  * Return player sd skill_lv learned for given skill
  *------------------------------------------*/
  *------------------------------------------*/
-uint8 pc_checkskill(struct map_session_data *sd, uint16 skill_id)
+uint8 pc_checkskill(struct map_session_data *sd,uint16 skill_id)
 {
 {
-	uint16 i = 0, idx = 0;
-	if (sd == NULL)
-		return 0;
-	if ((idx = skill_get_index(skill_id)) == 0) {
-		ShowError("pc_checkskill: Invalid skill id %d (char_id=%d).\n", skill_id, sd->status.char_id);
-		return 0;
-	}
-	if (SKILL_CHK_GUILD(skill_id) ) {
+	if(sd == NULL) return 0;
+	if( skill_id >= GD_SKILLBASE && skill_id < GD_MAX ) {
 		struct guild *g;
 		struct guild *g;
 
 
 		if( sd->status.guild_id>0 && (g=sd->guild)!=NULL)
 		if( sd->status.guild_id>0 && (g=sd->guild)!=NULL)
 			return guild_checkskill(g,skill_id);
 			return guild_checkskill(g,skill_id);
 		return 0;
 		return 0;
+	} else if(skill_id >= ARRAYLENGTH(sd->status.skill) ) {
+		ShowError("pc_checkskill: Invalid skill id %d (char_id=%d).\n", skill_id, sd->status.char_id);
+		return 0;
 	}
 	}
-	return sd->status.skill[idx].lv;
+
+	if(sd->status.skill[skill_id].id == skill_id)
+		return (sd->status.skill[skill_id].lv);
+
+	return 0;
 }
 }
 
 
 /**
 /**
@@ -6687,57 +6632,52 @@ int pc_statusup2(struct map_session_data* sd, int type, int val)
  * Update skill_lv for player sd
  * Update skill_lv for player sd
  * Skill point allocation
  * Skill point allocation
  *------------------------------------------*/
  *------------------------------------------*/
-void pc_skillup(struct map_session_data *sd,uint16 skill_id)
+int pc_skillup(struct map_session_data *sd,uint16 skill_id)
 {
 {
-	uint16 idx = skill_get_index(skill_id);
-
-	nullpo_retv(sd);
-
-	if (!idx) {
-		if (skill_id)
-			ShowError("pc_skillup: Player attempts to level up invalid skill '%d'\n", skill_id);
-		return;
-	}
+	nullpo_ret(sd);
 
 
-	// Level up guild skill
-	if (SKILL_CHK_GUILD(skill_id)) {
+	if( skill_id >= GD_SKILLBASE && skill_id < GD_SKILLBASE+MAX_GUILDSKILL )
+	{
 		guild_skillup(sd, skill_id);
 		guild_skillup(sd, skill_id);
-		return;
+		return 0;
 	}
 	}
-	// Level up homunculus skill
-	else if (sd->hd && SKILL_CHK_HOMUN(skill_id)) {
+
+	if( skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE+MAX_HOMUNSKILL && sd->hd )
+	{
 		hom_skillup(sd->hd, skill_id);
 		hom_skillup(sd->hd, skill_id);
-		return;
+		return 0;
 	}
 	}
-	else {
-		if( sd->status.skill_point > 0 &&
-			sd->status.skill[idx].id &&
-			sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex]
-			sd->status.skill[idx].lv < skill_tree_get_max(skill_id, sd->status.class_) )
-		{
-			int lv, range, upgradable;
-			sd->status.skill[idx].lv++;
-			sd->status.skill_point--;
-			if( !skill_get_inf(skill_id) )
-				status_calc_pc(sd,SCO_NONE); // Only recalculate for passive skills.
-			else if( sd->status.skill_point == 0 && pc_is_taekwon_ranker(sd) )
-				pc_calc_skilltree(sd); // Required to grant all TK Ranker skills.
-			else
-				pc_check_skilltree(sd); // Check if a new skill can Lvlup
-
-			lv = sd->status.skill[idx].lv;
-			range = skill_get_range2(&sd->bl, skill_id, lv);
-			upgradable = (lv < skill_tree_get_max(sd->status.skill[idx].id, sd->status.class_)) ? 1 : 0;
-			clif_skillup(sd,skill_id,lv,range,upgradable);
-			clif_updatestatus(sd,SP_SKILLPOINT);
-			if( skill_id == GN_REMODELING_CART ) /* cart weight info was updated by status_calc_pc */
-				clif_updatestatus(sd,SP_CARTINFO);
-			if (!pc_has_permission(sd, PC_PERM_ALL_SKILL)) // may skill everything at any time anyways, and this would cause a huge slowdown
-				clif_skillinfoblock(sd);
-		}
+
+	if(skill_id >= MAX_SKILL )
+		return 0;
+
+	if( sd->status.skill_point > 0 &&
+		sd->status.skill[skill_id].id &&
+		sd->status.skill[skill_id].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex]
+		sd->status.skill[skill_id].lv < skill_tree_get_max(skill_id, sd->status.class_) )
+	{
+		int lv,range, upgradable;
+		sd->status.skill[skill_id].lv++;
+		sd->status.skill_point--;
+		if( !skill_get_inf(skill_id) )
+			status_calc_pc(sd,SCO_NONE); // Only recalculate for passive skills.
+		else if( sd->status.skill_point == 0 && pc_is_taekwon_ranker(sd) )
+			pc_calc_skilltree(sd); // Required to grant all TK Ranker skills.
 		else
 		else
-			ShowDebug("Skill Level up failed. ID:%d idx:%d (CID=%d. AID=%d)\n", skill_id, idx, sd->status.char_id, sd->status.account_id);
+			pc_check_skilltree(sd, skill_id); // Check if a new skill can Lvlup
+
+		lv = sd->status.skill[skill_id].lv;
+		range = skill_get_range2(&sd->bl, skill_id, lv);
+		upgradable = (lv < skill_tree_get_max(sd->status.skill[skill_id].id, sd->status.class_)) ? 1 : 0;
+		clif_skillup(sd,skill_id,lv,range,upgradable);
+		clif_updatestatus(sd,SP_SKILLPOINT);
+		if( skill_id == GN_REMODELING_CART ) /* cart weight info was updated by status_calc_pc */
+			clif_updatestatus(sd,SP_CARTINFO);
+		if (!pc_has_permission(sd, PC_PERM_ALL_SKILL)) // may skill everything at any time anyways, and this would cause a huge slowdown
+			clif_skillinfoblock(sd);
 	}
 	}
+
+	return 0;
 }
 }
 
 
 /*==========================================
 /*==========================================
@@ -6749,7 +6689,7 @@ int pc_allskillup(struct map_session_data *sd)
 
 
 	nullpo_ret(sd);
 	nullpo_ret(sd);
 
 
-	for (i = 0; i < MAX_SKILL; i++) {
+	for(i=0;i<MAX_SKILL;i++){
 		if (sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED) {
 		if (sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED) {
 			sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
 			sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
 			sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
 			sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
@@ -6758,23 +6698,34 @@ int pc_allskillup(struct map_session_data *sd)
 		}
 		}
 	}
 	}
 
 
-	if (!pc_grant_allskills(sd, true)) {
-		uint16 sk_id;
-		for (i = 0; i < MAX_SKILL_TREE && (sk_id = skill_tree[pc_class2idx(sd->status.class_)][i].id) > 0;i++){
-			int inf2 = 0;
-			uint16 sk_idx = 0;
-			if (!sk_id || !(sk_idx = skill_get_index(sk_id)))
-				continue;
-			inf2 = skill_get_inf2(sk_id);
+	if (pc_has_permission(sd, PC_PERM_ALL_SKILL))
+	{	//Get ALL skills except npc/guild ones. [Skotlex]
+		//and except SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage]
+		for(i=0;i<MAX_SKILL;i++){
+			switch( i ) {
+				case SG_DEVIL:
+				case MO_TRIPLEATTACK:
+				case RG_SNATCHER:
+					continue;
+				default:
+					if( !(skill_get_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL)) )
+						if ( ( sd->status.skill[i].lv = skill_get_max(i) ) )//Nonexistant skills should return a max of 0 anyway.
+							sd->status.skill[i].id = i;
+			}
+		}
+	} else {
+		int id;
+		for(i=0;i < MAX_SKILL_TREE && (id=skill_tree[pc_class2idx(sd->status.class_)][i].id)>0;i++){
+			int inf2 = skill_get_inf2(id);
 			if (
 			if (
 				(inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
 				(inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
 				(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) ||
 				(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) ||
-				sk_id == SG_DEVIL
+				id==SG_DEVIL
 			)
 			)
 				continue; //Cannot be learned normally.
 				continue; //Cannot be learned normally.
 
 
-			sd->status.skill[sk_idx].id = sk_id;
-			sd->status.skill[sk_idx].lv = skill_tree_get_max(sk_id, sd->status.class_);	// celest
+			sd->status.skill[id].id = id;
+			sd->status.skill[id].lv = skill_tree_get_max(id, sd->status.class_);	// celest
 		}
 		}
 	}
 	}
 	status_calc_pc(sd,SCO_NONE);
 	status_calc_pc(sd,SCO_NONE);
@@ -6814,8 +6765,8 @@ int pc_resetlvl(struct map_session_data* sd,int type)
 		if(sd->status.class_ == JOB_NOVICE_HIGH) {
 		if(sd->status.class_ == JOB_NOVICE_HIGH) {
 			sd->status.status_point=100;	// not 88 [celest]
 			sd->status.status_point=100;	// not 88 [celest]
 			// give platinum skills upon changing
 			// give platinum skills upon changing
-			pc_skill(sd,NV_FIRSTAID,1,ADDSKILL_PERMANENT);
-			pc_skill(sd,NV_TRICKDEAD,1,ADDSKILL_PERMANENT);
+			pc_skill(sd,142,1,0);
+			pc_skill(sd,143,1,0);
 		}
 		}
 	}
 	}
 
 
@@ -6989,11 +6940,9 @@ int pc_resetskill(struct map_session_data* sd, int flag)
 
 
 	for( i = 1; i < MAX_SKILL; i++ )
 	for( i = 1; i < MAX_SKILL; i++ )
 	{
 	{
-		uint8 lv = sd->status.skill[i].lv;
+		int lv = sd->status.skill[i].lv;
 		int inf2;
 		int inf2;
-		uint16 skill_id = skill_idx2id(i);
-		if (lv == 0 || skill_id == 0)
-			continue;
+		if (lv < 1) continue;
 
 
 		inf2 = skill_get_inf2(i);
 		inf2 = skill_get_inf2(i);
 
 
@@ -7001,7 +6950,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
 			continue;
 			continue;
 
 
 		// Don't reset trick dead if not a novice/baby
 		// Don't reset trick dead if not a novice/baby
-		if( skill_id == NV_TRICKDEAD && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE )
+		if( i == NV_TRICKDEAD && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE )
 		{
 		{
 			sd->status.skill[i].lv = 0;
 			sd->status.skill[i].lv = 0;
 			sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
 			sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
@@ -7009,13 +6958,13 @@ int pc_resetskill(struct map_session_data* sd, int flag)
 		}
 		}
 
 
 		// do not reset basic skill
 		// do not reset basic skill
-		if( skill_id == NV_BASIC && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE )
+		if( i == NV_BASIC && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE )
 			continue;
 			continue;
 
 
 		if( sd->status.skill[i].flag == SKILL_FLAG_PERM_GRANTED )
 		if( sd->status.skill[i].flag == SKILL_FLAG_PERM_GRANTED )
 			continue;
 			continue;
 
 
-		if( flag&4 && !skill_ischangesex(skill_id) )
+		if( flag&4 && !skill_ischangesex(i) )
 			continue;
 			continue;
 
 
 		if( inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn )
 		if( inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn )
@@ -8064,26 +8013,26 @@ bool pc_jobchange(struct map_session_data *sd,int job, char upper)
 		pc_setglobalreg (sd, "jobchange_level_3rd", sd->change_level_3rd);
 		pc_setglobalreg (sd, "jobchange_level_3rd", sd->change_level_3rd);
 	}
 	}
 
 
-	if(sd->cloneskill_idx > 0) {
+	if(sd->cloneskill_idx >= 0) {
 		if( sd->status.skill[sd->cloneskill_idx].flag == SKILL_FLAG_PLAGIARIZED ) {
 		if( sd->status.skill[sd->cloneskill_idx].flag == SKILL_FLAG_PLAGIARIZED ) {
 			sd->status.skill[sd->cloneskill_idx].id = 0;
 			sd->status.skill[sd->cloneskill_idx].id = 0;
 			sd->status.skill[sd->cloneskill_idx].lv = 0;
 			sd->status.skill[sd->cloneskill_idx].lv = 0;
 			sd->status.skill[sd->cloneskill_idx].flag = SKILL_FLAG_PERMANENT;
 			sd->status.skill[sd->cloneskill_idx].flag = SKILL_FLAG_PERMANENT;
 			clif_deleteskill(sd,pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM));
 			clif_deleteskill(sd,pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM));
 		}
 		}
-		sd->cloneskill_idx = 0;
+		sd->cloneskill_idx = -1;
 		pc_setglobalreg(sd,SKILL_VAR_PLAGIARISM, 0);
 		pc_setglobalreg(sd,SKILL_VAR_PLAGIARISM, 0);
 		pc_setglobalreg(sd,SKILL_VAR_PLAGIARISM_LV, 0);
 		pc_setglobalreg(sd,SKILL_VAR_PLAGIARISM_LV, 0);
 	}
 	}
 
 
-	if(sd->reproduceskill_idx > 0) {
+	if(sd->reproduceskill_idx >= 0) {
 		if( sd->status.skill[sd->reproduceskill_idx].flag == SKILL_FLAG_PLAGIARIZED ) {
 		if( sd->status.skill[sd->reproduceskill_idx].flag == SKILL_FLAG_PLAGIARIZED ) {
 			sd->status.skill[sd->reproduceskill_idx].id = 0;
 			sd->status.skill[sd->reproduceskill_idx].id = 0;
 			sd->status.skill[sd->reproduceskill_idx].lv = 0;
 			sd->status.skill[sd->reproduceskill_idx].lv = 0;
 			sd->status.skill[sd->reproduceskill_idx].flag = SKILL_FLAG_PERMANENT;
 			sd->status.skill[sd->reproduceskill_idx].flag = SKILL_FLAG_PERMANENT;
 			clif_deleteskill(sd,pc_readglobalreg(sd,SKILL_VAR_REPRODUCE));
 			clif_deleteskill(sd,pc_readglobalreg(sd,SKILL_VAR_REPRODUCE));
 		}
 		}
-		sd->reproduceskill_idx = 0;
+		sd->reproduceskill_idx = -1;
 		pc_setglobalreg(sd,SKILL_VAR_REPRODUCE,0);
 		pc_setglobalreg(sd,SKILL_VAR_REPRODUCE,0);
 		pc_setglobalreg(sd,SKILL_VAR_REPRODUCE_LV,0);
 		pc_setglobalreg(sd,SKILL_VAR_REPRODUCE_LV,0);
 	}
 	}
@@ -11334,32 +11283,6 @@ uint64 pc_generate_unique_id(struct map_session_data *sd) {
 	return ((uint64)sd->status.char_id << 32) | sd->status.uniqueitem_counter++;
 	return ((uint64)sd->status.char_id << 32) | sd->status.uniqueitem_counter++;
 }
 }
 
 
-/**
- * Validating skill from player after logged on
- * @param sd
- **/
-void pc_validate_skill(struct map_session_data *sd) {
-	if (sd) {
-		uint16 i = 0, count = 0;
-		struct s_skill tmp_skills[MAX_SKILL] = {{ 0 }};
-
-		memcpy(tmp_skills, sd->status.skill, sizeof(sd->status.skill));
-		memset(sd->status.skill, 0, sizeof(sd->status.skill));
-
-		for (i = 0; i < MAX_SKILL; i++) {
-			uint16 idx = 0;
-			if (tmp_skills[i].id == 0 || tmp_skills[i].lv == 0)
-				continue;
-			if ((idx = skill_get_index(tmp_skills[i].id))) {
-				memcpy(&sd->status.skill[idx], &tmp_skills[i], sizeof(tmp_skills[i]));
-				count++;
-			}
-			else
-				ShowWarning("pc_validate_skill: Removing invalid skill '%d' from player (AID=%d CID=%d).\n", tmp_skills[i].id, sd->status.account_id, sd->status.char_id);
-		}
-	}
-}
-
 /*==========================================
 /*==========================================
  * pc Init/Terminate
  * pc Init/Terminate
  *------------------------------------------*/
  *------------------------------------------*/

+ 8 - 20
src/map/pc.h

@@ -437,7 +437,7 @@ struct map_session_data {
 
 
 	short catch_target_class; // pet catching, stores a pet class to catch (short now) [zzo]
 	short catch_target_class; // pet catching, stores a pet class to catch (short now) [zzo]
 
 
-	int8 spiritball, spiritball_old;
+	short spiritball, spiritball_old;
 	int spirit_timer[MAX_SPIRITBALL];
 	int spirit_timer[MAX_SPIRITBALL];
 	short talisman[ELE_POISON+1]; // There are actually 5 talisman Fire, Ice, Wind, Earth & Poison maybe because its color violet.
 	short talisman[ELE_POISON+1]; // There are actually 5 talisman Fire, Ice, Wind, Earth & Poison maybe because its color violet.
 	int talisman_timer[ELE_POISON+1][10];
 	int talisman_timer[ELE_POISON+1][10];
@@ -657,8 +657,6 @@ enum weapon_type {
 	W_DOUBLE_SA, // sword + axe
 	W_DOUBLE_SA, // sword + axe
 };
 };
 
 
-#define WEAPON_TYPE_ALL ((1<<MAX_WEAPON_TYPE)-1)
-
 enum ammo_type {
 enum ammo_type {
 	A_ARROW = 1,
 	A_ARROW = 1,
 	A_DAGGER,   //2
 	A_DAGGER,   //2
@@ -916,15 +914,7 @@ void pc_bonus2(struct map_session_data *sd, int type, int type2, int val);
 void pc_bonus3(struct map_session_data *sd, int type, int type2, int type3, int val);
 void pc_bonus3(struct map_session_data *sd, int type, int type2, int type3, int val);
 void pc_bonus4(struct map_session_data *sd, int type, int type2, int type3, int type4, int val);
 void pc_bonus4(struct map_session_data *sd, int type, int type2, int type3, int type4, int val);
 void pc_bonus5(struct map_session_data *sd, int type, int type2, int type3, int type4, int type5, int val);
 void pc_bonus5(struct map_session_data *sd, int type, int type2, int type3, int type4, int type5, int val);
-
-enum e_addskill_type {
-	ADDSKILL_PERMANENT			= 0,	///< Permanent skill. Remove the skill if level is 0
-	ADDSKILL_TEMP				= 1,	///< Temporary skill. If player learned the skill and the given level is higher, level will be replaced and learned level will be palced in skill flag. `flag = learned + SKILL_FLAG_REPLACED_LV_0; learned_level = level;`
-	ADDSKILL_TEMP_ADDLEVEL		= 2,	///< Like PCSKILL_TEMP, except the level will be stacked. `learned_level += level`. The flag is used to store original learned level
-	ADDSKILL_PERMANENT_GRANTED	= 3,	///< Grant permanent skill, ignore skill tree and learned level
-};
-
-bool pc_skill(struct map_session_data *sd, uint16 skill_id, int level, enum e_addskill_type type);
+int pc_skill(struct map_session_data *sd, int id, int level, int flag);
 
 
 int pc_insert_card(struct map_session_data *sd,int idx_card,int idx_equip);
 int pc_insert_card(struct map_session_data *sd,int idx_card,int idx_equip);
 
 
@@ -951,7 +941,7 @@ int pc_need_status_point(struct map_session_data *,int,int);
 int pc_maxparameterincrease(struct map_session_data*,int);
 int pc_maxparameterincrease(struct map_session_data*,int);
 bool pc_statusup(struct map_session_data*,int,int);
 bool pc_statusup(struct map_session_data*,int,int);
 int pc_statusup2(struct map_session_data*,int,int);
 int pc_statusup2(struct map_session_data*,int,int);
-void pc_skillup(struct map_session_data*,uint16 skill_id);
+int pc_skillup(struct map_session_data*,uint16 skill_id);
 int pc_allskillup(struct map_session_data*);
 int pc_allskillup(struct map_session_data*);
 int pc_resetlvl(struct map_session_data*,int type);
 int pc_resetlvl(struct map_session_data*,int type);
 int pc_resetstate(struct map_session_data*);
 int pc_resetstate(struct map_session_data*);
@@ -1036,12 +1026,12 @@ int pc_mapid2jobid(unsigned short class_, int sex);	// Skotlex
 const char * job_name(int class_);
 const char * job_name(int class_);
 
 
 struct skill_tree_entry {
 struct skill_tree_entry {
-	uint16 id;
-	uint8 max;
-	uint8 joblv;
+	short id;
+	unsigned char max;
+	unsigned char joblv;
 	struct {
 	struct {
-		uint16 id;
-		uint8 lv;
+		short id;
+		unsigned char lv;
 	} need[MAX_PC_SKILL_REQUIRE];
 	} need[MAX_PC_SKILL_REQUIRE];
 }; // Celest
 }; // Celest
 extern struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE];
 extern struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE];
@@ -1144,8 +1134,6 @@ bool pc_is_same_equip_index(enum equip_index eqi, short *equip_index, short inde
 
 
 int pc_autotrade_timer(int tid, unsigned int tick, int id, intptr_t data);
 int pc_autotrade_timer(int tid, unsigned int tick, int id, intptr_t data);
 
 
-void pc_validate_skill(struct map_session_data *sd);
-
 #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
 #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
 int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_class, int type);
 int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_class, int type);
 #endif
 #endif

+ 34 - 6
src/map/script.c

@@ -8604,17 +8604,45 @@ BUILDIN_FUNC(skill)
 {
 {
 	int id;
 	int id;
 	int level;
 	int level;
-	int flag = ADDSKILL_TEMP;
+	int flag = 1;
 	TBL_PC* sd;
 	TBL_PC* sd;
 	struct script_data *data;
 	struct script_data *data;
-	const char* command = script_getfuncname(st);
 
 
 	sd = script_rid2sd(st);
 	sd = script_rid2sd(st);
 	if( sd == NULL )
 	if( sd == NULL )
 		return 0;// no player attached, report source
 		return 0;// no player attached, report source
 
 
-	if (strcmpi(command, "addtoskill") == 0)
-		flag = ADDSKILL_TEMP_ADDLEVEL;
+	data = script_getdata(st, 2);
+	get_val(st, data); // Convert into value in case of a variable
+	id = ( data_isstring(data) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
+	level = script_getnum(st,3);
+	if( script_hasdata(st,4) )
+		flag = script_getnum(st,4);
+	pc_skill(sd, id, level, flag);
+
+	return SCRIPT_CMD_SUCCESS;
+}
+
+/// Changes the level of a player skill.
+/// like skill, but <flag> defaults to 2
+///
+/// addtoskill <skill id>,<amount>,<flag>
+/// addtoskill <skill id>,<amount>
+/// addtoskill "<skill name>",<amount>,<flag>
+/// addtoskill "<skill name>",<amount>
+///
+/// @see skill
+BUILDIN_FUNC(addtoskill)
+{
+	int id;
+	int level;
+	int flag = 2;
+	TBL_PC* sd;
+	struct script_data *data;
+
+	sd = script_rid2sd(st);
+	if( sd == NULL )
+		return 0;// no player attached, report source
 
 
 	data = script_getdata(st, 2);
 	data = script_getdata(st, 2);
 	get_val(st, data); // Convert into value in case of a variable
 	get_val(st, data); // Convert into value in case of a variable
@@ -8622,7 +8650,7 @@ BUILDIN_FUNC(skill)
 	level = script_getnum(st,3);
 	level = script_getnum(st,3);
 	if( script_hasdata(st,4) )
 	if( script_hasdata(st,4) )
 		flag = script_getnum(st,4);
 		flag = script_getnum(st,4);
-	pc_skill(sd, id, level, (enum e_addskill_type)flag);
+	pc_skill(sd, id, level, flag);
 
 
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
 }
 }
@@ -19348,7 +19376,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(autobonus2,"sii??"),
 	BUILDIN_DEF(autobonus2,"sii??"),
 	BUILDIN_DEF(autobonus3,"siiv?"),
 	BUILDIN_DEF(autobonus3,"siiv?"),
 	BUILDIN_DEF(skill,"vi?"),
 	BUILDIN_DEF(skill,"vi?"),
-	BUILDIN_DEF2(skill,"addtoskill","vi?"), // [Valaris]
+	BUILDIN_DEF(addtoskill,"vi?"), // [Valaris]
 	BUILDIN_DEF(guildskill,"vi"),
 	BUILDIN_DEF(guildskill,"vi"),
 	BUILDIN_DEF(getskilllv,"v"),
 	BUILDIN_DEF(getskilllv,"v"),
 	BUILDIN_DEF(getgdskilllv,"iv"),
 	BUILDIN_DEF(getgdskilllv,"iv"),

File diff suppressed because it is too large
+ 283 - 333
src/map/skill.c


+ 61 - 107
src/map/skill.h

@@ -13,14 +13,14 @@ struct skill_unit;
 struct skill_unit_group;
 struct skill_unit_group;
 struct status_change_entry;
 struct status_change_entry;
 
 
+#define MAX_SKILL_DB			MAX_SKILL /// Max Skill DB
 #define MAX_SKILL_PRODUCE_DB	270 /// Max Produce DB
 #define MAX_SKILL_PRODUCE_DB	270 /// Max Produce DB
 #define MAX_PRODUCE_RESOURCE	12 /// Max Produce requirements
 #define MAX_PRODUCE_RESOURCE	12 /// Max Produce requirements
 #define MAX_SKILL_ARROW_DB		150 /// Max Arrow Creation DB
 #define MAX_SKILL_ARROW_DB		150 /// Max Arrow Creation DB
 #define MAX_ARROW_RESULT		5 /// Max Arrow results/created
 #define MAX_ARROW_RESULT		5 /// Max Arrow results/created
 #define MAX_SKILL_ABRA_DB		160 /// Max Skill list of Abracadabra DB
 #define MAX_SKILL_ABRA_DB		160 /// Max Skill list of Abracadabra DB
 #define MAX_SKILL_IMPROVISE_DB 30 /// Max Skill for Improvise
 #define MAX_SKILL_IMPROVISE_DB 30 /// Max Skill for Improvise
-#define MAX_SKILL_LEVEL 10 /// Max Skill Level (for skill_db storage)
-#define MAX_MOBSKILL_LEVEL 100	/// Max monster skill level (on skill usage)
+#define MAX_SKILL_LEVEL 100 /// Max Skill Level
 #define MAX_SKILL_CRIMSON_MARKER 3 /// Max Crimson Marker targets (RL_C_MARKER)
 #define MAX_SKILL_CRIMSON_MARKER 3 /// Max Crimson Marker targets (RL_C_MARKER)
 #define SKILL_NAME_LENGTH 31 /// Max Skill Name length
 #define SKILL_NAME_LENGTH 31 /// Max Skill Name length
 #define SKILL_DESC_LENGTH 31 /// Max Skill Desc length
 #define SKILL_DESC_LENGTH 31 /// Max Skill Desc length
@@ -111,116 +111,80 @@ enum e_skill_display {
 #define MAX_SKILL_ITEM_REQUIRE	10 /// Maximum required items
 #define MAX_SKILL_ITEM_REQUIRE	10 /// Maximum required items
 #define MAX_SKILL_STATUS_REQUIRE 3 /// Maximum required statuses
 #define MAX_SKILL_STATUS_REQUIRE 3 /// Maximum required statuses
 #define MAX_SKILL_EQUIP_REQUIRE 10 /// Maximum required equipped item
 #define MAX_SKILL_EQUIP_REQUIRE 10 /// Maximum required equipped item
-
-/// Single skill requirement. !TODO: Cleanup the variable types
 struct skill_condition {
 struct skill_condition {
-	int16 hp;								 ///< HP cost
-	int16 mhp;								 ///< Max HP to trigger
-	int16 sp;								 /// SP cost
-	int16 hp_rate;							 /// HP cost (%)
-	int16 sp_rate;							 /// SP cost (%)
-	uint32 zeny;							 /// Zeny cost
-	uint32 weapon;							 /// Weapon type. Combined bitmask of enum weapon_type (1<<weapon)
-	uint16 ammo;							 /// Ammo type. Combine bitmask of enum ammo_type (1<<ammo)
-	int8 ammo_qty;							 /// Amount of ammo
-	uint8 state;							 /// State/condition. @see enum e_require_state
-	int8 spiritball;						 /// Spiritball cost
-	uint16 itemid[MAX_SKILL_ITEM_REQUIRE];	 /// Required item
-	uint16 amount[MAX_SKILL_ITEM_REQUIRE];	 /// Amount of item
-	uint16 *eqItem;							 /// List of equipped item
-	enum sc_type *status;					 /// List of Status required (SC)
-	uint8 status_count,						 /// Count of SC
-		eqItem_count;						 /// Count of equipped item
+	int hp, /// HP cost
+		mhp, /// Max HP to trigger
+		sp, /// SP cost
+		hp_rate, /// HP cost (%)
+		sp_rate, /// SP cost (%)
+		ammo, /// Ammo type
+		ammo_qty, /// Amount of ammo
+		weapon, /// Weapon type
+		zeny, /// Zeny cost
+		state, /// State/condition
+		spiritball, /// Spiritball cost
+		itemid[MAX_SKILL_ITEM_REQUIRE], /// Required item
+		amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
+	uint16 *eqItem; /// List of equipped item
+	enum sc_type *status; /// List of Status required (SC)
+	uint8 status_count, /// Count of SC
+		eqItem_count; /// Count of equipped item
 };
 };
 
 
-/// Skill requirement structure. !TODO: Cleanup the variable types that use array [MAX_SKILL_LEVEL]
 struct s_skill_require {
 struct s_skill_require {
-	int hp[MAX_SKILL_LEVEL];			 ///< HP cost
-	int mhp[MAX_SKILL_LEVEL];			 ///< Max HP to trigger
-	int sp[MAX_SKILL_LEVEL];			 /// SP cost
-	int hp_rate[MAX_SKILL_LEVEL];		 /// HP cost (%)
-	int sp_rate[MAX_SKILL_LEVEL];		 /// SP cost (%)
-	int zeny[MAX_SKILL_LEVEL];			 /// Zeny cost
-	uint32 weapon;						 /// Weapon type. Combined bitmask of enum weapon_type (1<<weapon)
-	uint16 ammo;						 /// Ammo type. Combine bitmask of enum ammo_type (1<<ammo)
-	int ammo_qty[MAX_SKILL_LEVEL];		 /// Amount of ammo
-	uint8 state;						 /// State/condition. @see enum e_require_state
-	int spiritball[MAX_SKILL_LEVEL];	 /// Spiritball cost
-	int itemid[MAX_SKILL_ITEM_REQUIRE];	 /// Required item
-	int amount[MAX_SKILL_ITEM_REQUIRE];	 /// Amount of item
-	uint16 *eqItem;						 /// List of equipped item
-	enum sc_type *status;				 /// List of Status required (SC)
-	uint8 status_count,					 /// Count of SC
-		eqItem_count;					 /// Count of equipped item
+	int hp[MAX_SKILL_LEVEL], /// HP cost
+		mhp[MAX_SKILL_LEVEL], /// Max HP to trigger
+		sp[MAX_SKILL_LEVEL], /// SP cost
+		hp_rate[MAX_SKILL_LEVEL], /// HP cost (%)
+		sp_rate[MAX_SKILL_LEVEL], /// SP cost (%)
+		zeny[MAX_SKILL_LEVEL], /// Zeny cost
+		weapon, /// Weapon type
+		ammo, /// Ammo type
+		ammo_qty[MAX_SKILL_LEVEL], /// Amount of ammo
+		state, /// State/condition
+		spiritball[MAX_SKILL_LEVEL], /// Spiritball cost
+		itemid[MAX_SKILL_ITEM_REQUIRE], /// Required item
+		amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
+	uint16 *eqItem; /// List of equipped item
+	enum sc_type *status; /// List of Status required (SC)
+	uint8 status_count, /// Count of SC
+		eqItem_count; /// Count of equipped item
 };
 };
 
 
-/// Database skills. !TODO: Cleanup the variable types that use array [MAX_SKILL_LEVEL]
+/// Database skills
 struct s_skill_db {
 struct s_skill_db {
-	// skill_db.txt
-	uint16 nameid;								 ///< Skill ID
-	char name[SKILL_NAME_LENGTH];				 ///< AEGIS_Name
-	char desc[SKILL_DESC_LENGTH];				 ///< English Name
-	int range[MAX_SKILL_LEVEL];					 ///< Range
-	int8 hit;									 ///< Hit type
-	uint8 inf;									 ///< Inf: 0- passive, 1- enemy, 2- place, 4- self, 16- friend, 32- trap
-	int element[MAX_SKILL_LEVEL];				 ///< Element
-	uint8 nk;									 ///< Damage properties
-	int splash[MAX_SKILL_LEVEL];				 ///< Splash effect
-	uint8 max;									 ///< Max level
-	int num[MAX_SKILL_LEVEL];					 ///< Number of hit
-	bool castcancel;							 ///< Cancel cast when being hit
-	int16 cast_def_rate;						 ///< Def rate during cast a skill
-	uint16 skill_type;							 ///< Skill type
-	int blewcount[MAX_SKILL_LEVEL];				 ///< Blew count
-	uint32 inf2;								 ///<
-	uint32 inf3;								 ///<
-	int maxcount[MAX_SKILL_LEVEL];				 ///< Max number skill can be casted in same map
-
-	// skill_castnodex_db.txt
-	uint8 castnodex;							 ///< 1 - Not affected by dex, 2 - Not affected by SC, 4 - Not affected by item
-	uint8 delaynodex;							 ///< 1 - Not affected by dex, 2 - Not affected by SC, 4 - Not affected by item
-
-	// skill_nocast_db.txt
-	uint32 nocast;								 ///< Skill cannot be casted at this zone
-
-	// skill_unit_db.txt
-	uint16 unit_id[2];							 ///< Unit ID. @see enum s_skill_unit_id
-	int unit_layout_type[MAX_SKILL_LEVEL];		 ///< Layout type. -1 is special layout, others are square with lenght*width: (val*2+1)^2
-	int unit_range[MAX_SKILL_LEVEL];			 ///< Unit cell effect range
-	int16 unit_interval;						 ///< Interval
-	uint32 unit_target;							 ///< Unit target. @see enum e_battle_check_target
-	uint32 unit_flag;							 ///< Unit flags. @see enum e_skill_unit_flag
-
-	// skill_cast_db.txt
-	int cast[MAX_SKILL_LEVEL];				 ///< Variable casttime
+	char name[SKILL_NAME_LENGTH];
+	char desc[SKILL_DESC_LENGTH];
+	int range[MAX_SKILL_LEVEL],hit,inf,element[MAX_SKILL_LEVEL],nk,splash[MAX_SKILL_LEVEL],max;
+	int num[MAX_SKILL_LEVEL];
+	int cast[MAX_SKILL_LEVEL],walkdelay[MAX_SKILL_LEVEL],delay[MAX_SKILL_LEVEL];
 #ifdef RENEWAL_CAST
 #ifdef RENEWAL_CAST
-	int fixed_cast[MAX_SKILL_LEVEL];			 ///< If -1 means 20% than 'cast'
+	int fixed_cast[MAX_SKILL_LEVEL];
 #endif
 #endif
-	int walkdelay[MAX_SKILL_LEVEL];			 ///< Delay to walk after casting
-	int delay[MAX_SKILL_LEVEL];				 ///< Global delay (delay before reusing all skills)
-	int cooldown[MAX_SKILL_LEVEL];			 ///< Cooldown (delay before reusing same skill)
-	int upkeep_time[MAX_SKILL_LEVEL];		 ///< Duration
-	int upkeep_time2[MAX_SKILL_LEVEL];		 ///< Duration2
-
-	// skill_require_db.txt
-	struct s_skill_require require;				 ///< Skill requirement
-
-	// skill_nonearnpc_db.txt
+	int upkeep_time[MAX_SKILL_LEVEL],upkeep_time2[MAX_SKILL_LEVEL],cooldown[MAX_SKILL_LEVEL];
+	int castcancel,cast_def_rate;
+	int inf2,maxcount[MAX_SKILL_LEVEL],skill_type,inf3;
+	int blewcount[MAX_SKILL_LEVEL];
+	struct s_skill_require require;
+	int castnodex[MAX_SKILL_LEVEL], delaynodex[MAX_SKILL_LEVEL];
+	int32 nocast;
+	int unit_id[2];
+	int unit_layout_type[MAX_SKILL_LEVEL];
+	int unit_range[MAX_SKILL_LEVEL];
+	int unit_interval;
+	int unit_target;
+	int unit_flag;
 	uint8 unit_nonearnpc_range;	//additional range for UF_NONEARNPC or INF2_NO_NEARNPC [Cydh]
 	uint8 unit_nonearnpc_range;	//additional range for UF_NONEARNPC or INF2_NO_NEARNPC [Cydh]
 	uint8 unit_nonearnpc_type;	//type of NPC [Cydh]
 	uint8 unit_nonearnpc_type;	//type of NPC [Cydh]
-
-	// skill_damage_db.txt
 #ifdef ADJUST_SKILL_DAMAGE
 #ifdef ADJUST_SKILL_DAMAGE
 	struct s_skill_damage damage;
 	struct s_skill_damage damage;
 #endif
 #endif
-
-	// skill_copyable_db.txt
 	struct s_copyable { // [Cydh]
 	struct s_copyable { // [Cydh]
 		uint8 option;
 		uint8 option;
 		uint16 joballowed, req_opt;
 		uint16 joballowed, req_opt;
 	} copyable;
 	} copyable;
 };
 };
-extern struct s_skill_db **skill_db;
+extern struct s_skill_db skill_db[MAX_SKILL_DB];
 
 
 #define MAX_SKILL_UNIT_LAYOUT	52
 #define MAX_SKILL_UNIT_LAYOUT	52
 #define MAX_SKILL_UNIT_LAYOUT2	17
 #define MAX_SKILL_UNIT_LAYOUT2	17
@@ -297,7 +261,7 @@ struct skill_unit_group_tickset {
 };
 };
 
 
 
 
-enum e_skill_unit_flag {
+enum {
 	UF_DEFNOTENEMY      = 0x00001,	// If 'defunit_not_enemy' is set, the target is changed to 'friend'
 	UF_DEFNOTENEMY      = 0x00001,	// If 'defunit_not_enemy' is set, the target is changed to 'friend'
 	UF_NOREITERATION    = 0x00002,	// Spell cannot be stacked
 	UF_NOREITERATION    = 0x00002,	// Spell cannot be stacked
 	UF_NOFOOTSET        = 0x00004,	// Spell cannot be cast near/on targets
 	UF_NOFOOTSET        = 0x00004,	// Spell cannot be cast near/on targets
@@ -357,9 +321,7 @@ const char*	skill_get_desc( uint16 skill_id ); 	// [Skotlex]
 int skill_tree_get_max( uint16 skill_id, int b_class );	// Celest
 int skill_tree_get_max( uint16 skill_id, int b_class );	// Celest
 
 
 // Accessor to the skills database
 // Accessor to the skills database
-int skill_get_index_( uint16 skill_id, bool check_db );
-#define skill_get_index(skill_id)  skill_get_index_((skill_id),false) /// Get skill index from skill_id (common usage on source)
-#define skill_get_index2(skill_id) skill_get_index_((skill_id),true)  /// Get skill index from skill_id (used when reading skill_db files)
+int skill_get_index( uint16 skill_id );
 int skill_get_type( uint16 skill_id );
 int skill_get_type( uint16 skill_id );
 int skill_get_hit( uint16 skill_id );
 int skill_get_hit( uint16 skill_id );
 int skill_get_inf( uint16 skill_id );
 int skill_get_inf( uint16 skill_id );
@@ -375,7 +337,7 @@ int skill_get_delay( uint16 skill_id ,uint16 skill_lv );
 int skill_get_walkdelay( uint16 skill_id ,uint16 skill_lv );
 int skill_get_walkdelay( uint16 skill_id ,uint16 skill_lv );
 int skill_get_time( uint16 skill_id ,uint16 skill_lv );
 int skill_get_time( uint16 skill_id ,uint16 skill_lv );
 int skill_get_time2( uint16 skill_id ,uint16 skill_lv );
 int skill_get_time2( uint16 skill_id ,uint16 skill_lv );
-int skill_get_castnodex( uint16 skill_id );
+int skill_get_castnodex( uint16 skill_id ,uint16 skill_lv );
 int skill_get_castdef( uint16 skill_id );
 int skill_get_castdef( uint16 skill_id );
 int skill_get_nocast( uint16 skill_id );
 int skill_get_nocast( uint16 skill_id );
 int skill_get_unit_id(uint16 skill_id,int flag);
 int skill_get_unit_id(uint16 skill_id,int flag);
@@ -405,9 +367,6 @@ int skill_get_itemid( uint16 skill_id, int idx );
 int skill_get_itemqty( uint16 skill_id, int idx );
 int skill_get_itemqty( uint16 skill_id, int idx );
 
 
 int skill_name2id(const char* name);
 int skill_name2id(const char* name);
-uint16 skill_idx2id(uint16 idx);
-
-uint16 SKILL_MAX_DB(void);
 
 
 int skill_isammotype(struct map_session_data *sd, unsigned short skill_id);
 int skill_isammotype(struct map_session_data *sd, unsigned short skill_id);
 int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data);
 int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data);
@@ -1856,7 +1815,7 @@ enum e_skill {
 };
 };
 
 
 /// The client view ids for land skills.
 /// The client view ids for land skills.
-enum s_skill_unit_id {
+enum {
 	UNT_SAFETYWALL = 0x7e,
 	UNT_SAFETYWALL = 0x7e,
 	UNT_FIREWALL,
 	UNT_FIREWALL,
 	UNT_WARP_WAITING,
 	UNT_WARP_WAITING,
@@ -2096,9 +2055,4 @@ enum e_skill_damage_caster {
 /// Variable name of copied skill level by Reproduce
 /// Variable name of copied skill level by Reproduce
 #define SKILL_VAR_REPRODUCE_LV "REPRODUCE_SKILL_LV"
 #define SKILL_VAR_REPRODUCE_LV "REPRODUCE_SKILL_LV"
 
 
-#define SKILL_CHK_HOMUN(skill_id) ( (skill_id) >= HM_SKILLBASE && (skill_id) < HM_SKILLBASE+MAX_HOMUNSKILL )
-#define SKILL_CHK_MERC(skill_id)  ( (skill_id) >= MC_SKILLBASE && (skill_id) < MC_SKILLBASE+MAX_MERCSKILL )
-#define SKILL_CHK_ELEM(skill_id)  ( (skill_id) >= EL_SKILLBASE && (skill_id) < EL_SKILLBASE+MAX_ELEMENTALSKILL )
-#define SKILL_CHK_GUILD(skill_id) ( (skill_id) >= GD_SKILLBASE && (skill_id) < GD_SKILLBASE+MAX_GUILDSKILL )
-
 #endif /* _SKILL_H_ */
 #endif /* _SKILL_H_ */

+ 20 - 30
src/map/status.c

@@ -154,11 +154,11 @@ static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag)
 {
 {
 	uint16 idx = skill_get_index(skill_id);
 	uint16 idx = skill_get_index(skill_id);
 	if( idx == 0 ) {
 	if( idx == 0 ) {
-		ShowError("set_sc: Unsupported skill id %d (SC: %d. Icon: %d)\n", skill_id, sc, icon);
+		ShowError("set_sc: Unsupported skill id %d\n", skill_id);
 		return;
 		return;
 	}
 	}
 	if( sc < 0 || sc >= SC_MAX ) {
 	if( sc < 0 || sc >= SC_MAX ) {
-		ShowError("set_sc: Unsupported status change id %d (Skill: %d. Icon: %d)\n", sc, skill_id, icon);
+		ShowError("set_sc: Unsupported status change id %d\n", sc);
 		return;
 		return;
 	}
 	}
 
 
@@ -172,16 +172,6 @@ static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag)
 		SkillStatusChangeTable[idx] = sc;
 		SkillStatusChangeTable[idx] = sc;
 }
 }
 
 
-static void set_sc_with_vfx_noskill(sc_type sc, int icon, unsigned flag) {
-	if (sc > SC_NONE && sc < SC_MAX) {
-		if (StatusIconChangeTable[sc] == SI_BLANK)
-			StatusIconChangeTable[sc] = icon;
-		StatusChangeFlagTable[sc] |= flag;
-	}
-	if (icon > SI_BLANK && icon < SI_MAX)
-		StatusRelevantBLTypes[icon] |= BL_SCEFFECT;
-}
-
 void initChangeTables(void)
 void initChangeTables(void)
 {
 {
 	int i;
 	int i;
@@ -801,6 +791,8 @@ void initChangeTables(void)
 	set_sc( OB_OBOROGENSOU			, SC_GENSOU		, SI_GENSOU		, SCB_NONE );
 	set_sc( OB_OBOROGENSOU			, SC_GENSOU		, SI_GENSOU		, SCB_NONE );
 
 
 	set_sc( ALL_FULL_THROTTLE		, SC_FULL_THROTTLE	, SI_FULL_THROTTLE	, SCB_SPEED|SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
 	set_sc( ALL_FULL_THROTTLE		, SC_FULL_THROTTLE	, SI_FULL_THROTTLE	, SCB_SPEED|SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+	set_sc_with_vfx( SC_MOONSTAR		, SC_MOONSTAR		, SI_MOONSTAR		, SCB_NONE );
+	set_sc_with_vfx( SC_SUPER_STAR		, SC_SUPER_STAR		, SI_SUPER_STAR		, SCB_NONE );
 
 
 	/* Rebellion */
 	/* Rebellion */
 	add_sc( RL_MASS_SPIRAL		, SC_BLEEDING );
 	add_sc( RL_MASS_SPIRAL		, SC_BLEEDING );
@@ -814,26 +806,24 @@ void initChangeTables(void)
 	set_sc_with_vfx( RL_C_MARKER	, SC_C_MARKER		, SI_C_MARKER		, SCB_FLEE );
 	set_sc_with_vfx( RL_C_MARKER	, SC_C_MARKER		, SI_C_MARKER		, SCB_FLEE );
 	set_sc_with_vfx( RL_AM_BLAST	, SC_ANTI_M_BLAST	, SI_ANTI_M_BLAST	, SCB_NONE );
 	set_sc_with_vfx( RL_AM_BLAST	, SC_ANTI_M_BLAST	, SI_ANTI_M_BLAST	, SCB_NONE );
 
 
-	set_sc_with_vfx_noskill( SC_MOONSTAR	, SI_MOONSTAR	, SCB_NONE );
-	set_sc_with_vfx_noskill( SC_SUPER_STAR	, SI_SUPER_STAR	, SCB_NONE );
-	set_sc_with_vfx_noskill( SC_ALL_RIDING	, SI_ALL_RIDING	, SCB_SPEED );
+	set_sc_with_vfx( SC_ALL_RIDING		, SC_ALL_RIDING		, SI_ALL_RIDING		, SCB_SPEED );
 
 
 	/* Storing the target job rather than simply SC_SPIRIT simplifies code later on */
 	/* Storing the target job rather than simply SC_SPIRIT simplifies code later on */
-	SkillStatusChangeTable[skill_get_index(SL_ALCHEMIST)]	= (sc_type)MAPID_ALCHEMIST,
-	SkillStatusChangeTable[skill_get_index(SL_MONK)]		= (sc_type)MAPID_MONK,
-	SkillStatusChangeTable[skill_get_index(SL_STAR)]		= (sc_type)MAPID_STAR_GLADIATOR,
-	SkillStatusChangeTable[skill_get_index(SL_SAGE)]		= (sc_type)MAPID_SAGE,
-	SkillStatusChangeTable[skill_get_index(SL_CRUSADER)]	= (sc_type)MAPID_CRUSADER,
-	SkillStatusChangeTable[skill_get_index(SL_SUPERNOVICE)]	= (sc_type)MAPID_SUPER_NOVICE,
-	SkillStatusChangeTable[skill_get_index(SL_KNIGHT)]	= (sc_type)MAPID_KNIGHT,
-	SkillStatusChangeTable[skill_get_index(SL_WIZARD)]	= (sc_type)MAPID_WIZARD,
-	SkillStatusChangeTable[skill_get_index(SL_PRIEST)]	= (sc_type)MAPID_PRIEST,
-	SkillStatusChangeTable[skill_get_index(SL_BARDDANCER)]	= (sc_type)MAPID_BARDDANCER,
-	SkillStatusChangeTable[skill_get_index(SL_ROGUE)]	= (sc_type)MAPID_ROGUE,
-	SkillStatusChangeTable[skill_get_index(SL_ASSASIN)]	= (sc_type)MAPID_ASSASSIN,
-	SkillStatusChangeTable[skill_get_index(SL_BLACKSMITH)]	= (sc_type)MAPID_BLACKSMITH,
-	SkillStatusChangeTable[skill_get_index(SL_HUNTER)]	= (sc_type)MAPID_HUNTER,
-	SkillStatusChangeTable[skill_get_index(SL_SOULLINKER)]	= (sc_type)MAPID_SOUL_LINKER,
+	SkillStatusChangeTable[SL_ALCHEMIST]	= (sc_type)MAPID_ALCHEMIST,
+	SkillStatusChangeTable[SL_MONK]		= (sc_type)MAPID_MONK,
+	SkillStatusChangeTable[SL_STAR]		= (sc_type)MAPID_STAR_GLADIATOR,
+	SkillStatusChangeTable[SL_SAGE]		= (sc_type)MAPID_SAGE,
+	SkillStatusChangeTable[SL_CRUSADER]	= (sc_type)MAPID_CRUSADER,
+	SkillStatusChangeTable[SL_SUPERNOVICE]	= (sc_type)MAPID_SUPER_NOVICE,
+	SkillStatusChangeTable[SL_KNIGHT]	= (sc_type)MAPID_KNIGHT,
+	SkillStatusChangeTable[SL_WIZARD]	= (sc_type)MAPID_WIZARD,
+	SkillStatusChangeTable[SL_PRIEST]	= (sc_type)MAPID_PRIEST,
+	SkillStatusChangeTable[SL_BARDDANCER]	= (sc_type)MAPID_BARDDANCER,
+	SkillStatusChangeTable[SL_ROGUE]	= (sc_type)MAPID_ROGUE,
+	SkillStatusChangeTable[SL_ASSASIN]	= (sc_type)MAPID_ASSASSIN,
+	SkillStatusChangeTable[SL_BLACKSMITH]	= (sc_type)MAPID_BLACKSMITH,
+	SkillStatusChangeTable[SL_HUNTER]	= (sc_type)MAPID_HUNTER,
+	SkillStatusChangeTable[SL_SOULLINKER]	= (sc_type)MAPID_SOUL_LINKER,
 
 
 	/* Status that don't have a skill associated */
 	/* Status that don't have a skill associated */
 	StatusIconChangeTable[SC_WEIGHT50] = SI_WEIGHT50;
 	StatusIconChangeTable[SC_WEIGHT50] = SI_WEIGHT50;

+ 7 - 7
src/map/unit.c

@@ -1796,7 +1796,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
 
 
 	// Moved here to prevent Suffragium from ending if skill fails
 	// Moved here to prevent Suffragium from ending if skill fails
 #ifndef RENEWAL_CAST
 #ifndef RENEWAL_CAST
-	if (!(skill_get_castnodex(skill_id)&2))
+	if (!(skill_get_castnodex(skill_id, skill_lv)&2))
 		casttime = skill_castfix_sc(src, casttime);
 		casttime = skill_castfix_sc(src, casttime);
 #else
 #else
 	casttime = skill_vfcastfix(src, casttime, skill_id, skill_lv);
 	casttime = skill_vfcastfix(src, casttime, skill_id, skill_lv);
@@ -2013,7 +2013,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
 
 
 	// Moved here to prevent Suffragium from ending if skill fails
 	// Moved here to prevent Suffragium from ending if skill fails
 #ifndef RENEWAL_CAST
 #ifndef RENEWAL_CAST
-	if (!(skill_get_castnodex(skill_id)&2))
+	if (!(skill_get_castnodex(skill_id, skill_lv)&2))
 		casttime = skill_castfix_sc(src, casttime);
 		casttime = skill_castfix_sc(src, casttime);
 #else
 #else
 	casttime = skill_vfcastfix(src, casttime, skill_id, skill_lv );
 	casttime = skill_vfcastfix(src, casttime, skill_id, skill_lv );
@@ -2035,11 +2035,11 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
 // 		}
 // 		}
 // 	}
 // 	}
 
 
-	ud->skill_id    = skill_id;
-	ud->skill_lv    = skill_lv;
-	ud->skillx      = skill_x;
-	ud->skilly      = skill_y;
-	ud->skilltarget = 0;
+	ud->skill_id      = skill_id;
+	ud->skill_lv      = skill_lv;
+	ud->skillx       = skill_x;
+	ud->skilly       = skill_y;
+	ud->skilltarget  = 0;
 
 
 	if( sc ) {
 	if( sc ) {
 		// These 3 status do not stack, so it's efficient to use if-else
 		// These 3 status do not stack, so it's efficient to use if-else

Some files were not shown because too many files changed in this diff