From 1c9fdc0d3bbe2993ac1e8a31045ccbc60b8fbe26 Mon Sep 17 00:00:00 2001
From: shennetsind <ind@henn.et>
Date: Mon, 15 Apr 2013 22:32:10 -0300
Subject: Fixed Bug #7154

http://hercules.ws/board/tracker/issue-7154-equipment-based-skills-skill-891-for-example-persisting-through-resetsremoving-gears/
Merge of 3a9bacc515674885f079391899b22a5ccd8c2e31
Special Thanks to akinari1087
http://hercules.ws/board/topic/410-skill-script-command-updatefix/

Signed-off-by: shennetsind <ind@henn.et>
---
 src/map/pc.c | 88 +++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 49 insertions(+), 39 deletions(-)

(limited to 'src')

diff --git a/src/map/pc.c b/src/map/pc.c
index 01df6bb64..0e1656b91 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -3436,11 +3436,11 @@ int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4
 }
 
 /*==========================================
- *	Grants a player a given skill. Flag values are:
- *	0 - Grant skill unconditionally and forever (only this one invokes status_calc_pc,
- *	    as the other two are assumed to be invoked from within it)
- *	1 - Grant an item skill (temporary)
- *	2 - Like 1, except the level granted can stack with previously learned level.
+ * Grants a player a given skill. Flag values are:
+ * 0 - Grant permanent skill to be bound to skill tree
+ * 1 - Grant an item skill (temporary)
+ * 2 - Like 1, except the level granted can stack with previously learned level.
+ * 3 - Grant skill unconditionally and forever (persistent to job changes and skill resets)
  *------------------------------------------*/
 int pc_skill(TBL_PC* sd, int id, int level, int flag)
 {
@@ -3460,42 +3460,52 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag)
 	}
 
 	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_PERM_GRANTED;
-		if( level == 0 ) //Remove skill.
-		{
-			sd->status.skill[id].id = 0;
-			clif->deleteskill(sd,id);
-		}
-		else
-			clif->addskill(sd,id);
-		if( !skill->get_inf(id) ) //Only recalculate for passive skills.
-			status_calc_pc(sd, 0);
-	break;
-	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 {
+		case 0: //Set skill data overwriting whatever was there before.
 			sd->status.skill[id].id   = id;
-			sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY;
-		}
-		sd->status.skill[id].lv = level;
-	break;
-	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[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,id);
+			if( !skill->get_inf(id) ) //Only recalculate for passive skills.
+				status_calc_pc(sd, 0);
+		break;
+		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[id].id   = id;
+				sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY;
+			}
+			sd->status.skill[id].lv = level;
+		break;
+		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[id].id   = id;
+				sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //Set that this is a bonus skill.
+			}
+			sd->status.skill[id].lv += level;
+		break;
+		case 3:
 			sd->status.skill[id].id   = id;
-			sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //Set that this is a bonus skill.
-		}
-		sd->status.skill[id].lv += level;
-	break;
+			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,id);
+			if( !skill->get_inf(id) ) //Only recalculate for passive skills.
+				status_calc_pc(sd, 0);
+			break;
 	default: //Unknown flag?
 		return 0;
 	}
-- 
cgit v1.2.3-70-g09d2