summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-07-05 18:07:31 +0000
committerultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-07-05 18:07:31 +0000
commita7574756fd69e9935bbb98d0d0fe6c3d3645d71f (patch)
treedf23a8e42a8a66d8334f3408f2ac445bc782a083 /src/map
parent888584986b05b663898726aa5bf9f4ea9f3d8495 (diff)
downloadhercules-a7574756fd69e9935bbb98d0d0fe6c3d3645d71f.tar.gz
hercules-a7574756fd69e9935bbb98d0d0fe6c3d3645d71f.tar.bz2
hercules-a7574756fd69e9935bbb98d0d0fe6c3d3645d71f.tar.xz
hercules-a7574756fd69e9935bbb98d0d0fe6c3d3645d71f.zip
* update from Skotlex
- Fixed NPC_STOP's visual effect not clearing when the status ends - Corrected @homshuffle making the skill tree be lost. - Corrected homunculus skills being unusable if the master was sitting or inflicted by a disabling status (eg: petrify, stun) - Some fixes to the cell no stacking mod (mainly mobs would just get stuck behind each other and not properly surround you) git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@10856 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.c3
-rw-r--r--src/map/clif.c116
-rw-r--r--src/map/status.c2
-rw-r--r--src/map/status.h1
-rw-r--r--src/map/unit.c26
5 files changed, 100 insertions, 48 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index bfcb2600c..ccd5b37ed 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -8550,7 +8550,7 @@ int atcommand_homshuffle(const int fd, struct map_session_data* sd, const char*
struct homun_data *hd;
int lv, i, skillpts;
unsigned int exp;
- struct skill b_skill;
+ struct skill b_skill[MAX_HOMUNSKILL];
TBL_PC* tsd = sd;
nullpo_retr(-1, sd);
@@ -8591,6 +8591,7 @@ int atcommand_homshuffle(const int fd, struct map_session_data* sd, const char*
hd->homunculus.exp = exp;
memcpy(&hd->homunculus.hskill, &b_skill, sizeof(b_skill));
hd->homunculus.skillpts = skillpts;
+ clif_homskillinfoblock(hd->master);
status_calc_homunculus(hd,0);
status_percent_heal(&hd->bl, 100, 100);
clif_misceffect2(&hd->bl,568);
diff --git a/src/map/clif.c b/src/map/clif.c
index e7bab9ebc..07e9716a3 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -869,9 +869,11 @@ static int clif_set0078(struct block_list* bl, unsigned char* buf)
WBUFW(buf,30)=vd->cloth_color;
WBUFW(buf,32)=sd?sd->head_dir:0;
WBUFL(buf,34)=guild_id;
- WBUFL(buf,38)=emblem_id;
- if (sd)
+ WBUFW(buf,38)=emblem_id;
+ if (sd) {
+ WBUFW(buf,40)=sd->status.manner;
WBUFB(buf,44)=sd->status.karma;
+ }
WBUFB(buf,45)=vd->sex;
WBUFPOS(buf,46,bl->x,bl->y,dir);
WBUFB(buf,49)=5;
@@ -894,9 +896,9 @@ static int clif_set0078(struct block_list* bl, unsigned char* buf)
WBUFW(buf,42)=sc->opt3;
}
WBUFW(buf,14)=vd->class_;
- WBUFW(buf,16)=vd->hair_style; //Required for pets.
+ WBUFW(buf,16)=vd->hair_style; //Required for pets (removes attack cursor)
//18W: Weapon
- WBUFW(buf,20)=vd->head_bottom; //Pet armor
+ WBUFW(buf,20)=vd->head_bottom; //Pet armor (ignored by client)
if (bl->type == BL_NPC && vd->class_ == FLAG_CLASS)
{ //The hell, why flags work like this?
WBUFL(buf,22)=emblem_id;
@@ -907,22 +909,22 @@ static int clif_set0078(struct block_list* bl, unsigned char* buf)
//26W: Head mid
//28W: Hair color
//30W: Clothes color
- WBUFW(buf,32)=dir;
+ //32W: Head dir
WBUFL(buf,34)=guild_id;
- WBUFL(buf,38)=emblem_id;
- //42W: Manner
+ WBUFW(buf,38)=emblem_id;
+ //40W: Manner
//44B: Karma
//45B: Sex
WBUFPOS(buf,46,bl->x,bl->y,dir);
- //WBUFB(buf,49)=5;
- //WBUFB(buf,50)=5;
+ //49B: ???
+ //50B: ???
//51B: Sit/Stand
WBUFW(buf,52)=clif_setlevel(lv);
return packet_len(0x78);
}
/*==========================================
- *
+ * Prepares 'unit walking' packet
*------------------------------------------*/
static int clif_set007b(struct block_list *bl, struct view_data *vd, struct unit_data *ud, unsigned char *buf)
{
@@ -972,8 +974,8 @@ static int clif_set007b(struct block_list *bl, struct view_data *vd, struct unit
}
WBUFB(buf,53)=vd->sex;
WBUFPOS2(buf,54,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
- WBUFB(buf,60)=0;
- WBUFB(buf,61)=0;
+ WBUFB(buf,60)=5;
+ WBUFB(buf,61)=5;
WBUFW(buf,62)=clif_setlevel(lv);
return packet_len(0x22c);
@@ -1037,9 +1039,11 @@ static int clif_set007b(struct block_list *bl, struct view_data *vd, struct unit
WBUFW(buf,34)=vd->cloth_color;
WBUFW(buf,36)=sd?sd->head_dir:0;
WBUFL(buf,38)=guild_id;
- WBUFL(buf,42)=emblem_id;
- if (sd)
+ WBUFW(buf,42)=emblem_id;
+ if (sd) {
+ WBUFW(buf,44)=sd->status.manner;
WBUFB(buf,48)=sd->status.karma;
+ }
WBUFB(buf,49)=vd->sex;
WBUFPOS2(buf,50,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
WBUFB(buf,56)=5;
@@ -1063,15 +1067,23 @@ static int clif_set007b(struct block_list *bl, struct view_data *vd, struct unit
WBUFL(buf,48)=sc->opt3;
}
WBUFW(buf,16)=vd->class_;
- WBUFW(buf,18)=vd->hair_style; //For pets
+ WBUFW(buf,18)=vd->hair_style; //Required for pets (removes attack cursor)
+ //20L: Weapon/Shield
WBUFW(buf,24)=vd->head_bottom; //Pet armor
WBUFL(buf,26)=gettick();
- WBUFW(buf,38)=unit_getdir(bl);
+ //30W: Head top
+ //32W: Head mid
+ //34W: Hair color
+ //36W: Cloth color
+ //38W: Head dir
WBUFL(buf,40)=guild_id;
- WBUFL(buf,44)=emblem_id;
+ WBUFW(buf,44)=emblem_id;
+ //46W: Manner
+ //52B: Karma
+ //53B: Sex
WBUFPOS2(buf,54,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
- WBUFB(buf,60)=0;
- WBUFB(buf,61)=0;
+ //60B: ???
+ //61B: ???
WBUFW(buf,62)=clif_setlevel(lv);
return packet_len(0x22c);
#else
@@ -1088,11 +1100,21 @@ static int clif_set007b(struct block_list *bl, struct view_data *vd, struct unit
}
WBUFW(buf,14)=vd->class_;
WBUFW(buf,16)=vd->hair_style; //For pets
- WBUFW(buf,20)=vd->head_bottom; //Pet armor
+ //18W: Weapon
+ WBUFW(buf,20)=vd->head_bottom; //Pet armor
WBUFL(buf,22)=gettick();
- WBUFW(buf,36)=unit_getdir(bl);
+ //26W: Shield
+ //28W: Head top
+ //30W: Head mid
+ //32W: Hair color
+ //34W: Cloth color
+ //36W: Head dir
WBUFL(buf,38)=guild_id;
- WBUFL(buf,42)=emblem_id;
+ WBUFW(buf,42)=emblem_id;
+ //44W: Manner
+ //46W: Opt3
+ //48B: Karma
+ //49B: Sex
WBUFPOS2(buf,50,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
WBUFB(buf,56)=5;
WBUFB(buf,57)=5;
@@ -1109,6 +1131,7 @@ static int clif_set007b(struct block_list *bl, struct view_data *vd, struct unit
static void clif_setdisguise(struct map_session_data *sd, unsigned char *buf,int len, int flag)
{
if (flag) {
+ WBUFL(buf,2)=sd->bl.id;
#if PACKETVER > 6
switch (WBUFW(buf,0)) {
case 0x22c:
@@ -1119,7 +1142,6 @@ static void clif_setdisguise(struct map_session_data *sd, unsigned char *buf,int
break;
default:
#endif
- WBUFL(buf,2)=sd->bl.id;
WBUFW(buf,12)=OPTION_INVISIBLE;
WBUFW(buf,14)=sd->status.class_;
#if PACKETVER > 6
@@ -1259,7 +1281,7 @@ int clif_spawn(struct block_list *bl)
return 0;
if (pcdb_checkid(vd->class_))
- { //Player spawn packet.
+ { // player spawn packet
clif_set0078(bl, buf);
switch(WBUFW(buf,0))
{
@@ -1289,7 +1311,7 @@ int clif_spawn(struct block_list *bl)
break;
#endif
}
- } else { //Mob spawn packet.
+ } else { // npc/mob/pet/homun spawn packet
struct status_change *sc = status_get_sc(bl);
memset(buf,0,sizeof(buf));
WBUFW(buf,0)=0x7c;
@@ -1300,9 +1322,21 @@ int clif_spawn(struct block_list *bl)
WBUFW(buf,10)=sc->opt2;
WBUFW(buf,12)=sc->option;
}
+ //14W: Hair Style
+ //16W: Weapon
+ //18W: Head bottom
WBUFW(buf,20)=vd->class_;
-
+ //22W: Shield
+ //24W: Head top
+ //26W: Head mid
+ //28W: Hair color
+ //30W: Cloth color
+ //32W: Head dir
+ //34B: karma
+ //35B: Sex
WBUFPOS(buf,36,bl->x,bl->y,unit_getdir(bl));
+ //39B: ???
+ //40B: ???
clif_send(buf,packet_len(0x7c),bl,AREA_WOS);
if (disguised(bl)) {
WBUFL(buf,2)=-bl->id;
@@ -1337,9 +1371,9 @@ int clif_spawn(struct block_list *bl)
break;
case BL_PET:
{
- unsigned char buf[64];
- int len = clif_set0078(bl, buf);
- clif_send(buf, len, bl, AREA_WOS);
+ TBL_PET* pd = (TBL_PET*)bl;
+ clif_pet_equip(pd); // needed to display pet equip properly
+ clif_send_petdata_area(pd, 5, battle_config.pet_hair_style); // removes the attack cursor
}
break;
}
@@ -3728,9 +3762,16 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl)
break;
case BL_PET:
{
- unsigned char buf[64];
- int len = clif_set0078(bl, buf);
- clif_send(buf, len, &sd->bl, SELF);
+ // needed to display pet equip properly
+ //TODO: adjust clif_pet_equip() to support a 'target', then rewrite this mess into a function call
+ TBL_PET* pd = (TBL_PET*)bl;
+ int fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0x1a4));
+ WFIFOW(fd,0) = 0x1a4;
+ WFIFOB(fd,2) = 3;
+ WFIFOL(fd,3) = pd->bl.id;
+ WFIFOL(fd,7) = pd->vd.head_bottom;
+ WFIFOSET(fd,packet_len(0x1a4));
}
break;
}
@@ -8023,7 +8064,6 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
map_addblock(&sd->pd->bl);
clif_spawn(&sd->pd->bl);
clif_send_petdata(sd,0,0);
- clif_send_petdata(sd,5,battle_config.pet_hair_style);
clif_send_petstatus(sd);
// skill_unit_move(&sd->pd->bl,gettick(),1);
}
@@ -9420,11 +9460,6 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
int skillnum, skilllv, tmp, target_id;
unsigned int tick = gettick();
- if (clif_cant_act(sd))
- return;
- if (pc_issit(sd))
- return;
-
skilllv = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
if (skilllv < 1) skilllv = 1; //No clue, I have seen the client do this with guild skills :/ [Skotlex]
skillnum = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
@@ -9442,6 +9477,11 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
return;
}
+ if (clif_cant_act(sd))
+ return;
+ if (pc_issit(sd))
+ return;
+
if (skillnotok(skillnum, sd))
return;
diff --git a/src/map/status.c b/src/map/status.c
index 8672f81a8..dda86240c 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -276,7 +276,7 @@ void initChangeTables(void)
set_sc(DC_SERVICEFORYOU, SC_SERVICE4U, SI_BLANK, SCB_MAXSP|SCB_PC);
add_sc(NPC_DARKCROSS, SC_BLIND);
add_sc(NPC_GRANDDARKNESS, SC_BLIND);
- add_sc(NPC_STOP, SC_STOP);
+ set_sc(NPC_STOP, SC_STOP, SI_STOP, SCB_NONE);
set_sc(NPC_BREAKWEAPON, SC_BROKENWEAPON, SI_BROKENWEAPON, SCB_NONE);
set_sc(NPC_BREAKARMOR, SC_BROKENARMOR, SI_BROKENARMOR, SCB_NONE);
set_sc(NPC_CHANGEUNDEAD, SC_CHANGEUNDEAD, SI_UNDEAD, SCB_DEF_ELE);
diff --git a/src/map/status.h b/src/map/status.h
index 2e01a1e7c..e1907d234 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -336,6 +336,7 @@ enum {
SI_WATERWEAPON = 91,
SI_WINDWEAPON = 92,
SI_EARTHWEAPON = 93,
+ SI_STOP = 95,
SI_UNDEAD = 97,
// 102 = again gloria - from what I saw on screenshots, I wonder if it isn't gospel... [DracoRPG]
SI_AURABLADE = 103,
diff --git a/src/map/unit.c b/src/map/unit.c
index c05b8e25a..f09444b4c 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -317,6 +317,11 @@ int unit_walktoxy( struct block_list *bl, int x, int y, int flag)
return unit_walktoxy_sub(bl);
}
+//To set Mob's CHASE/FOLLOW states (shouldn't be done if there's no path to reach)
+#define set_mobstate(bl, flag) \
+ if((bl)->type == BL_MOB && (flag)) \
+ ((TBL_MOB*)(bl))->state.skillstate = ((TBL_MOB*)(bl))->state.aggressive?MSS_FOLLOW:MSS_RUSH;
+
static int unit_walktobl_sub(int tid,unsigned int tick,int id,int data)
{
struct block_list *bl = map_id2bl(id);
@@ -327,7 +332,10 @@ static int unit_walktobl_sub(int tid,unsigned int tick,int id,int data)
if (DIFF_TICK(ud->canmove_tick, tick) > 0) //Keep waiting?
add_timer(ud->canmove_tick+1, unit_walktobl_sub, id, data);
else if (unit_can_move(bl))
- unit_walktoxy_sub(bl);
+ {
+ if (unit_walktoxy_sub(bl))
+ set_mobstate(bl, ud->state.attack_continue);
+ }
}
return 0;
}
@@ -361,13 +369,10 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int
sc = status_get_sc(bl);
if (sc && sc->count && sc->data[SC_CONFUSION].timer != -1) //Randomize the target position
map_random_dir(bl, &ud->to_x, &ud->to_y);
-
- //Set Mob's CHASE/FOLLOW states.
- if(bl->type == BL_MOB && flag&2)
- ((TBL_MOB*)bl)->state.skillstate = ((TBL_MOB*)bl)->state.aggressive?MSS_FOLLOW:MSS_RUSH;
if(ud->walktimer != -1) {
ud->state.change_walk_target = 1;
+ set_mobstate(bl, flag&2);
return 1;
}
@@ -385,8 +390,13 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int
ud->attacktimer = -1;
}
- return unit_walktoxy_sub(bl);
+ if (unit_walktoxy_sub(bl)) {
+ set_mobstate(bl, flag&2);
+ return 1;
+ }
+ return 0;
}
+#undef set_mobstate
int unit_run(struct block_list *bl)
{
@@ -1317,9 +1327,9 @@ int unit_can_reach_bl(struct block_list *bl,struct block_list *tbl, int range, i
dx=(dx>0)?1:((dx<0)?-1:0);
dy=(dy>0)?1:((dy<0)?-1:0);
- if (map_getcell(tbl->m,tbl->x-dx,tbl->y-dy,CELL_CHKNOREACH))
+ if (map_getcell(tbl->m,tbl->x-dx,tbl->y-dy,CELL_CHKNOPASS))
{ //Look for a suitable cell to place in.
- for(i=0;i<9 && map_getcell(tbl->m,tbl->x-dirx[i],tbl->y-diry[i],CELL_CHKNOREACH);i++);
+ for(i=0;i<9 && map_getcell(tbl->m,tbl->x-dirx[i],tbl->y-diry[i],CELL_CHKNOPASS);i++);
if (i==9) return 0; //No valid cells.
dx = dirx[i];
dy = diry[i];