Browse Source

- cleaned up status_check_skilluse some to use status_data variables.
- Fixed mvp-exp calculations being messed up with more than one attacker.
- Changed the mob exp race bonus so that each player gets their own bonus, rather than the killer's bonus applying to everyone.


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

skotlex 19 years ago
parent
commit
4f89660d1a
3 changed files with 57 additions and 39 deletions
  1. 5 0
      Changelog-Trunk.txt
  2. 8 9
      src/map/mob.c
  3. 44 30
      src/map/status.c

+ 5 - 0
Changelog-Trunk.txt

@@ -4,6 +4,11 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2006/06/06
+	* Fixed mvp-exp calculations being messed up with more than one attacker.
+	  [Skotlex]
+	* Changed the mob exp race bonus so that each player gets their own bonus,
+	  rather than the killer's bonus applying to everyone. Still not the
+	  "correct" way, but one step closer to it. [Skotlex]
 	* [Fixed]:
 	  - Allocation of event_list in guild_npc_request_info to aCalloc so 
 	    memcpy(ev->name,event,strlen(event)) will have a null terminator. [Lance]

+ 8 - 9
src/map/mob.c

@@ -1723,9 +1723,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 		}
 	}
 
-	for(temp=0,i=0,count=0,mvp_damage=0;i<DAMAGELOG_SIZE && md->dmglog[i].id;i++)
+	for(temp=0,i=0,mvp_damage=0;i<DAMAGELOG_SIZE && md->dmglog[i].id;i++)
 	{
-		count++; //Count an attacker even if he is dead/logged-out.
 		tmpsd[temp] = map_charid2sd(md->dmglog[i].id);
 		if(tmpsd[temp] == NULL)
 			continue;
@@ -1733,13 +1732,14 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 			continue;
 		temp++;
 
-		if(mvp_damage<(unsigned int)md->dmglog[temp].dmg){
+		if(mvp_damage<(unsigned int)md->dmglog[i].dmg){
 			third_sd = second_sd;
 			second_sd = mvp_sd;
 			mvp_sd=tmpsd[temp];
-			mvp_damage=md->dmglog[temp].dmg;
+			mvp_damage=md->dmglog[i].dmg;
 		}
 	}
+	count = i; //Total number of attackers.
 
 	if(!(type&2) && //No exp
 		(!map[md->bl.m].flag.pvp || battle_config.pvp_exp) && //Pvp no exp rule [MouseJstr]
@@ -1773,11 +1773,10 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 		if (md->sc.data[SC_RICHMANKIM].timer != -1)
 			bonus += md->sc.data[SC_RICHMANKIM].val2;
 
-		if(sd) {
-			if (sd->expaddrace[status->race])
-				bonus += sd->expaddrace[status->race];	
-			bonus += sd->expaddrace[status->mode&MD_BOSS?RC_BOSS:RC_NONBOSS];
-		}
+		if (tmpsd[i]->expaddrace[status->race])
+			bonus += tmpsd[i]->expaddrace[status->race];	
+		bonus += tmpsd[i]->expaddrace[status->mode&MD_BOSS?RC_BOSS:RC_NONBOSS];
+	
 		if (battle_config.pk_mode &&
 			(int)(md->db->lv - tmpsd[i]->status.base_level) >= 20) //Needed due to unsigned checks
 			bonus += 15; // pk_mode additional exp if monster >20 levels [Valaris]	

+ 44 - 30
src/map/status.c

@@ -793,16 +793,17 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
  */
 int status_check_skilluse(struct block_list *src, struct block_list *target, int skill_num, int flag)
 {
-	int mode, race, hide_flag;
+	struct status_data *status;
 	struct status_change *sc=NULL, *tsc;
+	int hide_flag;
 
-	mode = src?status_get_mode(src):MD_CANATTACK;
+	status = src?status_get_status_data(src):&dummy_status;
 
 	if (src && status_isdead(src))
 		return 0;
 	
 	if (!skill_num) { //Normal attack checks.
-		if (!(mode&MD_CANATTACK))
+		if (!(status->mode&MD_CANATTACK))
 			return 0; //This mode is only needed for melee attacking.
 		//Dead state is not checked for skills as some skills can be used 
 		//on dead characters, said checks are left to skill.c [Skotlex]
@@ -824,24 +825,24 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
 
 	if (((src && map_getcell(src->m,src->x,src->y,CELL_CHKBASILICA)) ||
 		(target && target != src && map_getcell(target->m,target->x,target->y,CELL_CHKBASILICA)))
-		&& !(mode&MD_BOSS))
+		&& !(status->mode&MD_BOSS))
 	{	//Basilica Check
 		if (!skill_num) return 0;
-		race = skill_get_inf(skill_num);
-		if (race&INF_ATTACK_SKILL)
+		hide_flag = skill_get_inf(skill_num);
+		if (hide_flag&INF_ATTACK_SKILL)
 			return 0;
-		if (race&INF_GROUND_SKILL && skill_get_unit_target(skill_num)&BCT_ENEMY)
+		if (hide_flag&INF_GROUND_SKILL && skill_get_unit_target(skill_num)&BCT_ENEMY)
 			return 0;
 	}	
 
 	if (src) sc = status_get_sc(src);
 	
-	if(sc && sc->opt1 >0 && (battle_config.sc_castcancel || flag != 1))
-		//When sc do not cancel casting, the spell should come out.
-		return 0;
-	
 	if(sc && sc->count)
 	{
+		if(sc->opt1 >0 && (battle_config.sc_castcancel || flag != 1))
+			//When sc do not cancel casting, the spell should come out.
+			return 0;
+
 		if (
 			(sc->data[SC_TRICKDEAD].timer != -1 && skill_num != NV_TRICKDEAD)
 			|| (sc->data[SC_AUTOCOUNTER].timer != -1 && !flag)
@@ -850,8 +851,8 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
 		)
 			return 0;
 
-		if (sc->data[SC_WINKCHARM].timer != -1 && target && target->type == BL_PC && !flag)
-		{	//Prevents skill usage against players?
+		if (sc->data[SC_WINKCHARM].timer != -1 && target && !flag)
+		{	//Prevents skill usage
 			clif_emotion(src, 3);
 			return 0;
 		}
@@ -880,7 +881,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
 			//Skill blocking.
 			if (
 				(sc->data[SC_VOLCANO].timer != -1 && skill_num == WZ_ICEWALL) ||
-				(sc->data[SC_ROKISWEIL].timer != -1 && skill_num != BD_ADAPTATION && !(mode&MD_BOSS)) ||
+				(sc->data[SC_ROKISWEIL].timer != -1 && skill_num != BD_ADAPTATION && !(status->mode&MD_BOSS)) ||
 				(sc->data[SC_HERMODE].timer != -1 && skill_get_inf(skill_num) & INF_SUPPORT_SKILL) ||
 				sc->data[SC_NOCHAT].timer != -1
 			)
@@ -899,12 +900,18 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
 
 	if (sc && sc->option)
 	{
-		if (sc->option&OPTION_HIDE && skill_num != TF_HIDING && skill_num != AS_GRIMTOOTH
-			&& skill_num != RG_BACKSTAP && skill_num != RG_RAID && skill_num != NJ_SHADOWJUMP
-			&& skill_num != NJ_KIRIKAGE)
-			return 0;
-//		if (sc->option&OPTION_CLOAK && skill_num == TF_HIDING)
-//			return 0; //Latest reports indicate Hiding is usable while Cloaking. [Skotlex]
+		if (sc->option&OPTION_HIDE)
+		switch (skill_num) { //Usable skills while hiding.
+			case TF_HIDING:
+			case AS_GRIMTOOTH:
+			case RG_BACKSTAP:
+			case RG_RAID:
+			case NJ_SHADOWJUMP:
+			case NJ_KIRIKAGE:
+				break;
+			default:
+				return 0;
+		}
 		if (sc->option&OPTION_CHASEWALK && skill_num != ST_CHASEWALK)
 			return 0;
 	}
@@ -912,9 +919,10 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
 		return 1;
 
 	tsc = status_get_sc(target);
+	
 	if(tsc && tsc->count)
 	{	
-		if (!(mode & MD_BOSS) && tsc->data[SC_TRICKDEAD].timer != -1)
+		if (!(status->mode&MD_BOSS) && tsc->data[SC_TRICKDEAD].timer != -1)
 			return 0;
 		if(skill_num == WZ_STORMGUST && tsc->data[SC_FREEZE].timer != -1)
 			return 0;
@@ -922,38 +930,44 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
 			return 0;
 	}
 
-	race = src?status_get_race(src):0; 
 	//If targetting, cloak+hide protect you, otherwise only hiding does.
 	hide_flag = flag?OPTION_HIDE:(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK);
 		
  	//You cannot hide from ground skills.
-	if(skill_get_pl(skill_num) == 2)
+	if(skill_get_pl(skill_num) == ELE_EARTH)
 		hide_flag &= ~OPTION_HIDE;
 	
 	switch (target->type)
 	{
 	case BL_PC:
 		{
-			struct map_session_data *sd = (struct map_session_data*) target;
+			struct map_session_data *sd = (TBL_PC*) target;
 			if (pc_isinvisible(sd))
 				return 0;
-			if (tsc->option&hide_flag
-				&& (sd->state.perfect_hiding || !(race == RC_INSECT || race == RC_DEMON || mode&MD_DETECTOR))
-				&& !(mode&MD_BOSS))
+			if (tsc->option&hide_flag && !(status->mode&MD_BOSS)
+				&& (sd->state.perfect_hiding || !(
+					status->race == RC_INSECT ||
+				  	status->race == RC_DEMON ||
+				  	status->mode&MD_DETECTOR
+				)))
 				return 0;
 		}
 		break;
 	case BL_ITEM:	//Allow targetting of items to pick'em up (or in the case of mobs, to loot them).
 		//TODO: Would be nice if this could be used to judge whether the player can or not pick up the item it targets. [Skotlex]
-		if (mode&MD_LOOTER)
+		if (status->mode&MD_LOOTER)
 			return 1;
 		else
 			return 0;
 	default:
 		//Check for chase-walk/hiding/cloaking opponents.
-		if (tsc && !(mode&MD_BOSS))
+		if (tsc && !(status->mode&MD_BOSS))
 		{
-			if (tsc->option&hide_flag && !(race == RC_INSECT || race == RC_DEMON || mode&MD_DETECTOR))
+			if (tsc->option&hide_flag && !(
+				status->race == RC_INSECT ||
+			  	status->race == RC_DEMON ||
+			  	status->mode&MD_DETECTOR
+			))
 				return 0;
 		}
 	}