Browse Source

- Corrected Smokie's pet script to use petskillbonus instead of "bonus"
- Added constant map_flag_gvg2 which tags gvg maps independently of whether woe is on or off.
- battle_calc_gvg_damage will be invoked in gvg maps regardless of woe time.
- NPC_MENTALBREAKER now zaps matk*lv SP based on observations by Tharis.
- md->class_ will be changed on mob-class-change to fix all class-change related bugs. On respawn, the spawn data will be used to revert to the original class.
- Improved the pet skillbonus timer for "eternal bonuses" cases where the bonus delay is 0.
- Adjusted gvg long damage rate to 80%, magic damage rate to 60%


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

skotlex 18 years ago
parent
commit
d16c9da400
12 changed files with 54 additions and 28 deletions
  1. 10 0
      Changelog-Trunk.txt
  2. 3 0
      conf-tmpl/Changelog.txt
  3. 2 2
      conf-tmpl/battle/guild.conf
  4. 2 0
      db/Changelog.txt
  5. 2 2
      db/pet_db.txt
  6. 5 5
      src/map/battle.c
  7. 2 1
      src/map/map.h
  8. 6 3
      src/map/mob.c
  9. 11 10
      src/map/pet.c
  10. 9 2
      src/map/skill.c
  11. 1 1
      src/map/status.c
  12. 1 2
      src/map/unit.c

+ 10 - 0
Changelog-Trunk.txt

@@ -3,6 +3,16 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 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.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 
+2006/09/14
+	* battle_calc_gvg_damage will be invoked in gvg maps regardless of woe
+	  time. [Skotlex]
+	* NPC_MENTALBREAKER now zaps matk*lv SP based on observations by Tharis.
+	  [Skotlex]
+	* md->class_ will be changed on mob-class-change to fix all class-change
+	  related bugs. On respawn, the spawn data will be used to revert to the
+	  original class. [Skotlex]
+	* Improved the pet skillbonus timer for "eternal bonuses" cases where the
+	  bonus delay is 0. [Skotlex]
 2006/09/13
 2006/09/13
 	* SC_CHANGE cannot override itself anymore. This fixes being able to
 	* SC_CHANGE cannot override itself anymore. This fixes being able to
 	  "recast" the skill while it's still active to lengthen the duration AND
 	  "recast" the skill while it's still active to lengthen the duration AND

+ 3 - 0
conf-tmpl/Changelog.txt

@@ -1,5 +1,8 @@
 Date	Added
 Date	Added
 
 
+2006/09/14
+	* Adjusted gvg long damage rate to 80%, magic damage rate to 60%
+	  (battle/guild.conf) [Skotlex]
 2006/09/12
 2006/09/12
 	* Changed back the default of case-sensitive to ON since it shouldn't be
 	* Changed back the default of case-sensitive to ON since it shouldn't be
 	  such a bad performance hog now. [Skotlex]
 	  such a bad performance hog now. [Skotlex]

+ 2 - 2
conf-tmpl/battle/guild.conf

@@ -43,13 +43,13 @@ castle_defense_rate: 100
 gvg_short_attack_damage_rate: 80
 gvg_short_attack_damage_rate: 80
 
 
 // Ranged damage adjustments (non skills) for WoE battles (Guild Vs Guild) (Note 2)
 // Ranged damage adjustments (non skills) for WoE battles (Guild Vs Guild) (Note 2)
-gvg_long_attack_damage_rate: 75
+gvg_long_attack_damage_rate: 80
 
 
 // Weapon skills damage adjustments for WoE battles (Guild Vs Guild) (Note 2)
 // Weapon skills damage adjustments for WoE battles (Guild Vs Guild) (Note 2)
 gvg_weapon_attack_damage_rate: 60
 gvg_weapon_attack_damage_rate: 60
 
 
 // Magic skills damage adjustments for WoE battles (Guild Vs Guild) (Note 2)
 // Magic skills damage adjustments for WoE battles (Guild Vs Guild) (Note 2)
-gvg_magic_attack_damage_rate: 50
+gvg_magic_attack_damage_rate: 60
 
 
 // Misc skills damage adjustments for WoE battles (Guild Vs Guild) (Note 2)
 // Misc skills damage adjustments for WoE battles (Guild Vs Guild) (Note 2)
 gvg_misc_attack_damage_rate: 60
 gvg_misc_attack_damage_rate: 60

+ 2 - 0
db/Changelog.txt

@@ -20,6 +20,8 @@
 
 
 =========================
 =========================
 09/14
 09/14
+	* Corrected Smokie's pet script to use petskillbonus instead of "bonus"
+	  [Skotlex]
 	* Fixed Abyss Lake drop rates [Playtester]
 	* Fixed Abyss Lake drop rates [Playtester]
 	- also updated related aegis item names
 	- also updated related aegis item names
 	* Fixed Thanatos Tower drop rates [Playtester]
 	* Fixed Thanatos Tower drop rates [Playtester]

+ 2 - 2
db/pet_db.txt

@@ -42,8 +42,8 @@
 1035,HUNTER_FLY,Hunter Fly,626,9008,10002,716,80,12,10,100,250,20,500,150,1,0,500,500,200,{ petskillattack2 187,888,2,0,10;}
 1035,HUNTER_FLY,Hunter Fly,626,9008,10002,716,80,12,10,100,250,20,500,150,1,0,500,500,200,{ petskillattack2 187,888,2,0,10;}
 1042,STEEL_CHONCHON,Steel ChonChon,625,9007,10002,1002,80,12,20,100,250,20,1000,150,1,0,500,500,200,{ petskillbonus bAgiVit,4,20,40; }
 1042,STEEL_CHONCHON,Steel ChonChon,625,9007,10002,1002,80,12,20,100,250,20,1000,150,1,0,500,500,200,{ petskillbonus bAgiVit,4,20,40; }
 1049,PICKY,Picky,623,9005,10012,507,80,15,40,100,250,20,2000,200,1,0,500,600,50,{ petskillbonus bStr,3,10,50;}
 1049,PICKY,Picky,623,9005,10012,507,80,15,40,100,250,20,2000,200,1,0,500,600,50,{ petskillbonus bStr,3,10,50;}
-1052,ROCKER,Rocker,629,9011,10014,537,80,60,30,100,250,20,1500,200,0,0,350,350,600,{ petskillbonus bAllStats,1,10,50;}
-1056,SMOKIE,Smokie,633,9015,10019,537,80,15,30,100,250,20,1000,200,1,0,600,600,100,{ bonus bPerfectHide,1; }
+1052,ROCKER,Rocker,629,9011,10014,537,80,60,30,100,250,20,1500,200,0,0,350,350,600,{ petskillbonus bAllStats,1,10,50; }
+1056,SMOKIE,Smokie,633,9015,10019,537,80,15,30,100,250,20,1000,200,1,0,600,600,100,{ petskillbonus bPerfectHide,1,3600,0; }
 1057,YOYO,Yoyo,634,9016,10018,532,80,12,20,100,250,20,1000,200,1,0,300,800,400,{ petloot 20; }
 1057,YOYO,Yoyo,634,9016,10018,532,80,12,20,100,250,20,1000,200,1,0,300,800,400,{ petloot 20; }
 1063,LUNATIC,Lunatic,622,9004,10007,534,80,15,40,100,250,20,1500,200,0,0,300,300,1000,{ petskillbonus bLuk,3,10,50; }
 1063,LUNATIC,Lunatic,622,9004,10007,534,80,15,40,100,250,20,1500,200,0,0,300,300,1000,{ petskillbonus bLuk,3,10,50; }
 1077,POISON_SPORE,Poison Spore,631,9013,10017,537,80,20,20,100,250,20,1000,200,0,0,600,200,400,{ petskillattack 176,20,0,10; }
 1077,POISON_SPORE,Poison Spore,631,9013,10017,537,80,20,20,100,250,20,1000,200,0,0,600,200,400,{ petskillattack 176,20,0,10; }

+ 5 - 5
src/map/battle.c

@@ -2011,18 +2011,18 @@ static struct Damage battle_calc_weapon_attack(
 	{	//There is a total damage value
 	{	//There is a total damage value
 		if(!wd.damage2) {
 		if(!wd.damage2) {
 			wd.damage=battle_calc_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
 			wd.damage=battle_calc_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
-			if (map_flag_gvg(target->m))
+			if (map_flag_gvg2(target->m))
 				wd.damage=battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
 				wd.damage=battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
 		} else
 		} else
 		if(!wd.damage) {
 		if(!wd.damage) {
 			wd.damage2=battle_calc_damage(src,target,wd.damage2,wd.div_,skill_num,skill_lv,wd.flag);
 			wd.damage2=battle_calc_damage(src,target,wd.damage2,wd.div_,skill_num,skill_lv,wd.flag);
-			if (map_flag_gvg(target->m))
+			if (map_flag_gvg2(target->m))
 				wd.damage2=battle_calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_num,skill_lv,wd.flag);
 				wd.damage2=battle_calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_num,skill_lv,wd.flag);
 		} else
 		} else
 		{
 		{
 			int d1=wd.damage+wd.damage2,d2=wd.damage2;
 			int d1=wd.damage+wd.damage2,d2=wd.damage2;
 			wd.damage=battle_calc_damage(src,target,d1,wd.div_,skill_num,skill_lv,wd.flag);
 			wd.damage=battle_calc_damage(src,target,d1,wd.div_,skill_num,skill_lv,wd.flag);
-			if (map_flag_gvg(target->m))
+			if (map_flag_gvg2(target->m))
 				wd.damage=battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
 				wd.damage=battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
 			wd.damage2=(d2*100/d1)*wd.damage/100;
 			wd.damage2=(d2*100/d1)*wd.damage/100;
 			if(wd.damage > 1 && wd.damage2 < 1) wd.damage2=1;
 			if(wd.damage > 1 && wd.damage2 < 1) wd.damage2=1;
@@ -2454,7 +2454,7 @@ struct Damage battle_calc_magic_attack(
 		ad.damage = ad.damage>0?1:-1;
 		ad.damage = ad.damage>0?1:-1;
 		
 		
 	ad.damage=battle_calc_damage(src,target,ad.damage,ad.div_,skill_num,skill_lv,ad.flag);
 	ad.damage=battle_calc_damage(src,target,ad.damage,ad.div_,skill_num,skill_lv,ad.flag);
-	if (map_flag_gvg(target->m))
+	if (map_flag_gvg2(target->m))
 		ad.damage=battle_calc_gvg_damage(src,target,ad.damage,ad.div_,skill_num,skill_lv,ad.flag);
 		ad.damage=battle_calc_gvg_damage(src,target,ad.damage,ad.div_,skill_num,skill_lv,ad.flag);
 	return ad;
 	return ad;
 }
 }
@@ -2713,7 +2713,7 @@ struct Damage  battle_calc_misc_attack(
 		md.damage=battle_attr_fix(src, target, md.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
 		md.damage=battle_attr_fix(src, target, md.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
 
 
 	md.damage=battle_calc_damage(src,target,md.damage,md.div_,skill_num,skill_lv,md.flag);
 	md.damage=battle_calc_damage(src,target,md.damage,md.div_,skill_num,skill_lv,md.flag);
-	if (map_flag_gvg(target->m))
+	if (map_flag_gvg2(target->m))
 		md.damage=battle_calc_gvg_damage(src,target,md.damage,md.div_,skill_num,skill_lv,md.flag);
 		md.damage=battle_calc_gvg_damage(src,target,md.damage,md.div_,skill_num,skill_lv,md.flag);
 
 
 	return md;
 	return md;

+ 2 - 1
src/map/map.h

@@ -168,7 +168,8 @@ enum {
 #define map_flag_vs(m) (map[m].flag.pvp || map[m].flag.gvg_dungeon || map[m].flag.gvg || (agit_flag && map[m].flag.gvg_castle))
 #define map_flag_vs(m) (map[m].flag.pvp || map[m].flag.gvg_dungeon || map[m].flag.gvg || (agit_flag && map[m].flag.gvg_castle))
 //Specifies maps that have special GvG/WoE restrictions
 //Specifies maps that have special GvG/WoE restrictions
 #define map_flag_gvg(m) (map[m].flag.gvg || (agit_flag && map[m].flag.gvg_castle))
 #define map_flag_gvg(m) (map[m].flag.gvg || (agit_flag && map[m].flag.gvg_castle))
-
+//Specifies if the map is tagged as GvG/WoE (regardless of agit_flag status)
+#define map_flag_gvg2(m) (map[m].flag.gvg || map[m].flag.gvg_castle)
 //Caps values to min/max
 //Caps values to min/max
 #define cap_value(a, min, max) (a>=max?max:a<=min?min:a)
 #define cap_value(a, min, max) (a>=max?max:a<=min?min:a)
 
 

+ 6 - 3
src/map/mob.c

@@ -632,11 +632,13 @@ int mob_spawn (struct mob_data *md)
 	md->last_thinktime = tick -MIN_MOBTHINKTIME;
 	md->last_thinktime = tick -MIN_MOBTHINKTIME;
 	if (md->bl.prev != NULL)
 	if (md->bl.prev != NULL)
 		unit_remove_map(&md->bl,2);
 		unit_remove_map(&md->bl,2);
-	else if (md->vd->class_ != md->class_) {
+	else
+	if (md->spawn && md->class_ != md->spawn->class_)
+	{
+		md->class_ = md->spawn->class_;
 		status_set_viewdata(&md->bl, md->class_);
 		status_set_viewdata(&md->bl, md->class_);
 		md->db = mob_db(md->class_);
 		md->db = mob_db(md->class_);
-		if (md->spawn)
-			memcpy(md->name,md->spawn->name,NAME_LENGTH);
+		memcpy(md->name,md->spawn->name,NAME_LENGTH);
 	}
 	}
 
 
 	if (md->spawn) { //Respawn data
 	if (md->spawn) { //Respawn data
@@ -2286,6 +2288,7 @@ int mob_class_change (struct mob_data *md, int class_)
 		return 0; //Clones
 		return 0; //Clones
 
 
 	hp_rate = md->status.hp*100/md->status.max_hp;
 	hp_rate = md->status.hp*100/md->status.max_hp;
+	md->class_ = class_;
 	md->db = mob_db(class_);
 	md->db = mob_db(class_);
 	if (battle_config.override_mob_names==1)
 	if (battle_config.override_mob_names==1)
 		memcpy(md->name,md->db->name,NAME_LENGTH-1);
 		memcpy(md->name,md->db->name,NAME_LENGTH-1);

+ 11 - 10
src/map/pet.c

@@ -577,12 +577,12 @@ int pet_catch_process2(struct map_session_data *sd,int target_id)
 		pc_delitem(sd,i,1,0);
 		pc_delitem(sd,i,1,0);
 	}
 	}
 
 
-	i = search_petDB_index(md->vd->class_,PET_CLASS);
+	i = search_petDB_index(md->class_,PET_CLASS);
 	//catch_target_class == 0 is used for universal lures. [Skotlex]
 	//catch_target_class == 0 is used for universal lures. [Skotlex]
 	//for now universal lures do not include bosses.
 	//for now universal lures do not include bosses.
 	if (sd->catch_target_class == 0 && !(md->status.mode&MD_BOSS))
 	if (sd->catch_target_class == 0 && !(md->status.mode&MD_BOSS))
-		sd->catch_target_class = md->vd->class_;
-	if(i < 0 || sd->catch_target_class != md->vd->class_) {
+		sd->catch_target_class = md->class_;
+	if(i < 0 || sd->catch_target_class != md->class_) {
 		clif_emotion(&md->bl, 7);	//mob will do /ag if wrong lure is used on them.
 		clif_emotion(&md->bl, 7);	//mob will do /ag if wrong lure is used on them.
 		clif_pet_rulet(sd,0);
 		clif_pet_rulet(sd,0);
 		sd->catch_target_class = -1;
 		sd->catch_target_class = -1;
@@ -1100,6 +1100,7 @@ int pet_skill_bonus_timer(int tid,unsigned int tick,int id,int data)
 {
 {
 	struct map_session_data *sd=map_id2sd(id);
 	struct map_session_data *sd=map_id2sd(id);
 	struct pet_data *pd;
 	struct pet_data *pd;
+	int bonus;
 	int timer = 0;
 	int timer = 0;
 
 
 	if(sd == NULL || sd->pd==NULL || sd->pd->bonus == NULL)
 	if(sd == NULL || sd->pd==NULL || sd->pd->bonus == NULL)
@@ -1117,23 +1118,23 @@ int pet_skill_bonus_timer(int tid,unsigned int tick,int id,int data)
 	}
 	}
 	
 	
 	// determine the time for the next timer
 	// determine the time for the next timer
-	if (pd->state.skillbonus) {
-		pd->state.skillbonus = 0;
+	if (pd->state.skillbonus && pd->bonus->delay > 0) {
+		bonus = 0;
 		timer = pd->bonus->delay*1000;	// the duration until pet bonuses will be reactivated again
 		timer = pd->bonus->delay*1000;	// the duration until pet bonuses will be reactivated again
-		if (timer <= 0) //Always active bonus
-			timer = MIN_PETTHINKTIME; 
 	} else if (pd->pet.intimate) {
 	} else if (pd->pet.intimate) {
-		pd->state.skillbonus = 1;
+		bonus = 1;
 		timer = pd->bonus->duration*1000;	// the duration for pet bonuses to be in effect
 		timer = pd->bonus->duration*1000;	// the duration for pet bonuses to be in effect
 	} else { //Lost pet...
 	} else { //Lost pet...
 		pd->bonus->timer = -1;
 		pd->bonus->timer = -1;
 		return 0;
 		return 0;
 	}
 	}
 
 
-	status_calc_pc(sd, 0);
+	if (pd->state.skillbonus != bonus) {
+		pd->state.skillbonus = bonus;
+		status_calc_pc(sd, 0);
+	}
 	// wait for the next timer
 	// wait for the next timer
 	pd->bonus->timer=add_timer(tick+timer,pet_skill_bonus_timer,sd->bl.id,0);
 	pd->bonus->timer=add_timer(tick+timer,pet_skill_bonus_timer,sd->bl.id,0);
-	
 	return 0;
 	return 0;
 }
 }
 
 

+ 9 - 2
src/map/skill.c

@@ -1234,9 +1234,16 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 		sc_start(bl,SkillStatusChangeTable(skillid),50+10*skilllv,skilllv,src->type==BL_PET?skilllv*1000:skill_get_time2(skillid,skilllv));
 		sc_start(bl,SkillStatusChangeTable(skillid),50+10*skilllv,skilllv,src->type==BL_PET?skilllv*1000:skill_get_time2(skillid,skilllv));
 		break;
 		break;
 
 
-	case NPC_MENTALBREAKER:
-		status_percent_damage(src, bl, 0, -(10+skilllv));
+	case NPC_MENTALBREAKER: 
+	{	//Based on observations by Tharis, Mental Breaker should do SP damage
+	  	//equal to Matk*skLevel.
+		rate = sstatus->matk_min;
+		if (rate < sstatus->matk_max)
+			rate += rand()%(sstatus->matk_max - sstatus->matk_min);
+		rate*=skilllv;
+		status_zap(bl, 0, rate);
 		break;
 		break;
+	}
 	// Equipment breaking monster skills [Celest]
 	// Equipment breaking monster skills [Celest]
 	case NPC_BREAKWEAPON:
 	case NPC_BREAKWEAPON:
 		skill_break_equip(bl, EQP_WEAPON, 150*skilllv, BCT_ENEMY);
 		skill_break_equip(bl, EQP_WEAPON, 150*skilllv, BCT_ENEMY);

+ 1 - 1
src/map/status.c

@@ -6143,7 +6143,7 @@ int status_change_end( struct block_list* bl , int type,int tid )
 		case SC_CHANGE:
 		case SC_CHANGE:
 			if (tid == -1)
 			if (tid == -1)
 		 		break;
 		 		break;
-			// "lose almost all her HP and SP" on natural expiration.
+			// "lose almost all their HP and SP" on natural expiration.
 			status_set_hp(bl, 10, 0);
 			status_set_hp(bl, 10, 0);
 			status_set_sp(bl, 10, 0);
 			status_set_sp(bl, 10, 0);
 			break;
 			break;

+ 1 - 2
src/map/unit.c

@@ -169,8 +169,7 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data)
 			sd->areanpc_id=0;
 			sd->areanpc_id=0;
 		if (sd->state.gmaster_flag &&
 		if (sd->state.gmaster_flag &&
 			(battle_config.guild_aura&(agit_flag?2:1)) &&
 			(battle_config.guild_aura&(agit_flag?2:1)) &&
-			(battle_config.guild_aura&
-				(map[bl->m].flag.gvg || map[bl->m].flag.gvg_castle?8:4))
+			(battle_config.guild_aura&(map_flag_gvg2(bl->m)?8:4))
 		)
 		)
 		{ //Guild Aura: Likely needs to be recoded, this method seems inefficient.
 		{ //Guild Aura: Likely needs to be recoded, this method seems inefficient.
 			struct guild *g = sd->state.gmaster_flag;
 			struct guild *g = sd->state.gmaster_flag;