Explorar o código

* Added skill requirements for the new guild skills
* Allow Emergency Recall to be cast in guild castles
* Add 'minimum job level required' for skill_tree reading
- Berserk now requires job level 50
* Added Spring Trap to be able to trigger ankle snare traps that aren't activated yet
* Added a fix in guild.c by Mellowz
* Some rewrites on the pet skill bonuses system
* Check whether a monster is still alive before starting a status change

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

celest %!s(int64=20) %!d(string=hai) anos
pai
achega
509039ac6b
Modificáronse 14 ficheiros con 176 adicións e 145 borrados
  1. 14 0
      Changelog-SVN.txt
  2. 3 1
      Dev/bugs.txt
  3. 5 5
      db/skill_tree.txt
  4. 41 29
      src/map/clif.c
  5. 6 4
      src/map/guild.c
  6. 3 1
      src/map/map.h
  7. 26 36
      src/map/pc.c
  8. 1 0
      src/map/pc.h
  9. 32 57
      src/map/pet.c
  10. 0 2
      src/map/pet.h
  11. 10 3
      src/map/script.c
  12. 14 4
      src/map/skill.c
  13. 19 3
      src/map/status.c
  14. 2 0
      src/map/status.h

+ 14 - 0
Changelog-SVN.txt

@@ -1,5 +1,19 @@
 Date	Added
 
+02/20
+        * Added skill requirements for the new guild skills [celest]
+        * Allow Emergency Recall to be cast in guild castles even if nowarp and
+          nowarpto mapflags are enabled [celest]
+        * Add 'minimum job level required' for skill_tree reading [celest]
+          - Berserk now requires job level 50
+        * Added Spring Trap to be able to trigger ankle snare traps that aren't
+          activated yet [celest]
+        * Added a fix in guild.c by Mellowz [celest]
+        * Some rewrites on the pet skill bonuses system -- also fixes pet bonuses
+          not effecting stats as they should [celest]
+        * Check whether a monster is still alive before starting a status change
+          -- also fixes the status_change_timer nullpo errors with grimtooth [celest]
+
 02/19
         * Added bSubSize, bHPGainValue, and bDamageWhenUnequip [celest]
         * Updated bSPDrainValue/Rate to accept a 'type' [celest]

+ 3 - 1
Dev/bugs.txt

@@ -265,7 +265,9 @@ Progress:	0%
 Problem:	'Adrenaline Rush' has to work with any weapon again (for whole party)
 		according to the kRO Sak patch on 21/12
 Assigned:	N/A
-Progress:	0%
+Progress:	N/A
+Notes:          "Fixed Adrenaline Rush skill working for all weapon types again."
+                I think it was supposed to not work with all weapons ^^;
 
 Problem:	[Urgent!] Server doesn't save Variables (#global and global)
 		If you exit the client with Alt-F4 or lose connection to the server.

+ 5 - 5
db/skill_tree.txt

@@ -598,10 +598,10 @@
 23,52,10,0,0,0,0,0,0,0,0,0,0//TF_POISON		#インベナム#
 23,53,1,52,3,0,0,0,0,0,0,0,0//TF_DETOXIFY	#解毒#
 //Wedding Class
-22,1,9,0,0,0,0,0,0,0,0,0,0,0,0//NV_BASIC		#基-{スキル#
-22.334,1,0,0,0,0,0,0,0,0,0,0,0
-22,335,5,0,0,0,0,0,0,0,0,0,0,0//
-22,336,5,0,0,0,0,0,0,0,0,0,0,0//
+22,1,9,0,0,0,0,0,0,0,0,0,0//NV_BASIC		#基-{スキル#
+22,334,1,0,0,0,0,0,0,0,0,0,0
+22,335,5,0,0,0,0,0,0,0,0,0,0//
+22,336,5,0,0,0,0,0,0,0,0,0,0//
 // JobNo,Skill-ID,MaxLV,前提Skill-ID-1,前提Skill-ID-1-Lv,計5個まで繰り返し
 //Novice High
 4001,1,9,0,0,0,0,0,0,0,0,0,0//NV_BASIC		#基本スキル#
@@ -719,7 +719,7 @@
 4008,356,10,3,10,6,5,60,3,0,0,0,0//LK_PARRYING
 4008,357,5,4,1,55,5,63,1,0,0,0,0//LK_CONCENTRATE
 4008,358,1,4,10,6,5,8,3,0,0,0,0//LK_TENSIONRELAX
-4008,359,1,55,7,56,5,57,5,58,2,63,1//LK_BERSERK
+4008,359,1,50,55,7,56,5,57,5,58,2,63,1//LK_BERSERK
 4008,398,5,55,9,63,1,0,0,0,0,0,0//LK_HEADCRUSH
 4008,399,10,55,9,64,3,398,3,0,0,0,0//LK_JOINTBEAT#ジョイントビート#
 //High Priest

+ 41 - 29
src/map/clif.c

@@ -6680,35 +6680,47 @@ int clif_guild_skillinfo(struct map_session_data *sd)
 			memset(WFIFOP(fd,c*37+18),0,24);
 			if(g->skill[i].lv < guild_skill_get_max(id)) {
 				//Kafra and Guardian changed to require Approval [Sara]
-				if (g->skill[i].id == GD_KAFRACONTACT && guild_checkskill(g,GD_APPROVAL) <= 0)
-					up = 0;
-				else if (g->skill[i].id == GD_GUARDIANRESEARCH && guild_checkskill(g,GD_APPROVAL) <= 0)
-					up = 0;
-				//Glory skill requirements -- Pretty sure correct [Sara]
-				else if (g->skill[i].id == GD_LEADERSHIP && guild_checkskill(g,GD_GLORYGUILD) <= 0)
-					up = 0;
-				else if (g->skill[i].id == GD_GLORYWOUNDS && guild_checkskill(g,GD_GLORYGUILD) <= 0)
-					up = 0;
-				else if (g->skill[i].id == GD_SOULCOLD && guild_checkskill(g,GD_GLORYWOUNDS) <= 0)
-					up = 0;
-				else if (g->skill[i].id == GD_HAWKEYES && guild_checkskill(g,GD_LEADERSHIP) <= 0)
-					up = 0;
-				//Activated skill requirements -- Just guesses [Sara]
-				else if (g->skill[i].id == GD_BATTLEORDER && guild_checkskill(g,GD_APPROVAL) <= 0)
-					up = 0;
-				else if (g->skill[i].id == GD_REGENERATION && guild_checkskill(g,GD_APPROVAL) <= 0)
-					up = 0;
-				else if (g->skill[i].id == GD_RESTORE && guild_checkskill(g,GD_REGENERATION) <= 0)
-					up = 0;
-				else if (g->skill[i].id == GD_EMERGENCYCALL && guild_checkskill(g,GD_APPROVAL) <= 0)
-					up = 0;
-				if (g->skill[i].id == GD_GUARDUP && guild_checkskill(g,GD_GUARDIANRESEARCH) <= 0)
-					up = 0;
-				//Unadded yet? Has extension description in kRO tables
-				else if (g->skill[i].id == GD_DEVELOPMENT)
-					up = 0;
-				else
-					up = 1;
+				switch (g->skill[i].id)
+				{
+					case GD_KAFRACONTACT:
+					case GD_GUARDIANRESEARCH:
+					case GD_GUARDUP:
+						up = guild_checkskill(g,GD_APPROVAL) > 0;
+						break;
+					case GD_LEADERSHIP:
+						//Glory skill requirements -- Pretty sure correct [Sara]
+						up = guild_checkskill(g,GD_GLORYGUILD) > 0;
+						break;
+					case GD_GLORYWOUNDS:
+						up = guild_checkskill(g,GD_GLORYGUILD) > 0;
+						break;
+					case GD_SOULCOLD:
+						up = guild_checkskill(g,GD_GLORYWOUNDS) > 0;
+						break;
+					case GD_HAWKEYES:
+						up = guild_checkskill(g,GD_LEADERSHIP) > 0;
+						break;
+					case GD_BATTLEORDER:
+						up = guild_checkskill(g,GD_APPROVAL) > 0 &&
+							guild_checkskill(g,GD_EXTENSION) >= 2;
+						break;
+					case GD_REGENERATION:
+						up = guild_checkskill(g,GD_EXTENSION) >= 5 &&
+							guild_checkskill(g,GD_BATTLEORDER) > 0;
+						break;
+					case GD_RESTORE:
+						up = guild_checkskill(g,GD_REGENERATION) >= 2;
+						break;
+					case GD_EMERGENCYCALL:
+						up = guild_checkskill(g,GD_GUARDIANRESEARCH) > 0 &&
+							guild_checkskill(g,GD_REGENERATION) > 0;
+						break;
+					case GD_DEVELOPMENT:
+						up = 0;
+						break;
+					default:
+						up = 1;
+				}
 			}
 			else {
 				up = 0;

+ 6 - 4
src/map/guild.c

@@ -696,10 +696,12 @@ int guild_member_leaved(int guild_id,int account_id,int char_id,int flag,
 				g->member[i].sd=NULL;
 			}
 	}
-	if(sd!=NULL && sd->status.guild_id==guild_id){
-		sd->status.guild_id=0;
-		sd->guild_emblem_id=0;
-		sd->guild_sended=0;
+	if(sd!=NULL) {
+		if (sd->status.guild_id==guild_id){
+			sd->status.guild_id=0;
+			sd->guild_emblem_id=0;
+			sd->guild_sended=0;
+		}
 	}
 
 	// メンバーリストを全員に再通知

+ 3 - 1
src/map/map.h

@@ -485,6 +485,7 @@ struct pet_data {
 		unsigned state : 8 ;
 		unsigned skillstate : 8 ;
 		unsigned change_walk_target : 1 ;
+		short skillbonus;
 	} state;
 	int timer;
 	short to_x,to_y;
@@ -495,7 +496,8 @@ struct pet_data {
 	int move_fail_count;
 	unsigned int attackabletime,next_walktime,last_thinktime;
 	int skilltype,skillval,skilltimer,skillduration; // [Valaris]
-	int skillbonustype,skillbonusval,skillbonustimer,skillbonusduration; // [Valaris]
+	//int skillbonustype,skillbonusval,skillbonustimer,skillbonusduration; // [Valaris]
+	int skillbonustype,skillbonusval,skillbonustimer;
 	struct item *lootitem;
 	short loot; // [Valaris]
 	short lootmax; // [Valaris]

+ 26 - 36
src/map/pc.c

@@ -747,7 +747,7 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars
 
 	// スキルユニット?係の初期化
 	memset(sd->skillunit, 0, sizeof(sd->skillunit));
-	memset(sd->skillunittick, 0, sizeof(sd->skillunittick));
+	memset(sd->skillunittick, 0, sizeof(sd->skillunittick));	
 
 	// パ?ティ??係の初期化
 	sd->party_sended = 0;
@@ -989,23 +989,25 @@ int pc_calc_skilltree(struct map_session_data *sd)
                 for(i=0;(id=skill_tree[s][c][i].id)>0;i++){
                     int j,f=1;
                     if(!battle_config.skillfree) {
-                        for(j=0;j<5;j++) {
-                            if( skill_tree[s][c][i].need[j].id &&
-                                pc_checkskill(sd,skill_tree[s][c][i].need[j].id) <
-                                skill_tree[s][c][i].need[j].lv) {
-                                f=0;
+						for(j=0;j<5;j++) {
+							if( skill_tree[s][c][i].need[j].id &&
+								pc_checkskill(sd,skill_tree[s][c][i].need[j].id) <
+								skill_tree[s][c][i].need[j].lv) {
+								f=0;
 								break;
 							}
-                        }
-						if (id >= 2 && id <= 53 && pc_checkskill(sd, NV_BASIC) < 9)
+						}
+						if (sd->status.job_level < skill_tree[s][c][i].joblv)
 							f=0;
-                    }
-                    if(f && sd->status.skill[id].id==0 ){
-                        sd->status.skill[id].id=id;
-                        flag=1;
-                    }
-                }
-            } while(flag);
+						if (id >= 2 && id <= 53 && pc_checkskill(sd, NV_BASIC) < 9)
+							f=0;						
+					}
+					if(f && sd->status.skill[id].id==0 ){
+						sd->status.skill[id].id=id;
+						flag=1;
+					}
+				}
+			} while(flag);
 	}
 //	if(battle_config.etc_log)
 //		printf("calc skill_tree\n");
@@ -1493,20 +1495,12 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
 			sd->parame[SP_INT-SP_STR]+=val;
 			sd->parame[SP_DEX-SP_STR]+=val;
 			sd->parame[SP_LUK-SP_STR]+=val;
-			clif_updatestatus(sd,13);
-			clif_updatestatus(sd,14);
-			clif_updatestatus(sd,15);
-			clif_updatestatus(sd,16);
-			clif_updatestatus(sd,17);
-			clif_updatestatus(sd,18);
 		}
 		break;
 	case SP_AGI_VIT:	// [Valaris]
 		if(sd->state.lr_flag!=2) {
 			sd->parame[SP_AGI-SP_STR]+=val;
 			sd->parame[SP_VIT-SP_STR]+=val;
-			clif_updatestatus(sd,14);
-			clif_updatestatus(sd,15);
 		}
 		break;
 	case SP_AGI_DEX_STR:	// [Valaris]
@@ -1514,9 +1508,6 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
 			sd->parame[SP_AGI-SP_STR]+=val;
 			sd->parame[SP_DEX-SP_STR]+=val;
 			sd->parame[SP_STR-SP_STR]+=val;
-			clif_updatestatus(sd,14);
-			clif_updatestatus(sd,17);
-			clif_updatestatus(sd,13);
 		}
 		break;
 	case SP_PERFECT_HIDE: // [Valaris]
@@ -7024,16 +7015,20 @@ int pc_readdb(void)
 
 	while(fgets(line, sizeof(line)-1, fp)){
 		char *split[50];
+		int f=0, m=3;
 		if(line[0]=='/' && line[1]=='/')
 			continue;
-		for(j=0,p=line;j<13 && p;j++){
+		for(j=0,p=line;j<14 && p;j++){
 			split[j]=p;
 			p=strchr(p,',');
 			if(p) *p++=0;
 		}
 		if(j<13)
 			continue;
-		//i=atoi(split[0]);
+		if (j == 14) {
+			f=1;	// MinJobLvl has been added
+			m++;
+		}
 		s_class = pc_calc_base_job(atoi(split[0]));
 		i = s_class.job;
 		u = s_class.upper;
@@ -7045,16 +7040,11 @@ int pc_readdb(void)
 			continue;
 		skill_tree[u][i][j].id=atoi(split[1]);
 		skill_tree[u][i][j].max=atoi(split[2]);
-
-		//not required - Celest
-		//skill_tree[2][i][j].id=atoi(split[1]); //養子職は良く分からないので暫定
-		//skill_tree[2][i][j].max=atoi(split[2]); //養子職は良く分からないので暫定
+		if (f) skill_tree[u][i][j].joblv=atoi(split[3]);
 
 		for(k=0;k<5;k++){
-			skill_tree[u][i][j].need[k].id=atoi(split[k*2+3]);
-			skill_tree[u][i][j].need[k].lv=atoi(split[k*2+4]);
-			//skill_tree[2][i][j].need[k].id=atoi(split[k*2+3]); //養子職は良く分からないので暫定
-			//skill_tree[2][i][j].need[k].lv=atoi(split[k*2+4]); //養子職は良く分からないので暫定
+			skill_tree[u][i][j].need[k].id=atoi(split[k*2+m]);
+			skill_tree[u][i][j].need[k].lv=atoi(split[k*2+m+1]);
 		}
 	}
 	fclose(fp);

+ 1 - 0
src/map/pc.h

@@ -185,6 +185,7 @@ int pc_calc_upper(int b_class);
 struct skill_tree_entry {
 	short id;
 	unsigned char max;
+	unsigned char joblv;
 	struct {
 		short id;
 		unsigned char lv;

+ 32 - 57
src/map/pet.c

@@ -596,14 +596,14 @@ int pet_remove_map(struct map_session_data *sd)
 
 		struct pet_data *pd=sd->pd; // [Valaris]
 		if(pd->skillbonustimer!=-1) pd->skillbonustimer=-1;
-		if(pd->skillbonusduration!=-1) pd->skillbonusduration=-1;
-		if(pd->skilltype !=-1) pd->skilltype=-1;
-		if(pd->skillval !=-1) pd->skillval=-1;
+		pd->skilltype=0;
+		pd->skillval=0;
 		if(pd->skilltimer!=-1) pd->skilltimer=-1;
-		if(pd->skillduration!=-1) pd->skillduration=-1;
-		if(pd->skillbonustype!=-1) pd->skillbonustype=-1;
-		if(pd->skillbonusval!=-1) pd->skillbonusval=-1;
-		if(sd->perfect_hiding==1) sd->perfect_hiding=0;	// end additions		
+		pd->state.skillbonus=-1;
+		pd->skillduration=0;
+		pd->skillbonustype=0;
+		pd->skillbonusval=0;
+		if(sd->perfect_hiding==1) sd->perfect_hiding=0;	// end additions
 
 		pet_changestate(sd->pd,MS_IDLE,0);
 		if(sd->pet_hungry_timer != -1)
@@ -737,9 +737,13 @@ int pet_data_init(struct map_session_data *sd)
 	pd->move_fail_count = 0;
 	pd->next_walktime = pd->attackabletime = pd->last_thinktime = gettick();
 	pd->msd = sd;
-
+	
 	map_addiddb(&pd->bl);
 
+	// initialise
+	pd->state.skillbonus = -1;
+	run_script(pet_db[i].script,0,sd->bl.id,0);
+
 	if(sd->pet_hungry_timer != -1)
 		pet_hungry_timer_delete(sd);
 	if(battle_config.pet_hungry_delay_rate != 100)
@@ -1407,29 +1411,13 @@ int pet_delay_item_drop2(int tid,unsigned int tick,int id,int data)
  * pet bonus giving skills [Valaris]
  *------------------------------------------
  */ 
-
-int pet_skill_bonus(struct map_session_data *sd,struct pet_data *pd,int type,int val,int duration,int timer,int data)
-{
-	if(pd==NULL || sd==NULL)
-		return 1;
-
-	pd->skillbonustype=type;
-	pd->skillbonusval=val;
-	pd->skillduration=duration;
-	pd->skilltimer=timer;
-
-	pd->skillbonustimer=add_timer(gettick()+pd->skilltimer*1000,pet_skill_bonus_timer,sd->bl.id,0);
-
-	return 0;
-
-}
-
 int pet_skill_bonus_timer(int tid,unsigned int tick,int id,int data)
 {
-	struct map_session_data *sd=(struct map_session_data*)map_id2bl(id);
+	struct map_session_data *sd=map_id2sd(id);
 	struct pet_data *pd;
+	int timer = 0;
 	
-	if(sd==NULL || sd->bl.type!=BL_PC)
+	if(sd==NULL)
 		return 1;
 	
 	pd=sd->pd;
@@ -1440,38 +1428,26 @@ int pet_skill_bonus_timer(int tid,unsigned int tick,int id,int data)
 	if(pd->skillbonustimer != tid)
 		return 0;
 
-	pd->skillbonustimer=-1;
-	
-	pc_bonus(sd,pd->skillbonustype,pd->skillbonusval);
-	if(pd->skillbonustype < 56) clif_updatestatus(sd,pd->skillbonustype);
-	pd->skillbonusduration=add_timer(gettick()+pd->skillduration*1000,pet_skill_bonus_duration,sd->bl.id,0);
-	
-	return 0;
-}
-
-int pet_skill_bonus_duration(int tid,unsigned int tick,int id,int data)
-{
-	struct map_session_data *sd=(struct map_session_data*)map_id2bl(id);
-	struct pet_data *pd;
-
-	if(sd==NULL || sd->bl.type!=BL_PC)
-		return 1;
-
-	pd=sd->pd;
-
-	if(pd==NULL || pd->bl.type!=BL_PET)
-		return 1;
-
-	if(pd->skillbonusduration != tid)
-		return 0;
-
-	pd->skillbonusduration=-1;
+	// determine the time for the next timer
+	if (pd->state.skillbonus == 0) {
+		// pet bonuses are not active at the moment, so,
+		pd->state.skillbonus = 1;
+		timer = pd->skillduration;	// the duration for pet bonuses to be in effect
+	} else if (pd->state.skillbonus == 1) {
+		// pet bonuses are already active, so,
+		pd->state.skillbonus = 0;
+		timer = pd->skilltimer;	// the duration which pet bonuses will be reactivated again
+	}
 
-	pc_bonus(sd,pd->skillbonustype,-pd->skillbonusval);
-	if(pd->skillbonustype < 56) clif_updatestatus(sd,pd->skillbonustype);
+	if (pd->state.skillbonus == 1 && sd->petDB)
+		run_script(sd->petDB->script,0,sd->bl.id,0);
 
-	pet_skill_bonus(sd,pd,pd->skillbonustype,pd->skillbonusval,pd->skillduration,pd->skilltimer,0);
+	// add/remove our bonuses, which will be handled by sd->petbonus[]
+	status_calc_pc(sd, 0);
 
+	// wait for the next timer
+	if (timer) pd->skillbonustimer=add_timer(gettick()+timer,pet_skill_bonus_timer,sd->bl.id,0);
+	
 	return 0;
 }
 
@@ -1693,7 +1669,6 @@ int do_init_pet(void)
 	add_timer_func_list(pet_hungry,"pet_hungry");
 	add_timer_func_list(pet_ai_hard,"pet_ai_hard");
 	add_timer_func_list(pet_skill_bonus_timer,"pet_skill_bonus_timer"); // [Valaris]
-	add_timer_func_list(pet_skill_bonus_duration,"pet_skill_bonus_duration"); // [Valaris]
 	add_timer_func_list(pet_recovery_timer,"pet_recovery_timer"); // [Valaris]
 	add_timer_func_list(pet_mag_timer,"pet_mag_timer"); // [Valaris]
 	add_timer_func_list(pet_heal_timer,"pet_heal_timer"); // [Valaris]

+ 0 - 2
src/map/pet.h

@@ -55,9 +55,7 @@ int pet_food(struct map_session_data *sd);
 int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd);
 int pet_delay_item_drop2(int tid,unsigned int tick,int id,int data);
 int pet_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap);
-int pet_skill_bonus(struct map_session_data *sd,struct pet_data *pd,int type,int val,int duration,int timer,int data); 
 int pet_skill_bonus_timer(int tid,unsigned int tick,int id,int data); // [Valaris]
-int pet_skill_bonus_duration(int tid,unsigned int tick,int id,int data); // [Valaris]
 int pet_recovery_timer(int tid,unsigned int tick,int id,int data); // [Valaris]
 int pet_mag_timer(int tid,unsigned int tick,int id,int data); // [Valaris]
 int pet_heal_timer(int tid,unsigned int tick,int id,int data); // [Valaris]

+ 10 - 3
src/map/script.c

@@ -5713,10 +5713,17 @@ int buildin_petskillbonus(struct script_state *st)
 	duration=conv_num(st,& (st->stack->stack_data[st->start+4]));
 	timer=conv_num(st,& (st->stack->stack_data[st->start+5]));
 
-	pd->skillbonusduration=-1;
-	pd->skillbonustimer=-1;
+	// initialise bonuses
+	pd->skillbonustype=type;
+	pd->skillbonusval=val;
+	pd->skillduration=duration*1000;
+	pd->skilltimer=timer*1000;
 
-	pet_skill_bonus(sd,pd,type,val,duration,timer,0);
+	if (pd->state.skillbonus == -1)
+		pd->state.skillbonus=0;	// waiting state
+
+	// wait for timer to start
+	pd->skillbonustimer=add_timer(gettick()+pd->skilltimer,pet_skill_bonus_timer,sd->bl.id,0);
 
 	return 0;
 }

+ 14 - 4
src/map/skill.c

@@ -4239,6 +4239,12 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
 			struct skill_unit *su=NULL;
 			if((bl->type==BL_SKILL) && (su=(struct skill_unit *)bl) && (su->group) ){
 				switch(su->group->unit_id){
+					case 0x91:	// ankle snare
+						if (su->group->val2 != 0)
+							// if it is already trapping something don't spring it,
+							// remove trap should be used instead
+							break;
+						// otherwise fallthrough to below
 					case 0x8f:	/* ブラストマイン */
 					case 0x90:	/* スキッドトラップ */
 					case 0x93:	/* ランドマイン */
@@ -4490,7 +4496,9 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
 			int j = 0;
 			struct guild *g = NULL;
 			// Only usable during WoE
-			if (!agit_flag) {
+			if (!agit_flag ||
+				(sd && map[sd->bl.m].flag.nowarpto &&	// if not allowed to warp to the map
+				guild_mapname2gc(sd->mapname) == NULL)) {	// and it's not a castle...
 				clif_skill_fail(sd,skillid,0,0);
 				map_freeblock_unlock();
 				return 0;
@@ -4500,8 +4508,10 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
 				strcmp(sd->status.name,g->master)==0) {
 				for(i = 0; i < g->max_member; i++, j++) {
 					if (j>8) j=0;
-					if ((dstsd = g->member[i].sd) != NULL && sd != dstsd &&
-						!map[sd->bl.m].flag.nowarpto && !map[dstsd->bl.m].flag.nowarp) {
+					if ((dstsd = g->member[i].sd) != NULL && sd != dstsd) {
+						 if (map[dstsd->bl.m].flag.nowarp &&
+							 guild_mapname2gc(sd->mapname) == NULL)
+							 continue;
 						clif_skill_nodamage(src,bl,skillid,skilllv,1);
 						if(map_getcell(sd->bl.m,sd->bl.x+dx[j],sd->bl.y+dy[j],CELL_CHKNOPASS))
 							dx[j] = dy[j] = 0;
@@ -6325,7 +6335,7 @@ int skill_unit_onlimit(struct skill_unit *src,unsigned int tick)
 		{
 			struct map_session_data *sd = NULL;
 			struct map_session_data *p_sd = NULL;
-			if((sd = (struct map_session_data *)(map_id2bl(sg->src_id))) == NULL)
+			if((sd = map_id2sd(sg->src_id)) == NULL)
 				return 0;
 			if((p_sd = pc_get_partner(sd)) == NULL)
 				return 0;

+ 19 - 3
src/map/status.c

@@ -571,8 +571,11 @@ int status_calc_pc(struct map_session_data* sd,int first)
 	if(sd->status.pet_id > 0) {
 		struct pet_data *pd=sd->pd;
 		if((pd && battle_config.pet_status_support==1) && (battle_config.pet_equip_required==0 || (battle_config.pet_equip_required && pd->equip > 0))) {
-			if(sd->status.pet_id > 0 && sd->petDB && sd->pet.intimate > 0)
-				run_script(sd->petDB->script,0,sd->bl.id,0);
+			if(sd->status.pet_id > 0 && sd->petDB && sd->pet.intimate > 0 &&
+				pd->state.skillbonus == 1) {
+				pc_bonus(sd,pd->skillbonustype,pd->skillbonusval);
+//				run_script(sd->petDB->script,0,sd->bl.id,0);
+			}
 			pele = sd->atk_ele;
 			pdef_ele = sd->def_ele;
 			sd->atk_ele = sd->def_ele = 0;
@@ -2832,6 +2835,16 @@ int status_get_race2(struct block_list *bl)
 	else
 		return 0;
 }
+int status_isdead(struct block_list *bl)
+{
+	nullpo_retr(0, bl);
+	if(bl->type == BL_MOB && (struct mob_data *)bl)
+		return ((struct mob_data *)bl)->state.state == MS_DEAD;
+	else if(bl->type==BL_PC && (struct map_session_data *)bl)
+		return pc_isdead((struct map_session_data *)bl);
+	else
+		return 0;
+}
 
 // StatusChangeŒn‚Ì�Š“¾
 struct status_change *status_get_sc_data(struct block_list *bl)
@@ -2971,6 +2984,9 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val
 	nullpo_retr(0, bl);
 	if(bl->type == BL_SKILL)
 		return 0;
+	if(bl->type == BL_MOB)
+		if (status_isdead(bl)) return 0;
+
 	nullpo_retr(0, sc_data=status_get_sc_data(bl));
 	nullpo_retr(0, sc_count=status_get_sc_count(bl));
 	nullpo_retr(0, option=status_get_option(bl));
@@ -3025,7 +3041,7 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val
 			}
 		}
 	}
-	else if(bl->type == BL_MOB) {
+	else if(bl->type == BL_MOB) {		
 	}
 	else {
 		if(battle_config.error_log)

+ 2 - 0
src/map/status.h

@@ -256,6 +256,8 @@ int status_get_atk_(struct block_list *bl);
 int status_get_atk_2(struct block_list *bl);
 int status_get_atk2(struct block_list *bl);
 
+int status_isdead(struct block_list *bl);
+
 int status_get_sc_def(struct block_list *bl, int type);
 #define status_get_sc_def_mdef(bl)	(status_get_sc_def(bl, SP_MDEF1))
 #define status_get_sc_def_vit(bl)	(status_get_sc_def(bl, SP_DEF2))