Sfoglia il codice sorgente

* Corrected Icewall skill to be closer to official behavior (part of bugreport:38)
- now works on occupied squares (previously it disappeared)
- now you can walk out of an icewall square (removed code that blocked pathfinding if the origin cell was of a nonwalkable type)
- added back the hack where mapcell changes are broadcast to whole map (prevents client from leaving the cells non-walkable if you warp away)

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

ultramage 17 anni fa
parent
commit
c7256c0577
7 ha cambiato i file con 66 aggiunte e 63 eliminazioni
  1. 6 0
      Changelog-Trunk.txt
  2. 30 36
      src/map/clif.c
  3. 1 1
      src/map/clif.h
  4. 4 4
      src/map/map.c
  5. 1 1
      src/map/path.c
  6. 22 15
      src/map/skill.c
  7. 2 6
      src/map/unit.c

+ 6 - 0
Changelog-Trunk.txt

@@ -4,6 +4,12 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2007/10/04
+	* Corrected Icewall skill to be closer to official behavior
+	- now works on occupied squares (previously it disappeared)
+	- now you can walk out of an icewall square (removed code that blocked
+	  pathfinding if the origin cell was of a nonwalkable type)
+	- added back the hack where mapcell changes are broadcast to whole map
+	  (prevents client from leaving the cells non-walkable if you warp away)
 	* Removed integer mob skill state/target definition support (unused)
 	* Added script source error reporting to countitem() (topic:167165)
 	* Fixed a compile problem when hotkey saving is disabled (topic:167265)

+ 30 - 36
src/map/clif.c

@@ -274,18 +274,15 @@ int clif_send_sub(struct block_list *bl, va_list ap)
 int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target type)
 {
 	int i;
-	struct map_session_data *sd = NULL;
+	struct map_session_data *sd;
 	struct party_data *p = NULL;
 	struct guild *g = NULL;
 	int x0 = 0, x1 = 0, y0 = 0, y1 = 0, fd;
 
-	if (type != ALL_CLIENT &&
-		type != CHAT_MAINCHAT) {
+	if( type != ALL_CLIENT && type != CHAT_MAINCHAT )
 		nullpo_retr(0, bl);
-		if (bl->type == BL_PC) {
-			sd = (struct map_session_data *)bl;
-		}
-	}
+
+	BL_CAST(BL_PC, bl, sd);
 
 	switch(type) {
 	case ALL_CLIENT: //All player clients.
@@ -3869,30 +3866,27 @@ void clif_standing(struct block_list* bl)
 }
 
 /*==========================================
- *
+ * Inform client(s) about a map-cell change
  *------------------------------------------*/
-void clif_changemapcell(int fd, short m, short x, short y, int type)
+void clif_changemapcell(int fd, struct block_list* pos, int type, enum send_target target)
 {
 	unsigned char buf[32];
+	nullpo_retv(pos);
 
 	WBUFW(buf,0) = 0x192;
-	WBUFW(buf,2) = x;
-	WBUFW(buf,4) = y;
+	WBUFW(buf,2) = pos->x;
+	WBUFW(buf,4) = pos->y;
 	WBUFW(buf,6) = type;
-	mapindex_getmapname_ext(map[m].name,(char*)WBUFP(buf,8));
+	mapindex_getmapname_ext(map[pos->m].name,(char*)WBUFP(buf,8));
 
-	if (fd == 0) {
-		struct block_list bl;
-		bl.type = BL_NUL;
-		bl.m = m;
-		bl.x = x;
-		bl.y = y;
-		clif_send(buf,packet_len(0x192),&bl,AREA);
-	} else {
+	if( fd )
+	{
 		WFIFOHEAD(fd,packet_len(0x192));
 		memcpy(WFIFOP(fd,0), buf, packet_len(0x192));
 		WFIFOSET(fd,packet_len(0x192));
 	}
+	else
+		clif_send(buf,packet_len(0x192),pos,target);
 }
 
 /*==========================================
@@ -3957,7 +3951,7 @@ static void clif_getareachar_skillunit(struct map_session_data *sd, struct skill
 	WFIFOSET(fd,packet_len(0x11f));
 
 	if(unit->group->skill_id == WZ_ICEWALL)
-		clif_changemapcell(fd,unit->bl.m,unit->bl.x,unit->bl.y,5);
+		clif_changemapcell(fd,&unit->bl,5,SELF);
 }
 
 /*==========================================
@@ -3973,7 +3967,21 @@ static void clif_clearchar_skillunit(struct skill_unit *unit, int fd)
 	WFIFOSET(fd,packet_len(0x120));
 
 	if(unit->group && unit->group->skill_id == WZ_ICEWALL)
-		clif_changemapcell(fd,unit->bl.m,unit->bl.x,unit->bl.y,unit->val2);
+		clif_changemapcell(fd,&unit->bl,unit->val2,SELF);
+}
+
+/*==========================================
+ * 場所スキルエフェクト削除
+ *------------------------------------------*/
+void clif_skill_delunit(struct skill_unit *unit)
+{
+	unsigned char buf[16];
+
+	nullpo_retv(unit);
+
+	WBUFW(buf, 0)=0x120;
+	WBUFL(buf, 2)=unit->bl.id;
+	clif_send(buf,packet_len(0x120),&unit->bl,AREA);
 }
 
 /*==========================================
@@ -4554,20 +4562,6 @@ void clif_skill_setunit(struct skill_unit *unit)
 	clif_send(buf,packet_len(0x11f),&unit->bl,AREA);
 }
 
-/*==========================================
- * 場所スキルエフェクト削除
- *------------------------------------------*/
-void clif_skill_delunit(struct skill_unit *unit)
-{
-	unsigned char buf[16];
-
-	nullpo_retv(unit);
-
-	WBUFW(buf, 0)=0x120;
-	WBUFL(buf, 2)=unit->bl.id;
-	clif_send(buf,packet_len(0x120),&unit->bl,AREA);
-}
-
 /*==========================================
  * ワープ場所選択
  *------------------------------------------*/

+ 1 - 1
src/map/clif.h

@@ -229,7 +229,7 @@ int clif_marionette(struct block_list *src, struct block_list *target);
 int clif_spiritball(struct map_session_data *sd);
 int clif_combo_delay(struct block_list *src,int wait);
 int clif_bladestop(struct block_list *src,struct block_list *dst,int bool_);
-void clif_changemapcell(int fd, short m, short x, short y, int type);
+void clif_changemapcell(int fd, struct block_list* pos, int type, enum send_target target);
 
 int clif_status_load(struct block_list *bl,int type, int flag);
 int clif_status_change(struct block_list *bl,int type,int flag);

+ 4 - 4
src/map/map.c

@@ -2189,25 +2189,25 @@ int map_calc_dir(struct block_list* src, int x, int y)
 	}
 	else if( dx >= 0 && dy >=0 )
 	{	// upper-right
-		if( dx*2-1 < dy )     dir = 0;	// up
+		if( dx*2 <= dy )      dir = 0;	// up
 		else if( dx > dy*2 )  dir = 6;	// right
 		else                  dir = 7;	// up-right
 	}
 	else if( dx >= 0 && dy <= 0 )
 	{	// lower-right
-		if( dx*2-1 < -dy )    dir = 4;	// down
+		if( dx*2 <= -dy )     dir = 4;	// down
 		else if( dx > -dy*2 ) dir = 6;	// right
 		else                  dir = 5;	// down-right
 	}
 	else if( dx <= 0 && dy <= 0 )
 	{	// lower-left
-		if( dx*2+1 > dy )     dir = 4;	// down
+		if( dx*2 >= dy )      dir = 4;	// down
 		else if( dx < dy*2 )  dir = 2;	// left
 		else                  dir = 3;	// down-left
 	}
 	else
 	{	// upper-left
-		if( -dx*2-1 < dy )    dir = 0;	// up
+		if( -dx*2 <= dy )     dir = 0;	// up
 		else if( -dx > dy*2 ) dir = 2;	// left
 		else                  dir = 1;	// up-left
 	

+ 1 - 1
src/map/path.c

@@ -324,7 +324,7 @@ int path_search_real(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1
 	//Do not check starting cell as that would get you stuck.
 	if( x0 < 0 || x0 >= md->xs || y0 < 0 || y0 >= md->ys )
 #else
-	if( x0 < 0 || x0 >= md->xs || y0 < 0 || y0 >= md->ys || map_getcellp(md,x0,y0,flag2) )
+	if( x0 < 0 || x0 >= md->xs || y0 < 0 || y0 >= md->ys /*|| map_getcellp(md,x0,y0,flag2)*/ )
 #endif
 		return -1;
 	if( x1 < 0 || x1 >= md->xs || y1 < 0 || y1 >= md->ys || map_getcellp(md,x1,y1,flag2) )

+ 22 - 15
src/map/skill.c

@@ -2957,7 +2957,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
 			//HACK: since knockback officially defaults to the left, the client also turns to the left... therefore,
 			// make the caster look in the direction of the target
 			unit_setdir(src, (dir+4)%8);
-			clif_changed_dir(src, AREA);
 		}
 
 		}
@@ -7017,7 +7016,14 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid,
 				if(celltype==5 || celltype==1)
 					alive=0;
 				else
-					clif_changemapcell(0,src->m,ux,uy,5);
+				{
+					struct block_list bl;
+					bl.type = BL_NUL;
+					bl.m = src->m;
+					bl.x = ux;
+					bl.y = uy;
+					clif_changemapcell(0,&bl,5,AREA);
+				}
 		}
 
 		if(alive){
@@ -7187,11 +7193,12 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
 			sc_start4(bl,type,100,sg->skill_lv,0,BCT_ENEMY,sg->group_id,sg->limit);
 		break;
 
-	case UNT_ICEWALL: //Destroy the cell. [Skotlex]
-		src->val1 = 0;
-		if(src->limit + sg->tick > tick + 700)
-			src->limit = DIFF_TICK(tick+700,sg->tick);
-		break;
+// officially, icewall has no problems existing on occupied cells [ultramage]
+//	case UNT_ICEWALL: //Destroy the cell. [Skotlex]
+//		src->val1 = 0;
+//		if(src->limit + sg->tick > tick + 700)
+//			src->limit = DIFF_TICK(tick+700,sg->tick);
+//		break;
 	
 	case UNT_MOONLIT:
 		//Knockback out of area if affected char isn't in Moonlit effect
@@ -7839,7 +7846,9 @@ int skill_unit_onlimit (struct skill_unit *src, unsigned int tick, int flag)
 		break;
 
 	case UNT_ICEWALL:
-		clif_changemapcell(0,src->bl.m,src->bl.x,src->bl.y,src->val2);
+		// hack to prevent client from leaving cells unwalkable
+		//FIXME: this should be done individually in insight/outsight code instead [ultramage]
+		clif_changemapcell(0,&src->bl,src->val2,ALL_SAMEMAP);
 		break;
 	case UNT_CALLFAMILY:
 		if (!flag)
@@ -9922,21 +9931,19 @@ int skill_delunit (struct skill_unit *unit, int flag)
 	struct skill_unit_group *group;
 
 	nullpo_retr(0, unit);
-	if(!unit->alive)
+	if( !unit->alive )
 		return 0;
 	nullpo_retr(0, group=unit->group);
 
 	// invoke onlimit event
-	skill_unit_onlimit( unit,gettick(), flag);
+	skill_unit_onlimit(unit, gettick(), flag);
 
-	if (group->state.song_dance&0x1) //Restore dissonance effect.
+	if( group->state.song_dance&0x1 ) //Restore dissonance effect.
 		skill_dance_overlap(unit, 0);
 
 	// invoke onout event
-	if (!unit->range) {
-		map_foreachincell(skill_unit_effect,unit->bl.m,
-			unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),4);
-	}
+	if( !unit->range )
+		map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),4);
 
 	switch (group->skill_id) {
 	case AL_PNEUMA:

+ 2 - 6
src/map/unit.c

@@ -457,13 +457,9 @@ int unit_run(struct block_list *bl)
 int unit_escape(struct block_list *bl, struct block_list *target, int dist)
 {
 	int dir = map_calc_dir(target, bl->x, bl->y);
-	while (dist > 0 && map_getcell(bl->m,
-		bl->x + dist*dirx[dir], bl->y + dist*diry[dir],
-		CELL_CHKNOREACH))
+	while( dist > 0 && map_getcell(bl->m, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], CELL_CHKNOREACH) )
 		dist--;
-	return (dist > 0 && unit_walktoxy(bl,
-		bl->x + dist*dirx[dir], bl->y + dist*diry[dir],
-		0));
+	return ( dist > 0 && unit_walktoxy(bl, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], 0) );
 }
 
 //Instant warp function.