Prechádzať zdrojové kódy

- Integrated the SG related info of hate_mob and feel_map into a single structure (sg_info).
- Modified skill_blown and skill_attack so that reflected spells do not cause knockback.
- SG Blessing skills now grant the extra experience to everyone when the SG killed the mob.


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

skotlex 17 rokov pred
rodič
commit
eee82904e7
7 zmenil súbory, kde vykonal 61 pridanie a 60 odobranie
  1. 4 0
      Changelog-Trunk.txt
  2. 6 12
      src/map/battle.c
  3. 1 2
      src/map/clif.c
  4. 17 10
      src/map/mob.c
  5. 11 22
      src/map/pc.c
  6. 10 0
      src/map/pc.h
  7. 12 14
      src/map/skill.c

+ 4 - 0
Changelog-Trunk.txt

@@ -3,6 +3,10 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
+2007/11/29
+	* Reflected spells no longer cause knockback. 
+	* SG Blessing skills now grant the extra experience to everyone when the SG
+	  killed the mob.
 2007/11/28
 	* Applied the required changes to handle def as a signed char (allows for
 	  negative def)

+ 6 - 12
src/map/battle.c

@@ -1760,19 +1760,13 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 			if (flag.lh)
 				wd.damage2 = battle_addmastery(sd,target,wd.damage2,1);
 
-			if((skill=pc_checkskill(sd,SG_STAR_ANGER)) >0 && (t_class == sd->hate_mob[2] ||
-				(sc && sc->data[SC_MIRACLE])))
+			if (sc && sc->data[SC_MIRACLE]) i = 2; //Star anger
+			else
+			ARR_FIND(0, 3, i, t_class == sd->hate_mob[i] && (skill=pc_checkskill(sd,sg_info[i].anger_id)));
+			if (i < 3) 
 			{
-				skillratio = sd->status.base_level + sstatus->str + sstatus->dex + sstatus->luk;
-				if (skill<4)
-					skillratio /= 12-3*skill;
-				ATK_ADDRATE(skillratio);
-			} else
-			if(
-				((skill=pc_checkskill(sd,SG_SUN_ANGER)) >0 && t_class == sd->hate_mob[0]) ||
-				((skill=pc_checkskill(sd,SG_MOON_ANGER)) >0 && t_class == sd->hate_mob[1])
-			) {
-				skillratio = sd->status.base_level + sstatus->dex+ sstatus->luk;
+				skillratio = sd->status.base_level + sstatus->dex + sstatus->luk;
+				if (i == 2) skillratio += sstatus->str; //Star Anger
 				if (skill<4)
 					skillratio /= 12-3*skill;
 				ATK_ADDRATE(skillratio);

+ 1 - 2
src/map/clif.c

@@ -10995,7 +10995,6 @@ void clif_parse_RankingPk(int fd,struct map_session_data *sd)
  *------------------------------------------*/
 void clif_parse_FeelSaveOk(int fd,struct map_session_data *sd)
 {
-	char feel_var[3][NAME_LENGTH] = {"PC_FEEL_SUN","PC_FEEL_MOON","PC_FEEL_STAR"};
 	int i;
 	if (sd->menuskill_id != SG_FEEL)
 		return;
@@ -11004,7 +11003,7 @@ void clif_parse_FeelSaveOk(int fd,struct map_session_data *sd)
 
 	sd->feel_map[i].index = map_id2index(sd->bl.m);
 	sd->feel_map[i].m = sd->bl.m;
-	pc_setglobalreg(sd,feel_var[i],sd->feel_map[i].index);
+	pc_setglobalreg(sd,sg_info[i].feel_var,sd->feel_map[i].index);
 
 //Are these really needed? Shouldn't they show up automatically from the feel save packet?
 //	clif_misceffect2(&sd->bl, 0x1b0);

+ 17 - 10
src/map/mob.c

@@ -1866,13 +1866,27 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 		(!md->master_id || !md->special_state.ai) && //Only player-summoned mobs do not give exp. [Skotlex]
 		(!map[m].flag.nobaseexp || !map[m].flag.nojobexp) //Gives Exp
 	) { //Experience calculation.
-
+		int bonus = 100; //Bonus on top of your share (common to all attackers).
+		if (md->sc.data[SC_RICHMANKIM])
+			bonus += md->sc.data[SC_RICHMANKIM]->val2;
+		if(sd) {
+			temp = status_get_class(&md->bl);
+			ARR_FIND(0, 3, i, temp == sd->hate_mob[i]);
+			if (i < 3 && (
+				battle_config.allow_skill_without_day ||
+				sg_info[i].day_func() ||
+				(i==2 && sd->sc.data[SC_MIRACLE]) //Miracle only applies to Star target
+			))
+				bonus += (i==2?20:10)*pc_checkskill(sd,sg_info[i].bless_id);
+
+			if(battle_config.mobs_level_up && md->level > md->db->lv) // [Valaris]
+				bonus += (md->level-md->db->lv)*battle_config.mobs_level_up_exp_rate;
+		}
 	for(i = 0; i < DAMAGELOG_SIZE && md->dmglog[i].id; i++)
 	{
 		int flag=1,zeny=0;
 		unsigned int base_exp, job_exp;
 		double per; //Your share of the mob's exp
-		int bonus; //Bonus on top of your share.
 
 		if (!tmpsd[i]) continue;
 
@@ -1897,15 +1911,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 			per /=2.;
 		else if(md->special_state.size==2)
 			per *=2.;
-
-		bonus = 100;
 		
-		if (md->sc.data[SC_RICHMANKIM])
-			bonus += md->sc.data[SC_RICHMANKIM]->val2;
-
-		if(battle_config.mobs_level_up && md->level > md->db->lv) // [Valaris]
-			bonus += (md->level-md->db->lv)*battle_config.mobs_level_up_exp_rate;
-
+	
 		if(battle_config.zeny_from_mobs && md->level) {
 			 // zeny calculation moblv + random moblv [Valaris]
 			zeny=(int) ((md->level+rand()%md->level)*per*bonus/100.);

+ 11 - 22
src/map/pc.c

@@ -64,8 +64,12 @@ static int GM_num = 0;
 #define MOTD_LINE_SIZE 128
 char motd_text[MOTD_LINE_SIZE][256]; // Message of the day buffer [Valaris]
 
-static const char feel_var[3][NAME_LENGTH] = {"PC_FEEL_SUN","PC_FEEL_MOON","PC_FEEL_STAR"};
-static const char hate_var[3][NAME_LENGTH] = {"PC_HATE_MOB_SUN","PC_HATE_MOB_MOON","PC_HATE_MOB_STAR"};
+//Links related info to the sd->hate_mob[]/sd->feel_map[] entries
+const struct sg_data sg_info[3] = {
+		{ SG_SUN_ANGER, SG_SUN_BLESS, SG_SUN_COMFORT, "PC_FEEL_SUN", "PC_HATE_MOB_SUN", is_day_of_sun },
+		{ SG_MOON_ANGER, SG_MOON_BLESS, SG_MOON_COMFORT, "PC_FEEL_MOON", "PC_HATE_MOB_MOON", is_day_of_moon },
+		{ SG_STAR_ANGER, SG_STAR_BLESS, SG_STAR_COMFORT, "PC_FEEL_STAR", "PC_HATE_MOB_STAR", is_day_of_star }
+	};
 
 //Converts a class to its array index for CLASS_COUNT defined arrays.
 //Note that it does not do a validity check for speed purposes, where parsing
@@ -817,7 +821,7 @@ int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl)
 			return 0; //Wrong size
 	}
 	sd->hate_mob[pos] = class_;
-	pc_setglobalreg(sd,hate_var[pos],class_+1);
+	pc_setglobalreg(sd,sg_info[pos].hate_var,class_+1);
 	clif_hate_info(sd, pos, class_, 1);
 	return 1;
 }
@@ -842,14 +846,14 @@ int pc_reg_received(struct map_session_data *sd)
 	//SG map and mob read [Komurka]
 	for(i=0;i<3;i++) //for now - someone need to make reading from txt/sql
 	{
-		if ((j = pc_readglobalreg(sd,feel_var[i]))!=0) {
+		if ((j = pc_readglobalreg(sd,sg_info[i].feel_var))!=0) {
 			sd->feel_map[i].index = j;
 			sd->feel_map[i].m = map_mapindex2mapid(j);
 		} else {
 			sd->feel_map[i].index = 0;
 			sd->feel_map[i].m = -1;
 		}
-		sd->hate_mob[i] = pc_readglobalreg(sd,hate_var[i])-1;
+		sd->hate_mob[i] = pc_readglobalreg(sd,sg_info[i].hate_var)-1;
 	}
 
 	if ((i = pc_checkskill(sd,RG_PLAGIARISM)) > 0) {
@@ -4190,26 +4194,11 @@ static void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsi
 {
 	int bonus = 0;
 	struct status_data *status = status_get_status_data(src);
-	unsigned int temp;
 
 	if (sd->expaddrace[status->race])
 		bonus += sd->expaddrace[status->race];	
 	bonus += sd->expaddrace[status->mode&MD_BOSS?RC_BOSS:RC_NONBOSS];
 	
-	//SG additional exp from Blessings [Komurka] - probably can be optimalized ^^;;
-	temp = status_get_class(src);
-	if(temp == sd->hate_mob[2] &&
-		(battle_config.allow_skill_without_day || is_day_of_star() || sd->sc.data[SC_MIRACLE]))
-		bonus += 20*pc_checkskill(sd,SG_STAR_BLESS);
-	else
-	if(temp == sd->hate_mob[1] &&
-		(battle_config.allow_skill_without_day || is_day_of_moon()))
-		bonus += 10*pc_checkskill(sd,SG_MOON_BLESS);
-	else
-	if(temp == sd->hate_mob[0] &&
-		(battle_config.allow_skill_without_day || is_day_of_sun()))
-		bonus += 10*pc_checkskill(sd,SG_SUN_BLESS);
-
 	if (battle_config.pk_mode && 
 		(int)(status_get_lv(src) - sd->status.base_level) >= 20)
 		bonus += 15; // pk_mode additional exp if monster >20 levels [Valaris]	
@@ -4847,7 +4836,7 @@ int pc_resetfeel(struct map_session_data* sd)
 	{
 		sd->feel_map[i].m = -1;
 		sd->feel_map[i].index = 0;
-		pc_setglobalreg(sd,feel_var[i],0);
+		pc_setglobalreg(sd,sg_info[i].feel_var,0);
 	}
 
 	return 0;
@@ -4861,7 +4850,7 @@ int pc_resethate(struct map_session_data* sd)
 	for (i=0; i<3; i++)
 	{
 		sd->hate_mob[i] = -1;
-		pc_setglobalreg(sd,hate_var[i],0);
+		pc_setglobalreg(sd,sg_info[i].hate_var,0);
 	}
 	return 0;
 }

+ 10 - 0
src/map/pc.h

@@ -304,6 +304,16 @@ struct skill_tree_entry {
 }; // Celest
 extern struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE];
 
+struct sg_data {
+	short anger_id;
+	short bless_id;
+	short comfort_id;
+	char feel_var[NAME_LENGTH];
+	char hate_var[NAME_LENGTH];
+	int (*day_func)(void);
+};
+extern const struct sg_data sg_info[3];
+
 int pc_read_gm_account(int fd);
 void pc_setinvincibletimer(struct map_session_data* sd, int val);
 void pc_delinvincibletimer(struct map_session_data* sd);

+ 12 - 14
src/map/skill.c

@@ -1223,7 +1223,7 @@ int skill_blown(struct block_list* src, struct block_list* target, int count, in
 
 	nullpo_retr(0, src);
 
-	if (map_flag_gvg(target->m))
+	if (src != target && map_flag_gvg(target->m))
 		return 0; //No knocking back in WoE
 	if (count == 0)
 		return 0; //Actual knockback distance is 0.
@@ -1632,7 +1632,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 	}
 
 	//Only knockback if it's still alive, otherwise a "ghost" is left behind. [Skotlex]
-	if (dmg.blewcount > 0 && !status_isdead(bl))
+	//Reflected spells do not bounce back (bl == dsrc since it only happens for direct skills)
+	if (dmg.blewcount > 0 && bl!=dsrc && !status_isdead(bl))
 	{
 		int direction = -1; // default
 		switch(skillid)
@@ -7880,28 +7881,25 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
 			return 0;
 		}
 		break;
-	//SHOULD BE OPTIMALIZED [Komurka]
-	//Optimized #1. optimize comfort later. [Vicious]
 	case SG_SUN_WARM:
 	case SG_MOON_WARM:
 	case SG_STAR_WARM:
-		if ((sd->bl.m == sd->feel_map[skill-SG_SUN_WARM].m) || (sc && sc->data[SC_MIRACLE]))
+		if (sc && sc->data[SC_MIRACLE])
+			break;
+		i = skill-SG_SUN_WARM;
+		if (sd->bl.m == sd->feel_map[i].m)
 			break;
 		clif_skill_fail(sd,skill,0,0);
 		return 0;
 		break;
 	case SG_SUN_COMFORT:
-		if ((sd->bl.m == sd->feel_map[0].m && (battle_config.allow_skill_without_day || is_day_of_sun())) || (sc && sc->data[SC_MIRACLE]))
-			break;
-		clif_skill_fail(sd,skill,0,0);
-		return 0;
 	case SG_MOON_COMFORT:
-		if ((sd->bl.m == sd->feel_map[1].m && (battle_config.allow_skill_without_day || is_day_of_moon())) || (sc && sc->data[SC_MIRACLE]))
-			break;
-		clif_skill_fail(sd,skill,0,0);
-		return 0;
 	case SG_STAR_COMFORT:
-		if ((sd->bl.m == sd->feel_map[2].m && (battle_config.allow_skill_without_day || is_day_of_star())) || (sc && sc->data[SC_MIRACLE]))
+		if (sc && sc->data[SC_MIRACLE])
+			break;
+		i = skill-SG_SUN_COMFORT;
+		if (sd->bl.m == sd->feel_map[i].m &&
+			(battle_config.allow_skill_without_day || sg_info[i].day_func()))
 			break;
 		clif_skill_fail(sd,skill,0,0);
 		return 0;