From d16c9da4005cee9bc600480484b82801d2a996ba Mon Sep 17 00:00:00 2001
From: skotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>
Date: Thu, 14 Sep 2006 13:46:14 +0000
Subject: [PATCH] - 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
---
 Changelog-Trunk.txt         | 10 ++++++++++
 conf-tmpl/Changelog.txt     |  3 +++
 conf-tmpl/battle/guild.conf |  4 ++--
 db/Changelog.txt            |  2 ++
 db/pet_db.txt               |  4 ++--
 src/map/battle.c            | 10 +++++-----
 src/map/map.h               |  3 ++-
 src/map/mob.c               |  9 ++++++---
 src/map/pet.c               | 21 +++++++++++----------
 src/map/skill.c             | 11 +++++++++--
 src/map/status.c            |  2 +-
 src/map/unit.c              |  3 +--
 12 files changed, 54 insertions(+), 28 deletions(-)

diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 4dc2ab49a4..388cdc93cd 100644
--- a/Changelog-Trunk.txt
+++ b/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.
 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
 	* SC_CHANGE cannot override itself anymore. This fixes being able to
 	  "recast" the skill while it's still active to lengthen the duration AND
diff --git a/conf-tmpl/Changelog.txt b/conf-tmpl/Changelog.txt
index 4499d63cbc..959abfdc5d 100644
--- a/conf-tmpl/Changelog.txt
+++ b/conf-tmpl/Changelog.txt
@@ -1,5 +1,8 @@
 Date	Added
 
+2006/09/14
+	* Adjusted gvg long damage rate to 80%, magic damage rate to 60%
+	  (battle/guild.conf) [Skotlex]
 2006/09/12
 	* Changed back the default of case-sensitive to ON since it shouldn't be
 	  such a bad performance hog now. [Skotlex]
diff --git a/conf-tmpl/battle/guild.conf b/conf-tmpl/battle/guild.conf
index b5bb29ab94..0d2e5d079a 100644
--- a/conf-tmpl/battle/guild.conf
+++ b/conf-tmpl/battle/guild.conf
@@ -43,13 +43,13 @@ castle_defense_rate: 100
 gvg_short_attack_damage_rate: 80
 
 // 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)
 gvg_weapon_attack_damage_rate: 60
 
 // 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)
 gvg_misc_attack_damage_rate: 60
diff --git a/db/Changelog.txt b/db/Changelog.txt
index 895854a73a..4cf5ee2b71 100644
--- a/db/Changelog.txt
+++ b/db/Changelog.txt
@@ -20,6 +20,8 @@
 
 =========================
 09/14
+	* Corrected Smokie's pet script to use petskillbonus instead of "bonus"
+	  [Skotlex]
 	* Fixed Abyss Lake drop rates [Playtester]
 	- also updated related aegis item names
 	* Fixed Thanatos Tower drop rates [Playtester]
diff --git a/db/pet_db.txt b/db/pet_db.txt
index a4be8041c4..79625ce701 100644
--- a/db/pet_db.txt
+++ b/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;}
 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;}
-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; }
 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; }
diff --git a/src/map/battle.c b/src/map/battle.c
index 6ee40df355..246d3fae4b 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -2011,18 +2011,18 @@ static struct Damage battle_calc_weapon_attack(
 	{	//There is a total damage value
 		if(!wd.damage2) {
 			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);
 		} else
 		if(!wd.damage) {
 			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);
 		} else
 		{
 			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);
-			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.damage2=(d2*100/d1)*wd.damage/100;
 			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=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);
 	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_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);
 
 	return md;
diff --git a/src/map/map.h b/src/map/map.h
index b0b114f99a..d855f2d538 100644
--- a/src/map/map.h
+++ b/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))
 //Specifies maps that have special GvG/WoE restrictions
 #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
 #define cap_value(a, min, max) (a>=max?max:a<=min?min:a)
 
diff --git a/src/map/mob.c b/src/map/mob.c
index ca12ba0eb9..6742c204a1 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -632,11 +632,13 @@ int mob_spawn (struct mob_data *md)
 	md->last_thinktime = tick -MIN_MOBTHINKTIME;
 	if (md->bl.prev != NULL)
 		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_);
 		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
@@ -2286,6 +2288,7 @@ int mob_class_change (struct mob_data *md, int class_)
 		return 0; //Clones
 
 	hp_rate = md->status.hp*100/md->status.max_hp;
+	md->class_ = class_;
 	md->db = mob_db(class_);
 	if (battle_config.override_mob_names==1)
 		memcpy(md->name,md->db->name,NAME_LENGTH-1);
diff --git a/src/map/pet.c b/src/map/pet.c
index 9b5f6a3a3a..d4069513f4 100644
--- a/src/map/pet.c
+++ b/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);
 	}
 
-	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]
 	//for now universal lures do not include bosses.
 	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_pet_rulet(sd,0);
 		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 pet_data *pd;
+	int bonus;
 	int timer = 0;
 
 	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
-	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
-		if (timer <= 0) //Always active bonus
-			timer = MIN_PETTHINKTIME; 
 	} 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
 	} else { //Lost pet...
 		pd->bonus->timer = -1;
 		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
 	pd->bonus->timer=add_timer(tick+timer,pet_skill_bonus_timer,sd->bl.id,0);
-	
 	return 0;
 }
 
diff --git a/src/map/skill.c b/src/map/skill.c
index 83954c9a28..5842cdc311 100644
--- a/src/map/skill.c
+++ b/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));
 		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;
+	}
 	// Equipment breaking monster skills [Celest]
 	case NPC_BREAKWEAPON:
 		skill_break_equip(bl, EQP_WEAPON, 150*skilllv, BCT_ENEMY);
diff --git a/src/map/status.c b/src/map/status.c
index fb39d8e2bb..ccff0a457a 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -6143,7 +6143,7 @@ int status_change_end( struct block_list* bl , int type,int tid )
 		case SC_CHANGE:
 			if (tid == -1)
 		 		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_sp(bl, 10, 0);
 			break;
diff --git a/src/map/unit.c b/src/map/unit.c
index 396eeca457..2bc274d109 100644
--- a/src/map/unit.c
+++ b/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;
 		if (sd->state.gmaster_flag &&
 			(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.
 			struct guild *g = sd->state.gmaster_flag;