Sfoglia il codice sorgente

* Fixed Status Recovery dealing too short blind time on undead mobs
* Fixed mobs not affected by Blind status
* Added an invalid id check check in map_id2sd
* Added sd check in clif_send

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

celest 20 anni fa
parent
commit
313d2ec7dd
5 ha cambiato i file con 72 aggiunte e 64 eliminazioni
  1. 5 0
      Changelog-SVN.txt
  2. 31 33
      src/map/clif.c
  3. 4 2
      src/map/map.c
  4. 25 21
      src/map/mob.c
  5. 7 8
      src/map/skill.c

+ 5 - 0
Changelog-SVN.txt

@@ -1,9 +1,14 @@
 Date	Added
 
 03/12
+        * Fixed Status Recovery dealing too short blind time on undead [celest]
+        * Fixed mobs not affected by Blind status [celest]
+        * Added an invalid id check check in map_id2sd [celest]
+        * Added sd check in clif_send [celest]
         * Fixed usage of mvp_hp_rate and monster_hp_rate. MVP rate was used for common monsters [Lupus]
 	* Added additional random respawn delay for instant respawning monsters (0..5 seconds) [Lupus]
 		- Should be made as an option of battle_athena.conf
+
 03/11
         * Fixed "--en/ja--" usage in 'monster' script not working properly, thanks
           to sbilly [celest]

+ 31 - 33
src/map/clif.c

@@ -295,8 +295,7 @@ int clif_send_sub(struct block_list *bl, va_list ap)
  */
 int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
 	int i;
-	struct map_session_data *sd;
-	struct chat_data *cd;
+	struct map_session_data *sd = NULL;
 	struct party *p = NULL;
 	struct guild *g = NULL;
 	int x0 = 0, x1 = 0, y0 = 0, y1 = 0;
@@ -304,6 +303,9 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
 	if (type != ALL_CLIENT) {
 		nullpo_retr(0, bl);
 	}
+	if (bl && bl->type == BL_PC) {
+		nullpo_retr (0, sd=(struct map_session_data*)bl);
+	}
 
 	switch(type) {
 	case ALL_CLIENT: // 全クライアントに送信
@@ -337,21 +339,24 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
 		break;
 	case CHAT:
 	case CHAT_WOS:
-		cd = (struct chat_data*)bl;
-		if (bl->type == BL_PC) {
-			sd = (struct map_session_data*)bl;
-			cd = (struct chat_data*)map_id2bl(sd->chatID);
-		} else if (bl->type != BL_CHAT)
-			break;
-		if (cd == NULL)
-			break;
-		for(i = 0; i < cd->users; i++) {
-			if (type == CHAT_WOS && cd->usersd[i] == (struct map_session_data*)bl)
-				continue;
-			if (packet_db[cd->usersd[i]->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
-				if (cd->usersd[i]->fd >=0 && session[cd->usersd[i]->fd]) // Added check to see if session exists [PoW]
-					memcpy(WFIFOP(cd->usersd[i]->fd,0), buf, len);
-				WFIFOSET(cd->usersd[i]->fd,len);
+		{
+			struct chat_data *cd;
+			if (sd) {
+				cd = (struct chat_data*)map_id2bl(sd->chatID);
+			} else if (bl->type == BL_CHAT) {
+				cd = (struct chat_data*)bl;
+			} else if (bl->type != BL_CHAT)
+				break;
+			if (cd == NULL)
+				break;
+			for(i = 0; i < cd->users; i++) {
+				if (type == CHAT_WOS && cd->usersd[i] == sd)
+					continue;
+				if (packet_db[cd->usersd[i]->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
+					if (cd->usersd[i]->fd >=0 && session[cd->usersd[i]->fd]) // Added check to see if session exists [PoW]
+						memcpy(WFIFOP(cd->usersd[i]->fd,0), buf, len);
+					WFIFOSET(cd->usersd[i]->fd,len);
+				}
 			}
 		}
 		break;
@@ -366,13 +371,11 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
 	case PARTY_WOS:			// 自分以外の全パーティーメンバに送信
 	case PARTY_SAMEMAP:		// 同じマップの全パーティーメンバに送信
 	case PARTY_SAMEMAP_WOS:	// 自分以外の同じマップの全パーティーメンバに送信
-		if (bl->type == BL_PC) {
-			sd = (struct map_session_data *)bl;
+		if (sd) {
 			if (sd->partyspy > 0) {
 				p = party_search(sd->partyspy);
-			} else {
-				if (sd->status.party_id > 0)
-					p = party_search(sd->status.party_id);
+			} else if (sd->status.party_id > 0) {
+				p = party_search(sd->status.party_id);
 			}
 		}
 		if (p) {
@@ -411,8 +414,7 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
 		}
 		break;
 	case SELF:
-		sd = (struct map_session_data *)bl;
-		if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
+		if (sd && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
 			memcpy(WFIFOP(sd->fd,0), buf, len);
 			WFIFOSET(sd->fd,len);
 		}
@@ -428,13 +430,11 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
 		y1 = bl->y + AREA_SIZE;
 	case GUILD:
 	case GUILD_WOS:
-		if (bl && bl->type == BL_PC) { // guildspy [Syrus22]
-			sd = (struct map_session_data *)bl;
+		if (sd) { // guildspy [Syrus22]
 			if (sd->guildspy > 0) {
 				g = guild_search(sd->guildspy);
-			} else {
-				if (sd->status.guild_id > 0)
-					g = guild_search(sd->status.guild_id);
+			} else if (sd->status.guild_id > 0) {
+				g = guild_search(sd->status.guild_id);
 			}
 		}
 		if (g) {
@@ -462,10 +462,8 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
 		break;
 	case GUILD_SAMEMAP:
 	case GUILD_SAMEMAP_WOS:
-		if (bl->type == BL_PC) {
-			sd = (struct map_session_data *)bl;
-			if (sd->status.guild_id > 0)
-				g = guild_search(sd->status.guild_id);
+		if (sd && sd->status.guild_id > 0) {
+			g = guild_search(sd->status.guild_id);
 		}
 		if (g) {
 			for(i = 0; i < g->max_member; i++) {

+ 4 - 2
src/map/map.c

@@ -1576,7 +1576,9 @@ struct map_session_data * map_id2sd(int id) {
 	return NULL;
 */
 	int i;
-	struct map_session_data *sd=NULL;
+	struct map_session_data *sd;
+
+	if (id <= 0) return 0;
 
 	for(i = 0; i < fd_max; i++)
 		if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd->bl.id == id)
@@ -2927,7 +2929,7 @@ int inter_config_read(char *cfgName)
 		} else if(strcmpi(w1,"map_server_db")==0){
 			strcpy(map_server_db, w2);
 		} else if(strcmpi(w1,"use_sql_db")==0){
-			if (strcmpi(w2,"yes")){db_use_sqldbs=0;} else if (strcmpi(w2,"no")){db_use_sqldbs=1;}
+			db_use_sqldbs = battle_config_switch(w2);
 			printf ("Using SQL dbs: %s\n",w2);
 		//Login Server SQL DB
 		} else if(strcmpi(w1,"login_server_ip")==0){

+ 25 - 21
src/map/mob.c

@@ -1596,6 +1596,8 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
 	int i,dx,dy,ret,dist;
 	int attack_type=0;
 	int mode,race;
+	int search_size = AREA_SIZE*2;
+	int blind_flag = 0;
 
 	nullpo_retr(0, bl);
 	nullpo_retr(0, ap);
@@ -1625,6 +1627,9 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
 	if((md->opt1 > 0 && md->opt1 != 6) || md->state.state==MS_DELAY || md->sc_data[SC_BLADESTOP].timer != -1)
 		return 0;
 
+	if (md->sc_data && md->sc_data[SC_BLIND].timer != -1)
+		blind_flag = 1;
+
 	if(!(mode&0x80) && md->target_id > 0)
 		md->target_id = 0;
 
@@ -1649,7 +1654,8 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
 			if(abl->type==BL_PC)
 				asd=(struct map_session_data *)abl;
 			if(asd==NULL || md->bl.m != abl->m || abl->prev == NULL || asd->invincible_timer != -1 || pc_isinvisible(asd) ||
-				(dist=distance(md->bl.x,md->bl.y,abl->x,abl->y))>=32 || battle_check_target(bl,abl,BCT_ENEMY)==0)
+				(dist=distance(md->bl.x,md->bl.y,abl->x,abl->y))>=32 || battle_check_target(bl,abl,BCT_ENEMY)==0 ||
+				(blind_flag && dist>3))
 				md->attacked_id=0;
 			else {
 				//距離が遠い場合はタゲを変更しない
@@ -1676,15 +1682,16 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
 	if( (!md->target_id || md->state.targettype == NONE_ATTACKABLE) && mode&0x04 && !md->state.master_check &&
 		battle_config.monster_active_enable){
 		i=0;
+		search_size = (blind_flag) ? 3 : AREA_SIZE*2;
 		if(md->state.special_mob_ai){
 			map_foreachinarea(mob_ai_sub_hard_activesearch,md->bl.m,
-							  md->bl.x-AREA_SIZE*2,md->bl.y-AREA_SIZE*2,
-							  md->bl.x+AREA_SIZE*2,md->bl.y+AREA_SIZE*2,
+							  md->bl.x-search_size,md->bl.y-search_size,
+							  md->bl.x+search_size,md->bl.y+search_size,
 							  0,md,&i);
 		}else{
 			map_foreachinarea(mob_ai_sub_hard_activesearch,md->bl.m,
-							  md->bl.x-AREA_SIZE*2,md->bl.y-AREA_SIZE*2,
-							  md->bl.x+AREA_SIZE*2,md->bl.y+AREA_SIZE*2,
+							  md->bl.x-search_size,md->bl.y-search_size,
+							  md->bl.x+search_size,md->bl.y+search_size,
 							  BL_PC,md,&i);
 		}
 	}
@@ -1692,9 +1699,10 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
 	// The item search of a route monster
 	if( !md->target_id && mode&0x02 && !md->state.master_check){
 		i=0;
+		search_size = (blind_flag) ? 3 : AREA_SIZE*2;
 		map_foreachinarea(mob_ai_sub_hard_lootsearch,md->bl.m,
-						  md->bl.x-AREA_SIZE*2,md->bl.y-AREA_SIZE*2,
-						  md->bl.x+AREA_SIZE*2,md->bl.y+AREA_SIZE*2,
+						  md->bl.x-search_size,md->bl.y-search_size,
+						  md->bl.x+search_size,md->bl.y+search_size,
 						  BL_ITEM,md,&i);
 	}
 
@@ -1706,7 +1714,7 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
 			else if(tbl->type==BL_MOB)
 				tmd=(struct mob_data *)tbl;
 			if(tsd || tmd) {
-				if(tbl->m != md->bl.m || tbl->prev == NULL || (dist=distance(md->bl.x,md->bl.y,tbl->x,tbl->y))>=md->min_chase)
+				if(tbl->m != md->bl.m || tbl->prev == NULL || (dist=distance(md->bl.x,md->bl.y,tbl->x,tbl->y)) >= search_size || (blind_flag && dist>3))
 					mob_unlocktarget(md,tick);	// 別マップか、視界外
 				else if( tsd && !(mode&0x20) && (tsd->sc_data[SC_TRICKDEAD].timer != -1 || tsd->sc_data[SC_BASILICA].timer != -1 ||
 					((pc_ishiding(tsd) || tsd->state.gangsterparadise) &&
@@ -1725,9 +1733,11 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
 //					if(md->timer != -1 && (DIFF_TICK(md->next_walktime,tick)<0 || distance(md->to_x,md->to_y,tsd->bl.x,tsd->bl.y)<2) )
 					if(md->timer != -1 && md->state.state!=MS_ATTACK && (DIFF_TICK(md->next_walktime,tick)<0 || distance(md->to_x,md->to_y,tbl->x,tbl->y)<2) )
 						return 0; // 既に移動中
-					if( !mob_can_reach(md,tbl,(md->min_chase>13)?md->min_chase:13) )
+					search_size = (blind_flag) ? 3 :
+						((md->min_chase > 13) ? md->min_chase : 13);
+					if(!mob_can_reach(md,tbl, search_size))
 						mob_unlocktarget(md,tick);	// 移動できないのでタゲ解除(IWとか?)
-					else{
+					else {
 						// 追跡
 						md->next_walktime=tick+500;
 						i=0;
@@ -1761,8 +1771,8 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
 							if(dy<0) dy=2;
 							else if(dy>0) dy=-2;
 							mob_walktoxy(md,md->bl.x+dx,md->bl.y+dy,0);
+						}
 					}
-				}
 				} else { // 攻撃射程範囲内
 					md->state.skillstate=MSS_ATTACK;
 					if(md->state.state==MS_WALK)
@@ -1770,23 +1780,17 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
 					if(md->state.state==MS_ATTACK)
 						return 0; // 既に攻撃中
 					mob_changestate(md,MS_ATTACK,attack_type);
-
-/*					if(mode&0x08){	// リンクモンスター
-						map_foreachinarea(mob_ai_sub_hard_linksearch,md->bl.m,
-							md->bl.x-13,md->bl.y-13,
-							md->bl.x+13,md->bl.y+13,
-							BL_MOB,md,&tsd->bl);
-					}*/
 				}
 				return 0;
-			}else{	// ルートモンスター処理
+			} else {	// ルートモンスター処理
 				if(tbl == NULL || tbl->type != BL_ITEM ||tbl->m != md->bl.m ||
-					 (dist=distance(md->bl.x,md->bl.y,tbl->x,tbl->y))>=md->min_chase || !md->lootitem){
+					(dist=distance(md->bl.x,md->bl.y,tbl->x,tbl->y))>=md->min_chase || !md->lootitem |
+					(blind_flag && dist>=4)){
 					 // 遠すぎるかアイテムがなくなった
 					mob_unlocktarget(md,tick);
 					if(md->state.state==MS_WALK)
 						mob_stop_walking(md,1);	// 歩行中なら停止
-				}else if(dist){
+				} else if(dist) {
 					if(!(mode&1)){	// 移動しないモード
 						mob_unlocktarget(md,tick);
 						return 0;

+ 7 - 8
src/map/skill.c

@@ -3633,7 +3633,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
 
 	case AL_CURE:				/* キュア? */
 		clif_skill_nodamage(src,bl,skillid,skilllv,1);
-		if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+		if(dstsd && dstsd->special_state.no_magic_damage )
 			break;
 		status_change_end(bl, SC_SILENCE	, -1 );
 		status_change_end(bl, SC_BLIND	, -1 );
@@ -3652,18 +3652,17 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
 	case PR_STRECOVERY:			/* リカバリ? */
 		{
 			clif_skill_nodamage(src,bl,skillid,skilllv,1);
-			if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+			if(dstsd && dstsd->special_state.no_magic_damage)
 				break;
 			status_change_end(bl, SC_FREEZE	, -1 );
 			status_change_end(bl, SC_STONE	, -1 );
 			status_change_end(bl, SC_SLEEP	, -1 );
-			status_change_end(bl, SC_STAN		, -1 );
+			status_change_end(bl, SC_STAN	, -1 );
 			if( battle_check_undead(status_get_race(bl),status_get_elem_type(bl)) ){//アンデッドなら暗闇?果
-				int blind_time;
-				//blind_time=30-status_get_vit(bl)/10-status_get_int/15;
-				blind_time=30*(100-(status_get_int(bl)+status_get_vit(bl))/2)/100;
-				if(rand()%100 < (100-(status_get_int(bl)/2+status_get_vit(bl)/3+status_get_luk(bl)/10)))
-					status_change_start(bl, SC_BLIND,1,0,0,0,blind_time,0);
+				if(rand()%100 < (100-(status_get_int(bl)/2+status_get_vit(bl)/3+status_get_luk(bl)/10))) {
+					status_change_start(bl, SC_BLIND,1,0,0,0,
+						1000 * 30 * (100-(status_get_int(bl)+status_get_vit(bl))/2)/100,0);
+				}
 			}
 			if(dstmd){
 				dstmd->attacked_id=0;