Kaynağa Gözat

Revert "Skill DB clean ups"

Aleos 10 yıl önce
ebeveyn
işleme
0e533fa7ab

+ 0 - 5
db/const.txt

@@ -4644,10 +4644,5 @@ BSF_REM_ON_MADOGEAR	0x080
 BSF_REM_ON_DAMAGED	0x100
 BSF_PERMANENT	0x200
 
-SKILL_PERM	0
-SKILL_TEMP	1
-SKILL_TEMPLEVEL	2
-SKILL_PERM_GRANT	3
-
 false	0
 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
 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
-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
@@ -553,10 +553,10 @@
 //****
 // Whitesmith
 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
-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
@@ -768,11 +768,6 @@
 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
 
-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)
 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
 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
-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
 //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
-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
 //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
 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
-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
@@ -553,10 +553,10 @@
 //****
 // Whitesmith
 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
-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
@@ -768,11 +768,6 @@
 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
 
-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)
 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
 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
-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
-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
 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

+ 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 
 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).
 
-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 
 // level 1.
     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.";
 				set Zeny,Zeny-10000;
 				getitem 6377,5; //Buy_Stall_Permit
-				skill "ALL_BUYING_STORE",1,SKILL_PERM_GRANT;
+				skill "ALL_BUYING_STORE",1,4;
 				next;
 				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.";

+ 2 - 2
npc/other/gympass.txt

@@ -79,7 +79,7 @@ payon,173,141,4	script	Ripped Cabus#GymPass	899,{
 				mes "training together like this.";
 				delitem 7776,1; //Max_Weight_Up_Scroll
 				set gympassmemory,.@add_carry;
-				skill "ALL_INCCARRY",.@add_carry,SKILL_PERM_GRANT;
+				skill "ALL_INCCARRY",.@add_carry,4;
 				close;
 			}
 			else {
@@ -135,7 +135,7 @@ payon,173,141,4	script	Ripped Cabus#GymPass	899,{
 			mes "muscles grew back,";
 			mes "just like that! Try not to";
 			mes "wimp out again, okay?";
-			skill "ALL_INCCARRY",gympassmemory,SKILL_PERM_GRANT;
+			skill "ALL_INCCARRY",gympassmemory,4;
 			close;
 		}
 		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");
 	}
 
+	//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
 	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 i,j;
+	char t_msg[128] = "";
 	struct mmo_charstatus* cp;
 	StringBuf buf;
 	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 item tmp_item;
 	struct s_skill tmp_skill;
-	uint16 skill_count = 0;
 	struct s_friend tmp_friend;
 #ifdef HOTKEY_SAVING
 	struct hotkey tmp_hotkey;
 	int hotkey_num;
 #endif
-	StringBuf msg_buf;
 
 	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;
 	}
 
-	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
 	{
 		SqlStmt_Free(stmt);
-		StringBuf_Destroy(&msg_buf);
 		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);
 		memcpy(&p->memo_point[i], &tmp_point, sizeof(tmp_point));
 	}
-	StringBuf_AppendStr(&msg_buf, " memo");
+	strcat(t_msg, " memo");
 
 	//read inventory
 	//`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 )
 		memcpy(&p->inventory[i], &tmp_item, sizeof(tmp_item));
 
-	StringBuf_AppendStr(&msg_buf, " inventory");
+	strcat(t_msg, " inventory");
 
 	//read cart
 	//`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 )
 		memcpy(&p->cart[i], &tmp_item, sizeof(tmp_item));
-	StringBuf_AppendStr(&msg_buf, " cart");
+	strcat(t_msg, " cart");
 
 	//read storage
 	storage_fromsql(p->account_id, &p->storage);
-	StringBuf_AppendStr(&msg_buf, " storage");
+	strcat(t_msg, " storage");
 
 	//read skill
 	//`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)
-		||	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);
 
 	if( tmp_skill.flag != SKILL_FLAG_PERM_GRANTED )
 		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
 			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
 	//`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 )
 		memcpy(&p->friends[i], &tmp_friend, sizeof(tmp_friend));
-	StringBuf_AppendStr(&msg_buf, " friends");
+	strcat(t_msg, " friends");
 
 #ifdef HOTKEY_SAVING
 	//read hotkeys
@@ -1209,21 +1211,20 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
 		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);
 	}
-	StringBuf_AppendStr(&msg_buf, " hotkeys");
+	strcat(t_msg, " hotkeys");
 #endif
 
 	/* Mercenary Owner DataBase */
 	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);
 	StringBuf_Destroy(&buf);
 
 	cp = idb_ensure(char_db_, char_id, char_create_charstatus);
 	memcpy(cp, p, sizeof(struct mmo_charstatus));
-	StringBuf_Destroy(&msg_buf);
 	return 1;
 }
 

+ 8 - 10
src/common/mmo.h

@@ -54,7 +54,7 @@
 #define MAX_BANK_ZENY SINT32_MAX ///Max zeny in Bank
 #define MAX_FAME 1000000000 ///Max fame points
 #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 ACCOUNT_REG_NUM 64 ///Max permanent local 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_TEMPORARY,
 	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 {
@@ -237,9 +236,9 @@ enum e_mmo_charstatus_opt {
 };
 
 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 {
@@ -625,7 +624,6 @@ enum e_guild_skill {
 	GD_MAX,
 };
 
-#define MAX_SKILL_ID GD_MAX
 
 //These mark the ID of the jobs, as expected by the client. [Skotlex]
 enum e_job {

+ 19 - 24
src/map/atcommand.c

@@ -32,7 +32,6 @@
 #include "trade.h"
 #include "mapreg.h"
 #include "quest.h"
-#include "pc.h"
 
 #include <stdlib.h>
 #include <math.h>
@@ -3251,7 +3250,7 @@ ACMD_FUNC(questskill)
 
 		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.
 		return -1;
 	}
@@ -3264,7 +3263,7 @@ ACMD_FUNC(questskill)
 		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.
 
 	return 0;
@@ -3275,7 +3274,7 @@ ACMD_FUNC(questskill)
  *------------------------------------------*/
 ACMD_FUNC(lostskill)
 {
-	uint16 skill_id = 0, sk_idx = 0;
+	uint16 skill_id;
 	nullpo_retr(-1, sd);
 
 	if (!message || !*message || (skill_id = atoi(message)) <= 0)
@@ -3295,7 +3294,7 @@ ACMD_FUNC(lostskill)
 
 		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.
 		return -1;
 	}
@@ -3308,8 +3307,8 @@ ACMD_FUNC(lostskill)
 		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_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) ) {
 		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);
-		} 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;
 	}
 
-	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)
 		bl = &sd->hd->bl;
 	else
@@ -5644,7 +5643,7 @@ ACMD_FUNC(skilltree)
 	{
 		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);
 			meets = 0;
 		}
@@ -9119,14 +9118,13 @@ ACMD_FUNC(unloadnpcfile) {
 	return 0;
 }
 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);
 	bool need_skill = (pc_checkskill(sd, MC_PUSHCART) == 0);
-	uint16 sk_idx = 0;
 
 	if( !message || !*message || val < 0 || val > MAX_CARTS ) {
 		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;
 	}
 
-	if (!(sk_idx = skill_get_index(MC_PUSHCART)))
-		return -1;
-
 	if( need_skill ) {
-		MC_CART_MDFY(sk_idx,1);
+		MC_CART_MDFY(1);
 	}
 
 	if( !pc_setcart(sd, val) ) {
 		if( need_skill ) {
-			MC_CART_MDFY(sk_idx,0);
+			MC_CART_MDFY(0);
 		}
 		return -1;/* @cart failed */
 	}
 
 	if( need_skill ) {
-		MC_CART_MDFY(sk_idx,0);
+		MC_CART_MDFY(0);
 	}
 
 	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 map_data *mapd = &map[m];
 
-	if (!idx || !skill_db[idx]->damage.map)
+	if (!idx || !skill_db[idx].damage.map)
 		return 0;
 
-	damage = &skill_db[idx]->damage;
+	damage = &skill_db[idx].damage;
 
 	//check the adjustment works for specified 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) {
-		uint16 r_skill = 0, sk_idx = 0;
 		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) {
 				int type;
@@ -7790,7 +7789,7 @@ static const struct _battle_data {
 	{ "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,              },
 	{ "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,              },
 	{ "rare_drop_announce",                 &battle_config.rare_drop_announce,              0,      0,      10000,          },
 	{ "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) {
 			int i;
 			// 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
-			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);
@@ -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) {
 	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 ) {
 		sd->status.child = 0;

+ 45 - 62
src/map/clif.c

@@ -1486,7 +1486,7 @@ int clif_homskillinfoblock(struct map_session_data *sd)
 {	//[orn]
 	struct homun_data *hd;
 	int fd = sd->fd;
-	int i, len=4;
+	int i,j,len=4;
 	WFIFOHEAD(fd, 4+37*MAX_HOMUNSKILL);
 
 	hd = sd->hd;
@@ -1498,17 +1498,15 @@ int clif_homskillinfoblock(struct map_session_data *sd)
 		int id = hd->homunculus.hskill[i].id;
 		if( id != 0 ){
 			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+2) = ((combo)?INF_SELF_SKILL:skill_get_inf(id));
 			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);
-			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;
 		}
 	}
@@ -1521,15 +1519,12 @@ int clif_homskillinfoblock(struct map_session_data *sd)
 void clif_homskillup(struct map_session_data *sd, uint16 skill_id)
 {	//[orn]
 	struct homun_data *hd;
-	int fd;
-	short idx = -1;
+	int fd, idx;
 	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));
 	WFIFOW(fd,0) = 0x239;
@@ -4822,9 +4817,8 @@ void clif_skillinfoblock(struct map_session_data *sd)
 
 	nullpo_retv(sd);
 
-	fd = sd->fd;
-	if (!fd)
-		return;
+	fd=sd->fd;
+	if (!fd) return;
 
 	WFIFOHEAD(fd, MAX_SKILL * 37 + 4);
 	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).
 /// 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;
-	uint16 idx = 0;
 
 	nullpo_retv(sd);
 
 	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;
 
 	WFIFOHEAD(fd, packet_len(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
 		WFIFOB(fd,38) = 0;
 	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).
 /// 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
 	int fd;
-	uint16 idx = 0;
 
 	nullpo_retv(sd);
-
 	fd = sd->fd;
-	if (!fd || !(idx = skill_get_index(skill_id)))
-		return;
+	if( !fd ) return;
 
 	WFIFOHEAD(fd,packet_len(0x441));
 	WFIFOW(fd,0) = 0x441;
-	WFIFOW(fd,2) = skill_id;
+	WFIFOW(fd,2) = id;
 	WFIFOSET(fd,packet_len(0x441));
 #endif
 	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).
 /// 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) {
-	int fd;
+    int fd;
 
 	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).
 /// 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;
-	uint16 idx = skill_get_index(skill_id);
-	if (!idx)
-		return;
 
 	WFIFOHEAD(fd,packet_len(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
 		WFIFOB(fd,14) = 0;
 	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)
 		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);
 		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);
 		return;
 	}
@@ -11454,7 +11440,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
 
 	sd->skillitem = sd->skillitemlv = 0;
 
-	if( SKILL_CHK_GUILD(skill_id) ) {
+	if( skill_id >= GD_SKILLBASE ) {
 		if( sd->state.gmaster_flag )
 			skill_lv = guild_checkskill(sd->guild, skill_id);
 		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) )
 		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);
 		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);
 		return;
 	}
@@ -15695,18 +15681,15 @@ void clif_mercenary_skillblock(struct map_session_data *sd)
 	WFIFOW(fd,0) = 0x29d;
 	for( i = 0; i < MAX_MERCSKILL; i++ )
 	{
-		uint16 id;
-		short idx = -1;
+		int id, j;
 		if( (id = md->db->skill[i].id) == 0 )
 			continue;
-		if ((idx = mercenary_skill_get_index(id)) == -1)
-			continue;
-
+		j = id - MC_SKILLBASE;
 		WFIFOW(fd,len) = 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);
 		WFIFOB(fd,len+36) = 0; // Skillable for Mercenary?
 		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_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_skillcastcancel(struct block_list* bl);

+ 8 - 10
src/map/elemental.c

@@ -9,7 +9,6 @@
 #include "../common/showmsg.h"
 #include "../common/random.h"
 #include "../common/strlib.h"
-#include "../common/utils.h"
 
 #include "log.h"
 #include "clif.h"
@@ -559,12 +558,13 @@ struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16
 	memset(&req,0,sizeof(req));
 
 	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;
 }
@@ -815,7 +815,6 @@ void read_elementaldb(void) {
 	uint8 i;
 
 	elemental_count = 0;
-	memset(elemental_db, 0, sizeof(elemental_db));
 	for(i = 0; i<ARRAYLENGTH(filename); 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
 */
 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;
 
 	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]);
-	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;
 	}
 

+ 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;
 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]
  *------------------------------------------*/
@@ -98,41 +84,44 @@ static TBL_PC* guild_sd_check(int guild_id, uint32 account_id, uint32 char_id) {
 
  // Modified [Komurka]
 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 guild_skill_tree[id].max;
+	return guild_skill_tree[id-GD_SKILLBASE].max;
 }
 
 // Retrive skill_lv learned by guild
 
 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 g->skill[id].lv;
+	return g->skill[idx].lv;
 }
 
 /*==========================================
  * 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>
-	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;
 	}
 
-	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++ ) 	{
-		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;
@@ -142,13 +131,13 @@ static bool guild_read_guildskill_tree_db(char* split[], int columns, int curren
  * Guild skill check - from jA [Komurka]
  *------------------------------------------*/
 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)
 		return 0;
 
-	if ((idx = guild_skill_get_index(id)) < 0)
+	if (idx < 0 || idx >= MAX_GUILDSKILL)
 		return 0;
 
 	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
  *---------------------------------------------------*/
-void guild_skillup(TBL_PC* sd, uint16 skill_id) {
+int guild_skillup(TBL_PC* sd, uint16 skill_id) {
 	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 &&
-		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);
+
+	return 0;
 }
 
 /*====================================================
  * Notification of guildskill skill_id increase request
  *---------------------------------------------------*/
 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;
-	short idx = guild_skill_get_index(skill_id);
-
-	if (g == NULL || idx == -1)
+	if(g==NULL)
 		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);
 		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_SOULCOLD:
 			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;
 		}
 	}
 
 	// 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);
 
 	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);
 int guild_expulsion(struct map_session_data *sd,int guild_id,
 	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);
 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);

+ 24 - 24
src/map/homunculus.c

@@ -38,11 +38,10 @@ static struct view_data hom_viewdb[MAX_HOMUNCULUS_CLASS];
 * @param skill_id
 * @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;
-	skill_id -= HM_SKILLBASE;
-	if (skill_id >= MAX_HOMUNSKILL)
+	if ((skill_id -= HM_SKILLBASE) < 0 || skill_id >= MAX_HOMUNSKILL)
 		return -1;
 	return skill_id;
 }
@@ -125,8 +124,8 @@ int hom_class2mapid(int hom_class)
 void hom_addspiritball(TBL_HOM *hd, int max) {
 	nullpo_retv(hd);
 
-	if (max > MAX_SPIRITBALL)
-		max = MAX_SPIRITBALL;
+	if (max > MAX_SKILL_LEVEL)
+		max = MAX_SKILL_LEVEL;
 	if (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)
 		return;
-	if (count > MAX_SPIRITBALL)
-		count = MAX_SPIRITBALL;
+	if (count > MAX_SKILL_LEVEL)
+		count = MAX_SKILL_LEVEL;
 	if (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. */
 	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++) {
-			short idx = hom_skill_get_index(skill_id);
+			int idx = hom_skill_get_index(skill_id);
 			if (idx < 0)
 				continue;
 			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++) {
 		int intimacy;
-		short idx = hom_skill_get_index(skill_id);
+		int idx = hom_skill_get_index(skill_id);
 		if (idx < 0)
 			continue;
 		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 idx = hom_skill_get_index(skill_id);
+	int idx = hom_skill_get_index(skill_id);
 	if (idx < 0) // Invalid skill
 		return 0;
 
@@ -1461,9 +1460,8 @@ void read_homunculusdb(void) {
 */
 static bool read_homunculus_skilldb_sub(char* split[], int columns, int current)
 {// <hom class>,<skill id>,<max level>[,<job level>],<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5>,<intimacy lv req>
-	uint16 skill_id;
-	uint8 i;
-	short class_idx, idx = -1;
+	int skill_id, class_idx;
+	int i, j;
 	int minJobLevelPresent = 0;
 
 	if (columns == 14)
@@ -1471,27 +1469,29 @@ static bool read_homunculus_skilldb_sub(char* split[], int columns, int current)
 
 	// check for bounds [celest]
 	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;
 	}
 
-	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;
 	}
 
-	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)
-		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++) {
-		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;
 }
 

+ 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);
 
-short hom_skill_get_index(uint16 skill_id);
-
 void do_final_homunculus(void);
 void do_init_homunculus(void);
 

+ 0 - 4
src/map/itemdb.h

@@ -325,12 +325,8 @@ enum e_item_ammo
 	AMMO_KUNAI,
 	AMMO_CANNONBALL,
 	AMMO_THROWABLE_ITEM, ///Sling items
-
-	MAX_AMMO_TYPE,
 };
 
-#define AMMO_TYPE_ALL ((1<<MAX_AMMO_TYPE)-1)
-
 ///Item combo struct
 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;
 }
 
-/**
- * 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
 * @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
 **/
 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 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) {
 	const char *filename[]={ "mercenary_db.txt",DBIMPORT"/mercenary_db.txt"};
 	uint8 i;
-
 	mercenary_count = 0; //Reset the counter
 	memset(mercenary_db,0,sizeof(mercenary_db));
 	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)
 {// <merc id>,<skill id>,<skill level>
 	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]);
 	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]);
-	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;
 	}
 
 	db = &mercenary_db[i];
 	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;
 }
@@ -587,7 +575,6 @@ static bool mercenary_read_skilldb_sub(char* str[], int columns, int current)
 void mercenary_read_skilldb(void){
 	const char *filename[]={ "mercenary_skill_db.txt",DBIMPORT"/mercenary_skill_db.txt"};
 	uint8 i;
-
 	for(i = 0; i<ARRAYLENGTH(filename); 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);
 
 int mercenary_checkskill(struct mercenary_data *md, uint16 skill_id);
-short mercenary_skill_get_index(uint16 skill_id);
 
 /**
  * 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.
 	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_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));
 		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].permillage = 500*battle_config.mob_skill_rate/100; //Default chance of all skills: 5%
 		ms[i].emotion = -1;
@@ -4290,7 +4289,7 @@ static bool mob_parse_row_mobskilldb(char** str, int columns, int current)
 
 	//Skill ID
 	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)
 			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]
 		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) {
-				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;
 			}
 		}
@@ -1687,9 +1687,8 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
 	// custom merchant shop exp bonus
 	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 )
 		{
@@ -1851,9 +1850,8 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
 	// custom merchant shop exp bonus
 	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 )
 		{

+ 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);
 
 		// 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
-		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;
 	}
@@ -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
 	 **/
 	pc_itemcd_do(sd,true);
-	pc_validate_skill(sd);
 
 #ifdef BOUND_ITEMS
 	// 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) {
 		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].lv = pc_readglobalreg(sd,SKILL_VAR_PLAGIARISM_LV);
 			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) {
 		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].lv = pc_readglobalreg(sd,SKILL_VAR_REPRODUCE_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)
 {
-	uint16 i, skill_point = 0;
+	uint16 i, skill_point=0;
 
 	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]
-				)
-			{
+				) {
 				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);
 			}
 		}
@@ -1471,57 +1471,6 @@ static int pc_calc_skillpoint(struct map_session_data* sd)
 	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.
@@ -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)
 {
-	int i, flag;
-	int c = 0;
+	int i,flag;
+	int c=0;
 
 	nullpo_retv(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.
 		/* permanent skills that must be re-checked */
 		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:
 					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;
 			}
 		}
 	}
 
-	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].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 )
 					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].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 )
 					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].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
 	if ((sd->class_&MAPID_UPPERMASK) != MAPID_TAEKWON) {
 		uint16 c_ = pc_class2idx(JOB_TAEKWON);
-
 		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;
-				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 {
-		uint16 skid = 0;
-
+		short skid=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.
 
-			if (!battle_config.skillfree) {
-				uint8 j;
+			f = 1;
+			if(!battle_config.skillfree) {
+				int 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
-							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;
 						}
 					}
 				}
-
-				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);
 					class_ = pc_class2idx(class_);
 					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_WEDDING_SKILL ||
 					(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.
 
-				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.
-					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
 			}
@@ -1687,7 +1646,7 @@ void pc_calc_skilltree(struct map_session_data *sd)
 	} while(flag);
 
 	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
 		============================================
 		- 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. */
 
 		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)) )
 				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 )
-				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.
-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
 
 	i = pc_calc_skilltree_normalize_job(sd);
@@ -1726,54 +1682,44 @@ static void pc_check_skilltree(struct map_session_data *sd)
 		return;
 	}
 	c = pc_class2idx(c);
-
 	do {
-		uint16 skid = 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;
-
-			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
-						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;
 					}
 				}
 			}
-
-			if( fail )
+			if( !f )
 				continue;
 			if( sd->status.job_level < skill_tree[c][i].joblv )
 				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_WEDDING_SKILL ||
 				(j&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
 			) )
 				continue; //Cannot be learned via normal means.
 
-			sd->status.skill[sk_idx].id = skid;
+			sd->status.skill[id].id = id;
 			flag = 1;
 		}
 	} while(flag);
@@ -1785,12 +1731,14 @@ void pc_clean_skilltree(struct map_session_data *sd)
 {
 	uint16 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].lv = 0;
 			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].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.
  *	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);
 
-	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);
-		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
-				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);
 			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 {
-				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;
-
-		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 {
-				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
-				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);
 			break;
-
-		default:
-			return false;
+		default: //Unknown flag?
+			return 0;
 	}
-	return true;
+	return 1;
 }
 /*==========================================
  * 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);
 	
 	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);
 	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
  *------------------------------------------*/
-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;
 
 		if( sd->status.guild_id>0 && (g=sd->guild)!=NULL)
 			return guild_checkskill(g,skill_id);
 		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
  * 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);
-		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);
-		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
-			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);
 
-	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) {
 			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;
@@ -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 (
 				(inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
 				(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) ||
-				sk_id == SG_DEVIL
+				id==SG_DEVIL
 			)
 				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);
@@ -6814,8 +6765,8 @@ int pc_resetlvl(struct map_session_data* sd,int type)
 		if(sd->status.class_ == JOB_NOVICE_HIGH) {
 			sd->status.status_point=100;	// not 88 [celest]
 			// 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++ )
 	{
-		uint8 lv = sd->status.skill[i].lv;
+		int lv = sd->status.skill[i].lv;
 		int inf2;
-		uint16 skill_id = skill_idx2id(i);
-		if (lv == 0 || skill_id == 0)
-			continue;
+		if (lv < 1) continue;
 
 		inf2 = skill_get_inf2(i);
 
@@ -7001,7 +6950,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
 			continue;
 
 		// 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].flag = SKILL_FLAG_PERMANENT;
@@ -7009,13 +6958,13 @@ int pc_resetskill(struct map_session_data* sd, int flag)
 		}
 
 		// 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;
 
 		if( sd->status.skill[i].flag == SKILL_FLAG_PERM_GRANTED )
 			continue;
 
-		if( flag&4 && !skill_ischangesex(skill_id) )
+		if( flag&4 && !skill_ischangesex(i) )
 			continue;
 
 		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);
 	}
 
-	if(sd->cloneskill_idx > 0) {
+	if(sd->cloneskill_idx >= 0) {
 		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].lv = 0;
 			sd->status.skill[sd->cloneskill_idx].flag = SKILL_FLAG_PERMANENT;
 			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_LV, 0);
 	}
 
-	if(sd->reproduceskill_idx > 0) {
+	if(sd->reproduceskill_idx >= 0) {
 		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].lv = 0;
 			sd->status.skill[sd->reproduceskill_idx].flag = SKILL_FLAG_PERMANENT;
 			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_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++;
 }
 
-/**
- * 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
  *------------------------------------------*/

+ 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]
 
-	int8 spiritball, spiritball_old;
+	short spiritball, spiritball_old;
 	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.
 	int talisman_timer[ELE_POISON+1][10];
@@ -657,8 +657,6 @@ enum weapon_type {
 	W_DOUBLE_SA, // sword + axe
 };
 
-#define WEAPON_TYPE_ALL ((1<<MAX_WEAPON_TYPE)-1)
-
 enum ammo_type {
 	A_ARROW = 1,
 	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_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);
-
-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);
 
@@ -951,7 +941,7 @@ int pc_need_status_point(struct map_session_data *,int,int);
 int pc_maxparameterincrease(struct map_session_data*,int);
 bool pc_statusup(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_resetlvl(struct map_session_data*,int type);
 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_);
 
 struct skill_tree_entry {
-	uint16 id;
-	uint8 max;
-	uint8 joblv;
+	short id;
+	unsigned char max;
+	unsigned char joblv;
 	struct {
-		uint16 id;
-		uint8 lv;
+		short id;
+		unsigned char lv;
 	} need[MAX_PC_SKILL_REQUIRE];
 }; // Celest
 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);
 
-void pc_validate_skill(struct map_session_data *sd);
-
 #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);
 #endif

+ 34 - 6
src/map/script.c

@@ -8604,17 +8604,45 @@ BUILDIN_FUNC(skill)
 {
 	int id;
 	int level;
-	int flag = ADDSKILL_TEMP;
+	int flag = 1;
 	TBL_PC* sd;
 	struct script_data *data;
-	const char* command = script_getfuncname(st);
 
 	sd = script_rid2sd(st);
 	if( sd == NULL )
 		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);
 	get_val(st, data); // Convert into value in case of a variable
@@ -8622,7 +8650,7 @@ BUILDIN_FUNC(skill)
 	level = script_getnum(st,3);
 	if( script_hasdata(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;
 }
@@ -19348,7 +19376,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(autobonus2,"sii??"),
 	BUILDIN_DEF(autobonus3,"siiv?"),
 	BUILDIN_DEF(skill,"vi?"),
-	BUILDIN_DEF2(skill,"addtoskill","vi?"), // [Valaris]
+	BUILDIN_DEF(addtoskill,"vi?"), // [Valaris]
 	BUILDIN_DEF(guildskill,"vi"),
 	BUILDIN_DEF(getskilllv,"v"),
 	BUILDIN_DEF(getgdskilllv,"iv"),

Dosya farkı çok büyük olduğundan ihmal edildi
+ 283 - 333
src/map/skill.c


+ 61 - 107
src/map/skill.h

@@ -13,14 +13,14 @@ struct skill_unit;
 struct skill_unit_group;
 struct status_change_entry;
 
+#define MAX_SKILL_DB			MAX_SKILL /// Max Skill DB
 #define MAX_SKILL_PRODUCE_DB	270 /// Max Produce DB
 #define MAX_PRODUCE_RESOURCE	12 /// Max Produce requirements
 #define MAX_SKILL_ARROW_DB		150 /// Max Arrow Creation DB
 #define MAX_ARROW_RESULT		5 /// Max Arrow results/created
 #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_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 SKILL_NAME_LENGTH 31 /// Max Skill Name 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_STATUS_REQUIRE 3 /// Maximum required statuses
 #define MAX_SKILL_EQUIP_REQUIRE 10 /// Maximum required equipped item
-
-/// Single skill requirement. !TODO: Cleanup the variable types
 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 {
-	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 {
-	// 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
-	int fixed_cast[MAX_SKILL_LEVEL];			 ///< If -1 means 20% than 'cast'
+	int fixed_cast[MAX_SKILL_LEVEL];
 #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_type;	//type of NPC [Cydh]
-
-	// skill_damage_db.txt
 #ifdef ADJUST_SKILL_DAMAGE
 	struct s_skill_damage damage;
 #endif
-
-	// skill_copyable_db.txt
 	struct s_copyable { // [Cydh]
 		uint8 option;
 		uint16 joballowed, req_opt;
 	} 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_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_NOREITERATION    = 0x00002,	// Spell cannot be stacked
 	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
 
 // 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_hit( 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_time( 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_nocast( uint16 skill_id );
 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_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_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.
-enum s_skill_unit_id {
+enum {
 	UNT_SAFETYWALL = 0x7e,
 	UNT_FIREWALL,
 	UNT_WARP_WAITING,
@@ -2096,9 +2055,4 @@ enum e_skill_damage_caster {
 /// Variable name of copied skill level by Reproduce
 #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_ */

+ 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);
 	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;
 	}
 	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;
 	}
 
@@ -172,16 +172,6 @@ static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag)
 		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)
 {
 	int i;
@@ -801,6 +791,8 @@ void initChangeTables(void)
 	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_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 */
 	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_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 */
-	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 */
 	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
 #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);
 #else
 	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
 #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);
 #else
 	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 ) {
 		// These 3 status do not stack, so it's efficient to use if-else

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor