Parcourir la source

*Added Skill Damage Adjustment!
- Disabled by default on src/config/core.h. Uncomment '#define ADJUST_SKILL_DAMAGE' to enable this skill damage adjustment
- Added skill_damage_db.txt (thank Lilith for 'Manage Skill Damage')
- Added new mapflag: 'skill_damage'. Please read 'doc/mapflags.txt' for more details
*Fixed bugreport:8029 (thank exneval for testing and reporting) (Akinari)
*Follow-up 647f99f (Akinari)
*Follow-up 15074d8: optimized item_isNoEquip check parts
*and some mirror changes

Cahyadi Ramadhan Togihon il y a 11 ans
Parent
commit
cd9a776f23

+ 2 - 1
conf/msg_conf/map_msg.conf

@@ -887,7 +887,8 @@
 1049: Weather Flags:
 1050: Other Flags:
 1051: Other Flags2:
-//1052-1064 free
+1052: Skill Damage Adjustments:
+//1053-1064 free
 1065:  No Exp Penalty: %s | No Zeny Penalty: %s
 1066: On
 1067: Off

+ 46 - 0
db/skill_damage_db.txt

@@ -0,0 +1,46 @@
+// Manage skill damage database
+// ----------------------------------------------
+// rAthena dev team
+// ----------------------------------------------
+// Credits:
+//		[Lilith]
+//		[Cydh]
+// ----------------------------------------------
+// <SkillName>,<Caster>,<Map>,<Damage against Players>{,<Damage against Mobs>{,<Damage against Bosses>{,<Damage against Other>}}}
+// ----------------------------------------------
+// Caster: The adjustment only works if the caster is (bitmask)
+//		 1 = Player
+//		 2 = Monster
+//		 4 = Pet
+//		 8 = Homunculus
+//		16 = Mercenary
+//		32 = Elemental
+// Map:
+// 		1    - Normal (the maps that aren't classified as these maps below)
+// 		2    - PVP
+// 		4    - GVG
+// 		8    - Battlegrounds
+// 		16   - 'skill_damage' mapflag
+// 		Restricted zones - they're configured by 'restricted <numberCastermapflag
+// 		32   - Zone 1
+// 		64   - Zone 2
+// 		128  - Zone 3
+// 		256  - Zone 4
+// 		512  - Zone 5
+// 		1024 - Zone 6
+// 		2048 - Zone 7
+// Damage adjustments:
+// 		Using value between -100 and 100000
+//  	minus value that mean normal damage will be decreased, and positive is
+// 		otherwise. 0 = no additional rate
+// ----------------------------------------------
+// Examples:
+// 1. Mammonite: Normal maps, +50% player vs players, nothing else
+//MC_MAMMONITE,1,1,50
+// 2. Adoramus: PvP & GvG maps, if the caster is player: +50% vs player, +0% vs
+//	  mob, +10% vs boss mob, +15% vs other
+//AB_ADORAMUS,1,6,50,0,10,15
+// 3. Asura Strike: Only deals half damage (-50%) if player vs player at PvP &
+//	  GvG maps
+//MO_EXTREMITYFIST,1,6,-50
+// ----------------------------------------------

+ 34 - 1
doc/mapflags.txt

@@ -283,6 +283,39 @@ Notes:
 
 ---------------------------------------
 
+*skill_damage	{<skill_name>,<caster>,<damage1>,<damage2>,<damage3>,<damage4>}
+
+Enable skill damage adjustment on this map that used for 'Map' field on
+skill_damage_db.txt.
+
+For advanced settings, this mapflag can be used to adjust damage of 'skill' if the caster
+is 'caster', the damage will be added or reduced 'damage'% from normal damage.
+
+<skill> is name of skill, look at skill_db.txt, not the skill id. Example SM_BASH.
+<caster> is to decide who can trigger this adjustment, the invoker not only for player.
+		Using bitmask, and the available casters are:
+		 1 = Player
+		 2 = Monster
+		 4 = Pet
+		 8 = Homunculus
+		16 = Mercenary
+		32 = Elemental
+<damage1> addition rate to against player
+<damage2> addition rate to against normal monster
+<damage3> addition rate to against boss monster
+<damage4> addition rate to against other (homunculus, mercenary, pet, and elemetal)
+
+Notes:
+- If you want to adjust X skill, you need at least define 'skill' (skill name), 'caster',
+  and 'damage1'
+- This mapflag can be used to adjust all skill damages, put "all" (without quotes) at
+  'skill' column
+- Please put the damages value between -100 and 100000. 0 means no addition.
+- One map can contains up to 5 skills adjustment
+  (max. value is defined on map.h, MAX_MAP_SKILL_MODIFIER)
+
+---------------------------------------
+
 ==================
 | 3. Map Effects |
 ==================
@@ -327,7 +360,7 @@ Allows usage of item Neuralizer (ID 12213).
 *jexp	<rate>
 
 Changes the base and job experience rates on a map.
-<rate> is given as a percentage (i.e. 100 = 1x EXP). This takes into account the modifiers
+<ratecasters given as a percentage (i.e. 100 = 1x EXP). This takes into account the modifiers
 'base_exp_rate' and 'job_exp_rate' in '/conf/battle/exp.conf'.
 
 ---------------------------------------

+ 3 - 0
npc/mapflag/skill_damage.txt

@@ -0,0 +1,3 @@
+//============================================================
+//<mapname>	mapflag	skill_damage	{<skill_name>,<caster>,<damage1>,<damage2>,<damage3>,<damage4>}
+//------------------------------------------------------------

+ 6 - 5
npc/scripts_mapflags.conf

@@ -1,17 +1,19 @@
 // --------------------------------------------------------------
 // -                         Map  Flags                         -
 // --------------------------------------------------------------
-npc: npc/mapflag/nopvp.txt
+npc: npc/mapflag/battleground.txt
 npc: npc/mapflag/gvg.txt
 npc: npc/mapflag/jail.txt
+npc: npc/mapflag/night.txt
 npc: npc/mapflag/nightmare.txt
 npc: npc/mapflag/nobranch.txt
 npc: npc/mapflag/noicewall.txt
 npc: npc/mapflag/nomemo.txt
 npc: npc/mapflag/nopenalty.txt
+npc: npc/mapflag/nopvp.txt
+npc: npc/mapflag/noreturn.txt
 npc: npc/mapflag/nosave.txt
 npc: npc/mapflag/noteleport.txt
-npc: npc/mapflag/noreturn.txt
 npc: npc/mapflag/noskill.txt
 npc: npc/mapflag/nowarp.txt
 npc: npc/mapflag/nowarpto.txt
@@ -19,8 +21,7 @@ npc: npc/mapflag/nowarpto.txt
 npc: npc/mapflag/pvp.txt
 npc: npc/mapflag/pvp_noparty.txt
 npc: npc/mapflag/pvp_noguild.txt
-npc: npc/mapflag/night.txt
 npc: npc/mapflag/restricted.txt
-npc: npc/mapflag/battleground.txt
-npc: npc/mapflag/town.txt
 npc: npc/mapflag/reset.txt
+npc: npc/mapflag/skill_damage.txt
+npc: npc/mapflag/town.txt

+ 10 - 0
src/config/core.h

@@ -59,6 +59,16 @@
 /// Uncomment to enable real-time server stats (in and out data and ram usage).
 //#define SHOW_SERVER_STATS
 
+/// Uncomment to enable skill's damage adjustments [Cydh]
+/// By enabling this, db/skill_damage.txt and skill_damage mapflag will be active to add
+/// damage rate of specified skill againts player, monster, boss-monster, or other.
+/// skill_damage mapflag is used to adjust damage of specified skill at specified map
+//#define ADJUST_SKILL_DAMAGE
+/// This MAX_SKILL_DAMAGE_RATE is used to cap max the rate
+#ifdef ADJUST_SKILL_DAMAGE
+#define MAX_SKILL_DAMAGE_RATE 100000
+#endif
+
 /**
  * No settings past this point
  **/

+ 41 - 0
src/map/atcommand.c

@@ -3846,6 +3846,38 @@ ACMD_FUNC(mapinfo) {
 		sprintf(atcmd_output, msg_txt(sd,1045),map[m_id].flag.battleground); // Battlegrounds ON (type %d)
 		clif_displaymessage(fd, atcmd_output);
 	}
+
+	/* Skill damage adjustment info [Cydh] */
+#ifdef ADJUST_SKILL_DAMAGE
+	if (map[m_id].flag.skill_damage) {
+		int j;
+		clif_displaymessage(fd,msg_txt(sd,1052));	// Skill Damage Adjustments:
+		sprintf(atcmd_output," > [Map] %d%%, %d%%, %d%%, %d%% | Caster:%d"
+			,map[m_id].adjust.damage.pc
+			,map[m_id].adjust.damage.mob
+			,map[m_id].adjust.damage.boss
+			,map[m_id].adjust.damage.other
+			,map[m_id].adjust.damage.caster);
+		clif_displaymessage(fd, atcmd_output);
+		if (map[m_id].skill_damage[0].skill_id) {
+			clif_displaymessage(fd," > [Map Skill] Name : Player, Monster, Boss Monster, Other | Caster");
+			for (j = 0; j < MAX_MAP_SKILL_MODIFIER; j++) {
+				if (map[m_id].skill_damage[j].skill_id) {
+					sprintf(atcmd_output,"     %d. %s : %d%%, %d%%, %d%%, %d%% | %d"
+						,j+1
+						,skill_db[skill_get_index(map[m_id].skill_damage[j].skill_id)].name
+						,map[m_id].skill_damage[j].pc
+						,map[m_id].skill_damage[j].mob
+						,map[m_id].skill_damage[j].boss
+						,map[m_id].skill_damage[j].other
+						,map[m_id].skill_damage[j].caster);
+					clif_displaymessage(fd,atcmd_output);
+				}
+			}
+		}
+	}
+#endif
+
 	strcpy(atcmd_output,msg_txt(sd,1046)); // PvP Flags:
 	if (map[m_id].flag.pvp)
 		strcat(atcmd_output, " Pvp ON |");
@@ -7677,6 +7709,9 @@ ACMD_FUNC(mapflag) {
 		checkflag(partylock);			checkflag(guildlock);			checkflag(reset);				checkflag(chmautojoin);
 		checkflag(nousecart);			checkflag(noitemconsumption);	checkflag(nosumstarmiracle);	checkflag(nomineeffect);
 		checkflag(nolockon);			checkflag(notomb);
+#ifdef ADJUST_SKILL_DAMAGE
+		checkflag(skill_damage);
+#endif
 		clif_displaymessage(sd->fd," ");
 		clif_displaymessage(sd->fd,msg_txt(sd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
 		clif_displaymessage(sd->fd,msg_txt(sd,1313)); // Type "@mapflag available" to list the available mapflags.
@@ -7698,6 +7733,9 @@ ACMD_FUNC(mapflag) {
 	setflag(partylock);			setflag(guildlock);			setflag(reset);					setflag(chmautojoin);
 	setflag(nousecart);			setflag(noitemconsumption);	setflag(nosumstarmiracle);		setflag(nomineeffect);
 	setflag(nolockon);			setflag(notomb);
+#ifdef ADJUST_SKILL_DAMAGE
+	setflag(skill_damage);
+#endif
 
 	clif_displaymessage(sd->fd,msg_txt(sd,1314)); // Invalid flag name or flag.
 	clif_displaymessage(sd->fd,msg_txt(sd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
@@ -7710,6 +7748,9 @@ ACMD_FUNC(mapflag) {
 	clif_displaymessage(sd->fd,"fog, fireworks, sakura, leaves, nogo, nobaseexp, nojobexp, nomobloot, nomvploot,");
 	clif_displaymessage(sd->fd,"nightenabled, restricted, nodrop, novending, loadevent, nochat, partylock, guildlock,");
 	clif_displaymessage(sd->fd,"reset, chmautojoin, nousecart, noitemconsumption, nosumstarmiracle, nolockon, notomb");
+#ifdef ADJUST_SKILL_DAMAGE
+	clif_displaymessage(sd->fd,"skill_damage");
+#endif
 
 #undef checkflag
 #undef setflag

+ 154 - 8
src/map/battle.c

@@ -1698,6 +1698,128 @@ static int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id)
 	return 0;
 }
 
+/*==========================================
+ * Damage calculation for adjusting skill damage
+ * Credits:
+		[Lilith] for the first release of this
+		[Cydh] finishing and adding mapflag
+ * battle_skill_damage_skill() - skill_id based
+ * battle_skill_damage_map() - map based
+ *------------------------------------------*/
+#ifdef ADJUST_SKILL_DAMAGE
+bool battle_skill_damage_iscaster(uint8 caster, enum bl_type type)
+{
+	if (caster == 0)
+		return false;
+
+	while (1) {
+		if (caster&SDC_PC && type == BL_PC) break;
+		if (caster&SDC_MOB && type == BL_MOB) break;
+		if (caster&SDC_PET && type == BL_PET) break;
+		if (caster&SDC_HOM && type == BL_HOM) break;
+		if (caster&SDC_MER && type == BL_MER) break;
+		if (caster&SDC_ELEM && type == BL_ELEM) break;
+		return false;
+	}
+	return true;
+}
+
+int battle_skill_damage_skill(struct block_list *src, struct block_list *target, uint16 skill_id)
+{
+	unsigned short m = src->m;
+	int idx;
+	struct s_skill_damage *damage = NULL;
+	
+	if ((idx = skill_get_index(skill_id)) < 0 || !skill_db[idx].damage.map)
+		return 0;
+		
+	damage = &skill_db[idx].damage;
+
+	//check the adjustment works for specified type
+	if (!battle_skill_damage_iscaster(damage->caster,src->type))
+		return 0;
+
+	if ((damage->map&1 && (!map[m].flag.pvp && !map_flag_gvg(m) && !map[m].flag.battleground && !map[m].flag.skill_damage && !map[m].flag.restricted)) ||
+		(damage->map&2 && map[m].flag.pvp) ||
+		(damage->map&4 && map_flag_gvg(m)) ||
+		(damage->map&8 && map[m].flag.battleground) ||
+		(damage->map&16 && map[m].flag.skill_damage) ||
+		(map[m].flag.restricted && skill_db[idx].damage.map&(8*map[m].zone)))
+	{
+		switch (target->type) {
+			case BL_PC:
+				return damage->pc;
+			case BL_MOB:
+				if (is_boss(target))
+					return damage->boss;
+				else
+					return damage->mob;
+			default:
+				return damage->other;
+		}
+	}
+
+	return 0;
+}
+
+int battle_skill_damage_map(struct block_list *src, struct block_list *target, uint16 skill_id)
+{
+	int rate = 0;
+	uint16 m = src->m;
+	uint8 i;
+
+	if (!map[m].flag.skill_damage)
+		return 0;
+
+	/* modifier for all skills */
+	if (battle_skill_damage_iscaster(map[m].adjust.damage.caster,src->type)) {
+		switch (target->type) {
+			case BL_PC:
+				rate = map[m].adjust.damage.pc;
+				break;
+			case BL_MOB:
+				if (is_boss(target))
+					rate = map[m].adjust.damage.boss;
+				else
+					rate = map[m].adjust.damage.mob;
+				break;
+			default:
+				rate = map[m].adjust.damage.other;
+				break;
+		}
+	}
+
+	/* modifier for specified map */
+	ARR_FIND(0,MAX_MAP_SKILL_MODIFIER,i,map[m].skill_damage[i].skill_id == skill_id);
+	if (i < MAX_MAP_SKILL_MODIFIER) {
+		if (battle_skill_damage_iscaster(map[m].skill_damage[i].caster,src->type)) {
+			switch (target->type) {
+				case BL_PC:
+					rate += map[m].skill_damage[i].pc;
+					break;
+				case BL_MOB:
+					if (is_boss(target))
+						rate += map[m].skill_damage[i].boss;
+					else
+						rate += map[m].skill_damage[i].mob;
+					break;
+				default:
+					rate += map[m].skill_damage[i].other;
+					break;
+			}
+		}
+	}
+	return rate;
+}
+
+int battle_skill_damage(struct block_list *src, struct block_list *target, uint16 skill_id)
+{
+	if (!target)
+		return 0;
+	return battle_skill_damage_skill(src,target,skill_id) + battle_skill_damage_map(src,target,skill_id);
+}
+#endif
+
 struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag);
 struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag);
 
@@ -4057,7 +4179,7 @@ struct Damage battle_calc_attack_gvg_bg(struct Damage wd, struct block_list *src
 			if( map_flag_gvg2(target->m) )
 				wd.damage2 = battle_calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag);
 			else if( map[target->m].flag.battleground )
-				wd.damage = battle_calc_bg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag);
+				wd.damage2 = battle_calc_bg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag);
 		}
 		else
 		{
@@ -4263,7 +4385,9 @@ static struct Damage initialize_weapon_data(struct block_list *src, struct block
 static struct Damage battle_calc_weapon_attack(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int wflag)
 {
 	int i;
-
+#ifdef ADJUST_SKILL_DAMAGE
+	int skill_damage;
+#endif
 	struct map_session_data *sd, *tsd;
 	struct Damage wd;
 	struct status_change *sc = status_get_sc(src);
@@ -4386,8 +4510,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
 	}
 #endif
 
-	if(sd)
-	{
+	if(sd) {
 		if (skill_id != CR_SHIELDBOOMERANG) //Only Shield boomerang doesn't takes the Star Crumbs bonus.
 			ATK_ADD2(wd.damage, wd.damage2, wd.div_*sd->right_weapon.star, wd.div_*sd->left_weapon.star);
 		if (skill_id==MO_FINGEROFFENSIVE) { //The finger offensive spheres on moment of attack do count. [Skotlex]
@@ -4462,6 +4585,12 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
 			wd = battle_calc_attack_gvg_bg(wd, src, target, skill_id, skill_lv);
 	}
 
+	/* Skill damage adjustment */
+#ifdef ADJUST_SKILL_DAMAGE
+	if ((skill_damage = battle_skill_damage(src, target, skill_id)) != 0)
+		ATK_ADDRATE(wd.damage, wd.damage2, skill_damage);
+#endif
+
 	return wd;
 }
 
@@ -4475,6 +4604,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
 struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag)
 {
 	int i, nk;
+#ifdef ADJUST_SKILL_DAMAGE
+	int skill_damage;
+#endif
 	short s_ele = 0;
 	unsigned int skillratio = 100;	//Skill dmg modifiers.
 
@@ -5137,6 +5269,12 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 		//case HM_ERASER_CUTTER:
 	}
 
+	/* Skill damage adjustment */
+#ifdef ADJUST_SKILL_DAMAGE
+	if ((skill_damage = battle_skill_damage(src,target,skill_id)) != 0)
+		MATK_ADDRATE(skill_damage);
+#endif
+
 	return ad;
 }
 
@@ -5150,6 +5288,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag)
 {
 	int skill;
+#ifdef ADJUST_SKILL_DAMAGE
+	int skill_damage;
+#endif
 	short i, nk;
 	short s_ele;
 
@@ -5522,6 +5663,12 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
 		break;
 	}
 
+	/* Skill damage adjustment */
+#ifdef ADJUST_SKILL_DAMAGE
+	if ((skill_damage = battle_skill_damage(src,target,skill_id)) != 0)
+		md.damage += (int64)md.damage * skill_damage / 100;
+#endif
+
 	if(tstatus->mode&MD_IGNOREMISC && md.flag&(BF_MISC) )	//misc @TODO optimize me
 		md.damage = md.damage2 = 1;
 
@@ -5584,11 +5731,10 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i
 				status_change_end(bl,SC_REFLECTDAMAGE,INVALID_TIMER);
 		}
 	} else if (flag & BF_SHORT) {//Bounces back part of the damage.
-		if ( sd && sd->bonus.short_weapon_damage_return ) {
+		if ( !status_reflect && sd && sd->bonus.short_weapon_damage_return ) {
 			rdamage += damage * sd->bonus.short_weapon_damage_return / 100;
 			if(rdamage < 1) rdamage = 1;
-		}
-		if( status_reflect && sc && sc->count ) {
+		} else if( status_reflect && sc && sc->count ) {
 			if ( sc->data[SC_REFLECTSHIELD] && skill_id != WS_CARTTERMINATION ) {
 				rdamage += damage * sc->data[SC_REFLECTSHIELD]->val2 / 100;
 				if (rdamage < 1) rdamage = 1;
@@ -5608,7 +5754,7 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i
 			}
 		}
 	} else {
-		if (sd && sd->bonus.long_weapon_damage_return) {
+		if (!status_reflect && sd && sd->bonus.long_weapon_damage_return) {
 			rdamage += damage * sd->bonus.long_weapon_damage_return / 100;
 			if (rdamage < 1) rdamage = 1;
 		}

+ 14 - 8
src/map/map.c

@@ -1687,10 +1687,10 @@ int map_quit(struct map_session_data *sd) {
 		}
 	}
 
-	for( i = 0; i < EQI_MAX; i++ ) {
-		if( sd->equip_index[ i ] >= 0 )
-			if( !pc_isequip( sd , sd->equip_index[ i ] ) )
-				pc_unequipitem( sd , sd->equip_index[ i ] , 2 );
+	for (i = 0; i < EQI_MAX; i++) {
+		if (sd->equip_index[i] >= 0)
+			if (!pc_isequip(sd,sd->equip_index[i]))
+				pc_unequipitem(sd,sd->equip_index[i],2);
 	}
 
 	// Return loot to owner
@@ -3050,12 +3050,18 @@ void map_flags_init(void)
 		memset(&map[i].flag, 0, sizeof(map[i].flag));
 
 		// additional mapflag data
-		map[i].zone      = 0;  // restricted mapflag zone
-		map[i].nocommand = 0;  // nocommand mapflag level
-		map[i].bexp      = 100;  // per map base exp multiplicator
-		map[i].jexp      = 100;  // per map job exp multiplicator
+		map[i].zone        = 0;  // restricted mapflag zone
+		map[i].nocommand   = 0;  // nocommand mapflag level
+		map[i].adjust.bexp = 100;  // per map base exp multiplicator
+		map[i].adjust.jexp = 100;  // per map job exp multiplicator
 		memset(map[i].drop_list, 0, sizeof(map[i].drop_list));  // pvp nightmare drop list
 
+		// skill damage
+#ifdef ADJUST_SKILL_DAMAGE
+		memset(map[i].skill_damage, 0, sizeof(map[i].skill_damage));
+		memset(&map[i].adjust.damage, 0, sizeof(map[i].adjust.damage));
+#endif
+
 		// adjustments
 		if( battle_config.pk_mode )
 			map[i].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris]

+ 26 - 2
src/map/map.h

@@ -516,6 +516,19 @@ struct iwall_data {
 	bool shootable;
 };
 
+#ifdef ADJUST_SKILL_DAMAGE
+struct s_skill_damage {
+	uint16 map, skill_id;
+	/* additional rates */
+	int pc,
+		mob,
+		boss,
+		other;
+	uint8 caster;	/* caster type */
+};
+#define MAX_MAP_SKILL_MODIFIER 5
+#endif
+
 struct map_data {
 	char name[MAP_NAME_LENGTH];
 	uint16 index; // The map index used by the mapindex* functions.
@@ -585,6 +598,9 @@ struct map_data {
 		unsigned nomineeffect : 1; //allow /mineeffect
 		unsigned nolockon : 1;
 		unsigned notomb : 1;
+#ifdef ADJUST_SKILL_DAMAGE
+		unsigned skill_damage : 1;
+#endif
 	} flag;
 	struct point save;
 	struct npc_data *npc[MAX_NPC_PER_MAP];
@@ -597,9 +613,17 @@ struct map_data {
 	struct spawn_data *moblist[MAX_MOB_LIST_PER_MAP]; // [Wizputer]
 	int mob_delete_timer;	// [Skotlex]
 	int zone;	// zone number (for item/skill restrictions)
-	int jexp;	// map experience multiplicator
-	int bexp;	// map experience multiplicator
 	int nocommand; //Blocks @/# commands for non-gms. [Skotlex]
+	struct {
+		int jexp;	// map experience multiplicator
+		int bexp;	// map experience multiplicator
+#ifdef ADJUST_SKILL_DAMAGE
+		struct s_skill_damage damage;
+#endif
+	} adjust;
+#ifdef ADJUST_SKILL_DAMAGE
+	struct s_skill_damage skill_damage[MAX_MAP_SKILL_MODIFIER];
+#endif
 	/**
 	 * Ice wall reference counter for bugreport:3574
 	 * - since there are a thounsand mobs out there in a lot of maps checking on,

+ 2 - 2
src/map/mob.c

@@ -2250,12 +2250,12 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 			if (map[m].flag.nobaseexp || !md->db->base_exp)
 				base_exp = 0;
 			else
-				base_exp = (unsigned int)cap_value(md->db->base_exp * per * bonus/100. * map[m].bexp/100., 1, UINT_MAX);
+				base_exp = (unsigned int)cap_value(md->db->base_exp * per * bonus/100. * map[m].adjust.bexp/100., 1, UINT_MAX);
 
 			if (map[m].flag.nojobexp || !md->db->job_exp || md->dmglog[i].flag == MDLF_HOMUN) //Homun earned job-exp is always lost.
 				job_exp = 0;
 			else
-				job_exp = (unsigned int)cap_value(md->db->job_exp * per * bonus/100. * map[m].jexp/100., 1, UINT_MAX);
+				job_exp = (unsigned int)cap_value(md->db->job_exp * per * bonus/100. * map[m].adjust.jexp/100., 1, UINT_MAX);
 
 			if ( ( temp = tmpsd[i]->status.party_id)>0 ) {
 				int j;

+ 49 - 6
src/map/npc.c

@@ -3417,14 +3417,14 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
 		}
 	}
 	else if (!strcmpi(w3,"jexp")) {
-		map[m].jexp = (state) ? atoi(w4) : 100;
-		if( map[m].jexp < 0 ) map[m].jexp = 100;
-		map[m].flag.nojobexp = (map[m].jexp==0)?1:0;
+		map[m].adjust.jexp = (state) ? atoi(w4) : 100;
+		if( map[m].adjust.jexp < 0 ) map[m].adjust.jexp = 100;
+		map[m].flag.nojobexp = (map[m].adjust.jexp==0)?1:0;
 	}
 	else if (!strcmpi(w3,"bexp")) {
-		map[m].bexp = (state) ? atoi(w4) : 100;
-		if( map[m].bexp < 0 ) map[m].bexp = 100;
-		 map[m].flag.nobaseexp = (map[m].bexp==0)?1:0;
+		map[m].adjust.bexp = (state) ? atoi(w4) : 100;
+		if( map[m].adjust.bexp < 0 ) map[m].adjust.bexp = 100;
+		 map[m].flag.nobaseexp = (map[m].adjust.bexp==0)?1:0;
 	}
 	else if (!strcmpi(w3,"loadevent"))
 		map[m].flag.loadevent=state;
@@ -3450,6 +3450,49 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
 		map[m].flag.nolockon = state;
 	else if (!strcmpi(w3,"notomb"))
 		map[m].flag.notomb = state;
+	else if (!strcmpi(w3,"skill_damage")) {
+#ifdef ADJUST_SKILL_DAMAGE
+		char skill[NAME_LENGTH];
+		int pc = 0, mob = 0, boss = 0, other = 0, caster = 0;
+
+		memset(skill,0,sizeof(skill));
+		map[m].flag.skill_damage = state;	//set the mapflag
+
+		if (sscanf(w4,"%24[^,],%d,%d,%d,%d,%d[^\n]",skill,&caster,&pc,&mob,&boss,&other) >= 3) {
+			caster = (!caster) ? SDC_ALL : caster;
+			pc = cap_value(pc,-100,MAX_SKILL_DAMAGE_RATE);
+			mob = cap_value(mob,-100,MAX_SKILL_DAMAGE_RATE);
+			boss = cap_value(boss,-100,MAX_SKILL_DAMAGE_RATE);
+			other = cap_value(other,-100,MAX_SKILL_DAMAGE_RATE);
+
+			if (strcmp(skill,"all") == 0) {	//adjust damages for all skills
+				map[m].adjust.damage.caster = caster;
+				map[m].adjust.damage.pc = pc;
+				map[m].adjust.damage.mob = mob;
+				map[m].adjust.damage.boss = boss;
+				map[m].adjust.damage.other = other;
+			}
+			else if (skill_name2id(skill) <= 0)
+				ShowWarning("npc_parse_mapflag: skill_damage: Invalid skill name '%s'. Skipping (file '%s', line '%d')\n",skill,filepath,strline(buffer,start-buffer));
+			else {	//damages for specified skill
+				int i;
+				ARR_FIND(0,MAX_MAP_SKILL_MODIFIER,i,map[m].skill_damage[i].skill_id <= 0);
+				if (i >= MAX_SKILL)
+					ShowWarning("npc_parse_mapflag: skill_damage: Skill damage for map '%s' is overflow.\n",map[m].name);
+				else {
+					map[m].skill_damage[i].skill_id = skill_name2id(skill);
+					map[m].skill_damage[i].caster = caster;
+					map[m].skill_damage[i].pc = pc;
+					map[m].skill_damage[i].mob = mob;
+					map[m].skill_damage[i].boss = boss;
+					map[m].skill_damage[i].other = other;
+				}
+			}
+		}
+#else
+		ShowInfo("npc_parse_mapflag: skill_damage: ADJUST_SKILL_DAMAGE is inactive (core.h). Skipping this mapflag..\n");
+#endif
+	}
 	else
 		ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer));
 

+ 7 - 7
src/map/pc.c

@@ -949,7 +949,7 @@ int pc_isequip(struct map_session_data *sd,int n)
 	}
 
 	//fail to equip if item is restricted
-	if (itemdb_isNoEquip(item, sd->bl.m) && !battle_config.allow_equip_restricted_item)
+	if (!battle_config.allow_equip_restricted_item && itemdb_isNoEquip(item, sd->bl.m))
 		return 0;
 
 	//Not equipable by class. [Skotlex]
@@ -4888,10 +4888,10 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
 			status_change_end(&sd->bl, SC_CLOAKING, INVALID_TIMER);
 			status_change_end(&sd->bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
 		}
-		for( i = 0; i < EQI_MAX; i++ ) {
-			if( sd->equip_index[ i ] >= 0 )
-				if( !pc_isequip( sd , sd->equip_index[ i ] ) )
-					pc_unequipitem( sd , sd->equip_index[ i ] , 2 );
+		for (i = 0; i < EQI_MAX; i++) {
+			if (sd->equip_index[i] >= 0)
+				if (!pc_isequip(sd,sd->equip_index[i]))
+					pc_unequipitem(sd,sd->equip_index[i],2);
 		}
 		if (battle_config.clear_unit_onwarp&BL_PC)
 			skill_clear_unitgroup(&sd->bl);
@@ -8797,7 +8797,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
 	//OnEquip script [Skotlex]
 	if (id) {
 		//only run the script if item isn't restricted
-		if (id->equip_script && (!id->flag.no_equip || (id->flag.no_equip && itemdb_isNoEquip(id, sd->bl.m) && pc_has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT))))
+		if (id->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(id,sd->bl.m)))
 			run_script(id->equip_script,0,sd->bl.id,fake_nd->bl.id);
 		if(itemdb_isspecial(sd->status.inventory[n].card[0]))
 			; //No cards
@@ -8807,7 +8807,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
 				if (!sd->status.inventory[n].card[i])
 					continue;
 				if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) {
-					if( data->equip_script && (!data->flag.no_equip || (data->flag.no_equip && itemdb_isNoEquip(data, sd->bl.m) && pc_has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT))))
+					if (data->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(data,sd->bl.m)))
 						run_script(data->equip_script,0,sd->bl.id,fake_nd->bl.id);
 				}
 			}

+ 51 - 17
src/map/script.c

@@ -414,7 +414,8 @@ enum {
 	MF_SUMSTARTMIRACLE,
 	MF_NOMINEEFFECT,
 	MF_NOLOCKON,
-	MF_NOTOMB
+	MF_NOTOMB,
+	MF_SKILL_DAMAGE	//60
 };
 
 const char* script_op2name(int op)
@@ -10780,11 +10781,12 @@ BUILDIN_FUNC(setmapflagnosave)
 
 BUILDIN_FUNC(getmapflag)
 {
-	int16 m,i;
+	int16 m,i,type=0;
 	const char *str;
 
 	str=script_getstr(st,2);
 	i=script_getnum(st,3);
+	FETCH(4,type);
 
 	m = map_mapname2mapid(str);
 	if(m >= 0) {
@@ -10826,8 +10828,8 @@ BUILDIN_FUNC(getmapflag)
 			case MF_RESTRICTED:			script_pushint(st,map[m].flag.restricted); break;
 			case MF_NOCOMMAND:			script_pushint(st,map[m].nocommand); break;
 			case MF_NODROP:				script_pushint(st,map[m].flag.nodrop); break;
-			case MF_JEXP:				script_pushint(st,map[m].jexp); break;
-			case MF_BEXP:				script_pushint(st,map[m].bexp); break;
+			case MF_JEXP:				script_pushint(st,map[m].adjust.jexp); break;
+			case MF_BEXP:				script_pushint(st,map[m].adjust.bexp); break;
 			case MF_NOVENDING:			script_pushint(st,map[m].flag.novending); break;
 			case MF_LOADEVENT:			script_pushint(st,map[m].flag.loadevent); break;
 			case MF_NOCHAT:				script_pushint(st,map[m].flag.nochat); break;
@@ -10847,6 +10849,21 @@ BUILDIN_FUNC(getmapflag)
 			case MF_NOMINEEFFECT:		script_pushint(st,map[m].flag.nomineeffect); break;
 			case MF_NOLOCKON:			script_pushint(st,map[m].flag.nolockon); break;
 			case MF_NOTOMB:				script_pushint(st,map[m].flag.notomb); break;
+#ifdef ADJUST_SKILL_DAMAGE
+			case MF_SKILL_DAMAGE:
+				{
+					int ret_val = 0;
+					switch (type) {
+						case 1: ret_val = map[m].adjust.damage.pc; break;
+						case 2: ret_val = map[m].adjust.damage.mob; break;
+						case 3: ret_val = map[m].adjust.damage.boss; break;
+						case 4: ret_val = map[m].adjust.damage.other; break;
+						case 5: ret_val = map[m].adjust.damage.caster; break;
+						default: ret_val = map[m].flag.skill_damage; break;
+					}
+					script_pushint(st,ret_val); break;
+				} break;
+#endif
 		}
 	}
 
@@ -10869,15 +10886,14 @@ static int script_mapflag_pvp_sub(struct block_list *bl,va_list ap) {
 }
 BUILDIN_FUNC(setmapflag)
 {
-	int16 m,i;
+	int16 m,i,type=0;
 	const char *str;
 	int val=0;
 
 	str=script_getstr(st,2);
 	i=script_getnum(st,3);
-	if(script_hasdata(st,4)){
-		val=script_getnum(st,4);
-	}
+	FETCH(4,val);
+	FETCH(5,type);
 	m = map_mapname2mapid(str);
 	if(m >= 0) {
 		switch(i) {
@@ -10934,8 +10950,8 @@ BUILDIN_FUNC(setmapflag)
 				break;
 			case MF_NOCOMMAND:			map[m].nocommand = (val <= 0) ? 100 : val; break;
 			case MF_NODROP:				map[m].flag.nodrop = 1; break;
-			case MF_JEXP:				map[m].jexp = (val <= 0) ? 100 : val; break;
-			case MF_BEXP:				map[m].bexp = (val <= 0) ? 100 : val; break;
+			case MF_JEXP:				map[m].adjust.jexp = (val <= 0) ? 100 : val; break;
+			case MF_BEXP:				map[m].adjust.bexp = (val <= 0) ? 100 : val; break;
 			case MF_NOVENDING:			map[m].flag.novending = 1; break;
 			case MF_LOADEVENT:			map[m].flag.loadevent = 1; break;
 			case MF_NOCHAT:				map[m].flag.nochat = 1; break;
@@ -10955,6 +10971,19 @@ BUILDIN_FUNC(setmapflag)
 			case MF_NOMINEEFFECT:		map[m].flag.nomineeffect = 1 ; break;
 			case MF_NOLOCKON:			map[m].flag.nolockon = 1 ; break;
 			case MF_NOTOMB:				map[m].flag.notomb = 1; break;
+#ifdef ADJUST_SKILL_DAMAGE
+			case MF_SKILL_DAMAGE:
+				{
+					switch (type) {
+						case 1: map[m].adjust.damage.pc = val; break;
+						case 2: map[m].adjust.damage.mob = val; break;
+						case 3: map[m].adjust.damage.boss = val; break;
+						case 4: map[m].adjust.damage.other = val; break;
+						case 5: map[m].adjust.damage.caster = val; break;
+					}
+					map[m].flag.skill_damage = 1;
+				} break;
+#endif
 		}
 	}
 
@@ -10969,9 +10998,7 @@ BUILDIN_FUNC(removemapflag)
 
 	str=script_getstr(st,2);
 	i=script_getnum(st,3);
-	if(script_hasdata(st,4)){
-		val=script_getnum(st,4);
-	}
+	FETCH(4,val);
 	m = map_mapname2mapid(str);
 	if(m >= 0) {
 		switch(i) {
@@ -11033,8 +11060,8 @@ BUILDIN_FUNC(removemapflag)
 				break;
 			case MF_NOCOMMAND:			map[m].nocommand = 0; break;
 			case MF_NODROP:				map[m].flag.nodrop = 0; break;
-			case MF_JEXP:				map[m].jexp = 0; break;
-			case MF_BEXP:				map[m].bexp = 0; break;
+			case MF_JEXP:				map[m].adjust.jexp = 0; break;
+			case MF_BEXP:				map[m].adjust.bexp = 0; break;
 			case MF_NOVENDING:			map[m].flag.novending = 0; break;
 			case MF_LOADEVENT:			map[m].flag.loadevent = 0; break;
 			case MF_NOCHAT:				map[m].flag.nochat = 0; break;
@@ -11054,6 +11081,13 @@ BUILDIN_FUNC(removemapflag)
 			case MF_NOMINEEFFECT:		map[m].flag.nomineeffect = 0 ; break;
 			case MF_NOLOCKON:			map[m].flag.nolockon = 0 ; break;
 			case MF_NOTOMB:				map[m].flag.notomb = 0; break;
+#ifdef ADJUST_SKILL_DAMAGE
+			case MF_SKILL_DAMAGE:
+				{
+					map[m].flag.skill_damage = 0;
+					memset(&map[m].adjust.damage,0,sizeof(map[m].adjust.damage));
+				} break;
+#endif
 		}
 	}
 
@@ -18143,8 +18177,8 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(detachrid,""),
 	BUILDIN_DEF(isloggedin,"i?"),
 	BUILDIN_DEF(setmapflagnosave,"ssii"),
-	BUILDIN_DEF(getmapflag,"si"),
-	BUILDIN_DEF(setmapflag,"si?"),
+	BUILDIN_DEF(getmapflag,"si?"),
+	BUILDIN_DEF(setmapflag,"si??"),
 	BUILDIN_DEF(removemapflag,"si?"),
 	BUILDIN_DEF(pvpon,"s"),
 	BUILDIN_DEF(pvpoff,"s"),

+ 31 - 23
src/map/skill.c

@@ -2311,7 +2311,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
 	struct status_data *sstatus, *tstatus;
 	struct status_change *tsc;
 	struct map_session_data *sd, *tsd;
-	int64 damage,rdamage=0;
+	int64 damage;
 	int type;
 	int8 rmdamage=0;//magic reflected
 	bool additional_effects = true;
@@ -2443,11 +2443,6 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
 		skill_id == MER_INCAGI || skill_id == MER_BLESSING) && tsd->sc.data[SC_CHANGEUNDEAD] )
 		damage = 1;
 
-	if( damage > 0 && (( dmg.flag&BF_WEAPON && src != bl && ( src == dsrc || ( dsrc->type == BL_SKILL &&
-		( skill_id == SG_SUN_WARM || skill_id == SG_MOON_WARM || skill_id == SG_STAR_WARM ) ) ))
-		|| ((tsc && tsc->data[SC_REFLECTDAMAGE]) && !(dmg.flag&(BF_MAGIC|BF_LONG)) && !(skill_get_inf2(skill_id)&INF2_TRAP)) ) )
-		rdamage = battle_calc_return_damage(bl,src, &damage, dmg.flag, skill_id, 1);
-
 	if( damage && tsc && tsc->data[SC_GENSOU] && dmg.flag&BF_MAGIC ){
 		struct block_list *nbl;
 		nbl = battle_getenemyarea(bl,bl->x,bl->y,2,BL_CHAR,bl->id);
@@ -2821,22 +2816,6 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
 			battle_drain(sd, bl, dmg.damage, dmg.damage2, tstatus->race, tstatus->mode&MD_BOSS);
 	}
 
-	if( rdamage > 0 ) {
-		if( tsc && tsc->data[SC_REFLECTDAMAGE] ) {
-			if( src != bl )// Don't reflect your own damage (Grand Cross)
-				map_foreachinshootrange(battle_damage_area,bl,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,bl,dmg.amotion,sstatus->dmotion,rdamage,tstatus->race);
-		} else {
-			if( dmg.amotion )
-				battle_delay_damage(tick, dmg.amotion,bl,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,0,additional_effects);
-			else
-				status_fix_damage(bl,src,rdamage,0);
-			clif_damage(src,src,tick, dmg.amotion,0,rdamage,1,4,0); // in aegis damage reflected is shown in single hit.
-			//Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
-			if( tsd && src != bl )
-				battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
-			skill_additional_effect(bl, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
-		}
-	}
 	if( damage > 0 ) {
 		/**
 		 * Post-damage effects
@@ -18305,6 +18284,33 @@ static bool skill_parse_row_changematerialdb(char* split[], int columns, int cur
 	return true;
 }
 
+/*==========================================
+ * Manage Skill Damage database
+ * Credits:
+		[Lilith]
+ *------------------------------------------*/
+#ifdef ADJUST_SKILL_DAMAGE
+static bool skill_parse_row_skilldamage(char* split[], int columns, int current)
+{
+	uint16 skill_id = skill_name2id(split[0]), idx;
+	if ((idx = skill_get_index(skill_id)) < 0) { // invalid skill id
+		ShowWarning("skill_parse_row_skilldamage: Invalid skill '%s'. Skipping..",split[0]);
+		return false;
+	}
+	memset(&skill_db[idx].damage,0,sizeof(struct s_skill_damage));
+	skill_db[idx].damage.caster |= atoi(split[1]);
+	skill_db[idx].damage.map |= atoi(split[2]);
+	skill_db[idx].damage.pc = cap_value(atoi(split[3]),-100,MAX_SKILL_DAMAGE_RATE);
+	if (split[3])
+		skill_db[idx].damage.mob = cap_value(atoi(split[4]),-100,MAX_SKILL_DAMAGE_RATE);
+	if (split[4])
+		skill_db[idx].damage.boss = cap_value(atoi(split[5]),-100,MAX_SKILL_DAMAGE_RATE);
+	if (split[5])
+		skill_db[idx].damage.other = cap_value(atoi(split[6]),-100,MAX_SKILL_DAMAGE_RATE);
+	return true;
+}
+#endif
+
 /*===============================
  * DB reading.
  * skill_db.txt
@@ -18357,7 +18363,9 @@ static void skill_readdb(void)
 	sv_readdb(db_path, "skill_reproduce_db.txt", ',',   1,  1, MAX_SKILL_DB, skill_parse_row_reproducedb);
 	sv_readdb(db_path, "skill_improvise_db.txt"      , ',',   2,  2, MAX_SKILL_IMPROVISE_DB, skill_parse_row_improvisedb);
 	sv_readdb(db_path, "skill_changematerial_db.txt"      , ',',   4,  4+2*5, MAX_SKILL_PRODUCE_DB, skill_parse_row_changematerialdb);
-
+#ifdef ADJUST_SKILL_DAMAGE
+	sv_readdb(db_path, "skill_damage_db.txt"      , ',',   4,  7, MAX_SKILL_DB, skill_parse_row_skilldamage);
+#endif
 }
 
 void skill_reload (void) {

+ 18 - 0
src/map/skill.h

@@ -133,6 +133,9 @@ struct s_skill_db {
 	int unit_interval;
 	int unit_target;
 	int unit_flag;
+#ifdef ADJUST_SKILL_DAMAGE
+	struct s_skill_damage damage;
+#endif
 };
 extern struct s_skill_db skill_db[MAX_SKILL_DB];
 
@@ -1924,4 +1927,19 @@ int skill_get_elemental_type(uint16 skill_id, uint16 skill_lv);
 void skill_combo_toogle_inf(struct block_list* bl, uint16 skill_id, int inf);
 void skill_combo(struct block_list* src,struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int tick);
 
+/**
+ * Skill Damage target
+ **/
+#ifdef ADJUST_SKILL_DAMAGE
+enum e_skill_damage_caster {
+	SDC_PC   = 0x01,
+	SDC_MOB  = 0x02,
+	SDC_PET  = 0x04,
+	SDC_HOM  = 0x08,
+	SDC_MER  = 0x10,
+	SDC_ELEM = 0x20,
+	SDC_ALL  = SDC_PC|SDC_MOB|SDC_PET|SDC_HOM|SDC_MER|SDC_ELEM,
+};
+#endif
+
 #endif /* _SKILL_H_ */

+ 2 - 2
src/map/status.c

@@ -2461,7 +2461,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
 		if(!sd->inventory_data[index])
 			continue;
 
-		if(!pc_has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT) && sd->inventory_data[index]->flag.no_equip && itemdb_isNoEquip(sd->inventory_data[index], sd->bl.m)) // Items may be equipped, their effects however are nullified.
+		if(!pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) && itemdb_isNoEquip(sd->inventory_data[index],sd->bl.m)) // Items may be equipped, their effects however are nullified.
 			continue;
 
 		status->def += sd->inventory_data[index]->def;
@@ -2605,7 +2605,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
 				}
 				if(!data->script)
 					continue;
-				if(!pc_has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT) && data->flag.no_equip && itemdb_isNoEquip(data, sd->bl.m)) //Card restriction checks.
+				if(!pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) && itemdb_isNoEquip(data,sd->bl.m)) //Card restriction checks.
 					continue;
 				if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L)
 				{	//Left hand status.