Bladeren bron

Implemented new item script bonuses:
- bSkillCooldown,n,x;
- bSkillFixedCast,n,x;
- *bSkillVariableCast,n,x;
- bFixedCastrate,x;
- *bVariableCastrate,x;
*Pending until RE Casting system is fully implemented.
ATM bCastrate is used to manipulate variable cast time where it should not.

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

rud0lp20 13 jaren geleden
bovenliggende
commit
2cf6927750
8 gewijzigde bestanden met toevoegingen van 102 en 8 verwijderingen
  1. 5 0
      db/const.txt
  2. 1 1
      db/re/item_db.txt
  3. 2 1
      src/map/map.h
  4. 57 1
      src/map/pc.c
  5. 2 2
      src/map/pc.h
  6. 3 0
      src/map/script.c
  7. 23 3
      src/map/skill.c
  8. 9 0
      src/map/status.c

+ 5 - 0
db/const.txt

@@ -581,6 +581,11 @@ bMatk	2047
 bSPGainRaceAttack	2048
 bHPGainRaceAttack	2049
 bUseSPrateSkill	2050
+bSkillCooldown	2051
+bSkillFixedCast	2052
+bSkillVariableCast	2053
+bFixedCastrate	2054
+bVariableCastrate	2055
 
 EQI_HEAD_TOP	1
 EQI_ARMOR	2

+ 1 - 1
db/re/item_db.txt

@@ -941,7 +941,7 @@
 1651,P_Staff2,Eden Staff II,4,0,,0,60:150,,1,0,0x00818314,7,2,2,2,40,0,10,{ bonus bInt,3; },{},{}
 1652,Tourist_Staff,Tourist Staff,4,0,,500,35:0,,1,0,0x00818315,7,2,2,1,1,0,10,{ bonus bInt,2; bonus bAgi,1; },{},{}
 1653,Staff_Of_Healing_C,Staff of Healing,4,20,,0,10:100,,1,0,0x00008110,7,2,2,3,1,0,10,{ bonus bAtkEle,Ele_Holy; },{},{}
-1654,Mental_Stick,Mental Stick,4,20,,500,40:170,,1,1,0x00818315,7,2,2,3,102,1,10,{ if (getrefine() > 5) { /* bonus bSkillAtk,"SO_PSYCHIC_WAVE",(getrefine()-5)*2; */ bonus bMaxHPRate,-(getrefine()-5)*2; } /* bonus2 bVariableCastTime,"SO_PSYCHIC_WAVE",-3000; bonus2 bUseSPAmount,"SO_PSYCHIC_WAVE",-60; */ },{},{ itemheal 0,-100; }
+1654,Mental_Stick,Mental Stick,4,20,,500,40:170,,1,1,0x00818315,7,2,2,3,102,1,10,{ if (getrefine() > 5) { /* bonus bSkillAtk,"SO_PSYCHIC_WAVE",(getrefine()-5)*2; */ bonus bMaxHPRate,-(getrefine()-5)*2; } /* bonus2 bSkillVariableCast,"SO_PSYCHIC_WAVE",-3000; bonus2 bUseSPAmount,"SO_PSYCHIC_WAVE",-60; */ },{},{ itemheal 0,-100; }
 //1655,
 //1656,
 1657,Mercy_Staff1,Mercy Staff I,4,20,,500,30:160,,1,2,0x00000100,7,2,2,3,100,1,10,{ bonus bInt,2; bonus bAtkEle,Ele_Holy; bonus bHealPower,10; if(isequipped(2471,2569,15029)){ bonus bHealPower,25; }; },{},{}

+ 2 - 1
src/map/map.h

@@ -392,7 +392,8 @@ enum _sp {
 	SP_UNSTRIPABLE_WEAPON,SP_UNSTRIPABLE_ARMOR,SP_UNSTRIPABLE_HELM,SP_UNSTRIPABLE_SHIELD,  // 2034-2037
 	SP_INTRAVISION, SP_ADD_MONSTER_DROP_ITEMGROUP, SP_SP_LOSS_RATE, // 2038-2040
 	SP_ADD_SKILL_BLOW, SP_SP_VANISH_RATE, SP_MAGIC_SP_GAIN_VALUE, SP_MAGIC_HP_GAIN_VALUE, SP_ADD_CLASS_DROP_ITEM, //2041-2045
-	SP_WEAPON_MATK, SP_BASE_MATK, SP_SP_GAIN_RACE_ATTACK, SP_HP_GAIN_RACE_ATTACK, SP_SP_RATE_SKILL //2046-2050
+	SP_WEAPON_MATK, SP_BASE_MATK, SP_SP_GAIN_RACE_ATTACK, SP_HP_GAIN_RACE_ATTACK, SP_SP_RATE_SKILL, //2046-2050
+	SP_SKILL_COOLDOWN,SP_SKILL_FIXEDCAST, SP_SKILL_VARIABLECAST, SP_FIXCASTRATE, SP_VARCASTRATE //2051-2055
 };
 
 enum _look {

+ 57 - 1
src/map/pc.c

@@ -2583,6 +2583,14 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
 		if(sd->state.lr_flag != 2)
 			sd->bonus.sp_base_matk += val;
 		break;
+	case SP_FIXCASTRATE:
+		if(sd->state.lr_flag != 2)
+			sd->fixcastrate+=val;
+		break;
+	case SP_VARCASTRATE:
+		if(sd->state.lr_flag != 2)
+			sd->varcastrate+=val;
+		break;
 	default:
 		ShowWarning("pc_bonus: unknown type %d %d !\n",type,val);
 		break;
@@ -3064,7 +3072,55 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
 			sd->sprateskill[i].id = type2;
 			sd->sprateskill[i].val = val;
 		}
-		break;			
+		break;		
+	case SP_SKILL_COOLDOWN:
+		if(sd->state.lr_flag == 2)
+			break;
+		ARR_FIND(0, ARRAYLENGTH(sd->skillcooldown), i, sd->skillcooldown[i].id == 0 || sd->skillcooldown[i].id == type2);
+		if (i == ARRAYLENGTH(sd->skillcooldown))
+		{	
+			ShowDebug("run_script: bonus2 bSkillCoolDown reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillcooldown), type2, val);
+			break;
+		}
+		if (sd->skillcooldown[i].id == type2)
+			sd->skillcooldown[i].val += val;
+		else {
+			sd->skillcooldown[i].id = type2;
+			sd->skillcooldown[i].val = val;
+		}
+		break;
+	case SP_SKILL_FIXEDCAST:
+		if(sd->state.lr_flag == 2)
+			break;
+		ARR_FIND(0, ARRAYLENGTH(sd->skillfixcast), i, sd->skillfixcast[i].id == 0 || sd->skillfixcast[i].id == type2);
+		if (i == ARRAYLENGTH(sd->skillfixcast))
+		{	
+			ShowDebug("run_script: bonus2 bSkillFixedCast reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillfixcast), type2, val);
+			break;
+		}
+		if (sd->skillfixcast[i].id == type2)
+			sd->skillfixcast[i].val += val;
+		else {
+			sd->skillfixcast[i].id = type2;
+			sd->skillfixcast[i].val = val;
+		}
+		break;
+	case SP_SKILL_VARIABLECAST:
+		if(sd->state.lr_flag == 2)
+			break;
+		ARR_FIND(0, ARRAYLENGTH(sd->skillvarcast), i, sd->skillvarcast[i].id == 0 || sd->skillvarcast[i].id == type2);
+		if (i == ARRAYLENGTH(sd->skillvarcast))
+		{	
+			ShowDebug("run_script: bonus2 bSkillVariableCast reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillvarcast), type2, val);
+			break;
+		}
+		if (sd->skillvarcast[i].id == type2)
+			sd->skillvarcast[i].val += val;
+		else {
+			sd->skillvarcast[i].id = type2;
+			sd->skillvarcast[i].val = val;
+		}
+		break;
 	default:
 		ShowWarning("pc_bonus2: unknown type %d %d %d!\n",type,type2,val);
 		break;

+ 2 - 2
src/map/pc.h

@@ -261,7 +261,7 @@ struct map_session_data {
 	struct { //skillatk raises bonus dmg% of skills, skillheal increases heal%, skillblown increases bonus blewcount for some skills.
 		unsigned short id;
 		short val;
-	} skillatk[MAX_PC_BONUS], sprateskill[MAX_PC_BONUS], skillheal[5], skillheal2[5], skillblown[MAX_PC_BONUS], skillcast[MAX_PC_BONUS];
+	} skillatk[MAX_PC_BONUS], sprateskill[MAX_PC_BONUS], skillheal[5], skillheal2[5], skillblown[MAX_PC_BONUS], skillcast[MAX_PC_BONUS], skillcooldown[MAX_PC_BONUS], skillfixcast[MAX_PC_BONUS], skillvarcast[MAX_PC_BONUS];
 	struct {
 		short value;
 		int rate;
@@ -322,7 +322,7 @@ struct map_session_data {
 
 	// zeroed vars end here.
 
-	int castrate,delayrate,hprate,sprate,dsprate;
+	int castrate,delayrate,hprate,sprate,dsprate,fixcastrate,varcastrate;
 	int hprecov_rate,sprecov_rate;
 	int matk_rate;
 	int critical_rate,hit_rate,flee_rate,flee2_rate,def_rate,def2_rate,mdef_rate,mdef2_rate;

+ 3 - 0
src/map/script.c

@@ -7358,6 +7358,9 @@ BUILDIN_FUNC(bonus)
 		case SP_CASTRATE:
 		case SP_ADDEFF_ONSKILL:
 		case SP_SP_RATE_SKILL:
+		case SP_SKILL_COOLDOWN:
+		case SP_SKILL_FIXEDCAST:
+		case SP_SKILL_VARIABLECAST:
 			// these bonuses support skill names
 			val1 = ( script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3) );
 			break;

+ 23 - 3
src/map/skill.c

@@ -8837,8 +8837,16 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
 
 		if( !sd || sd->skillitem != ud->skillid || skill_get_delay(ud->skillid,ud->skilllv) )
 			ud->canact_tick = tick + skill_delayfix(src, ud->skillid, ud->skilllv); //Tests show wings don't overwrite the delay but skill scrolls do. [Inkfish]
-		if( sd && skill_get_cooldown(ud->skillid,ud->skilllv) > 0 )
-			skill_blockpc_start(sd, ud->skillid, skill_get_cooldown(ud->skillid, ud->skilllv));
+		if( sd && skill_get_cooldown(ud->skillid,ud->skilllv) > 0 ){
+			int i, cooldown = skill_get_cooldown(ud->skillid, ud->skilllv);
+			for (i = 0; i < ARRAYLENGTH(sd->skillcooldown) && sd->skillcooldown[i].id; i++) { // Increases/Decreases cooldown of a skill by item/card bonuses.
+				if (sd->skillcooldown[i].id == ud->skillid){
+					cooldown += sd->skillcooldown[i].val;
+					break;
+				}
+			}
+			skill_blockpc_start(sd, ud->skillid, cooldown);
+		}
 		if( battle_config.display_status_timers && sd )
 			clif_status_change(src, SI_ACTIONDELAY, 1, skill_delayfix(src, ud->skillid, ud->skilllv), 0, 0, 0);
 		if( sd )
@@ -13001,12 +13009,24 @@ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv)
  *------------------------------------------*/
 int skill_castfix_sc (struct block_list *bl, int time, int skill_id, int skill_lv) {
 	struct status_change *sc = status_get_sc(bl);
+	struct map_session_data *sd = BL_CAST(BL_PC,bl);
 #ifdef RENEWAL_CAST
 	int fixed = skill_get_fixed_cast(skill_id, skill_lv);
 	if( !fixed ) {
 		fixed = skill_get_cast(skill_id, skill_lv);
 		fixed = ( fixed > 1 ? ( fixed * 20 / 100 ) : 0 );
 	}
+	if(sd){// Increases/Decreases fixed cast time of a skill by item/card bonuses.
+		int i;
+		if( sd->fixcastrate != 100 )
+			fixed = fixed * sd->fixcastrate / 100;
+		for (i = 0; i < ARRAYLENGTH(sd->skillfixcast) && sd->skillfixcast[i].id; i++) { 
+			if (sd->skillfixcast[i].id == skill_id){
+				fixed += sd->skillfixcast[i].val;
+				break;
+			}
+		}
+	}
 #endif
 	if (sc && sc->count) {
 		if (sc->data[SC_SLOWCAST])
@@ -13038,7 +13058,7 @@ int skill_castfix_sc (struct block_list *bl, int time, int skill_id, int skill_l
 	/**
 	 * WL_RADIUS decreases 10/15/20% fixed cast time from warlock skills
 	 **/
-	if( bl->type == BL_PC && skill_id >= WL_WHITEIMPRISON && skill_id <= WL_FREEZE_SP && ( skill_lv = pc_checkskill((TBL_PC*)bl, WL_RADIUS) ) )
+	if( sd && skill_id >= WL_WHITEIMPRISON && skill_id <= WL_FREEZE_SP && ( skill_lv = pc_checkskill(sd, WL_RADIUS) ) )
 		fixed -= fixed * (5+(skill_lv*5)) / 100;
 	return (time > 0 || fixed > 0) ? cap_value( time , fixed , INT_MAX ) : 0;
 #else

+ 9 - 0
src/map/status.c

@@ -2274,6 +2274,8 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
 	sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100;
 	sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
 	sd->regen.state.block = 0;
+	sd->fixcastrate=100;
+	sd->varcastrate=100;
 
 	// zeroed arrays, order follows the order in pc.h.
 	// add new arrays to the end of zeroed area in pc.h (see comments) and size here. [zzo]
@@ -2354,6 +2356,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
 		+ sizeof(sd->add_drop)
 		+ sizeof(sd->itemhealrate)
 		+ sizeof(sd->subele2)
+		+ sizeof(sd->skillcooldown)
+		+ sizeof(sd->skillfixcast)
+		+ sizeof(sd->skillvarcast)
 	);
 	
 	memset (&sd->bonus, 0,sizeof(sd->bonus));
@@ -2908,6 +2913,10 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
 		sd->hprecov_rate = 0;
 	if(sd->sprecov_rate < 0)
 		sd->sprecov_rate = 0;
+	if(sd->fixcastrate < 0)
+		sd->fixcastrate = 0;
+	if(sd->varcastrate < 0)
+		sd->varcastrate = 0;
 
 	// Anti-element and anti-race
 	if((skill=pc_checkskill(sd,CR_TRUST))>0)