From b4a305c08f2e6aaf2f1179462958af0f0b184fd2 Mon Sep 17 00:00:00 2001 From: ultramage Date: Thu, 4 Oct 2007 18:41:54 +0000 Subject: * 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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@11354 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/clif.c | 66 ++++++++++++++++++++++++++------------------------------- src/map/clif.h | 2 +- src/map/map.c | 8 +++---- src/map/path.c | 2 +- src/map/skill.c | 37 +++++++++++++++++++------------- src/map/unit.c | 8 ++----- 6 files changed, 60 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/map/clif.c b/src/map/clif.c index a66bd72d5..6331a6201 100644 --- a/src/map/clif.c +++ b/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); -} - /*========================================== * ワープ場所選択 *------------------------------------------*/ diff --git a/src/map/clif.h b/src/map/clif.h index 4361c1895..159a255ec 100644 --- a/src/map/clif.h +++ b/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); diff --git a/src/map/map.c b/src/map/map.c index 668929dfc..967edbab9 100644 --- a/src/map/map.c +++ b/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 diff --git a/src/map/path.c b/src/map/path.c index 52c34756a..9f173fc54 100644 --- a/src/map/path.c +++ b/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) ) diff --git a/src/map/skill.c b/src/map/skill.c index 47a591eed..3e2821464 100644 --- a/src/map/skill.c +++ b/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: diff --git a/src/map/unit.c b/src/map/unit.c index 17d9581f1..ddc590396 100644 --- a/src/map/unit.c +++ b/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. -- cgit v1.2.3-60-g2f50