Jump to content
  • 0

Question

Posted

Hi,

Anyone know how to edit the @follow command?

The current command will warp you to the player you are following
its just like @warpto


Can i request for a edit that this command will not work if the player that trying to follow is on other map
And if in the same map. the user of command will walk to the player following not warp.

Thankyou :)

11 answers to this question

Recommended Posts

Posted

Hi,

Can i request for a edit that this command will not work if the player that trying to follow is on other map

And if in the same map. the user of command will walk to the player following not warp.

Thankyou :)

 

Something like that can't be done in script... Well it could but poorly. Anyways I found some bits of code lying in the source and adapted them to the @follow command.

 

I'm not saying it's perfect but it works. xD

 

Replace the old pc_follow_timer with this one it's located in pc.c...

static int char_warpchase_sub(struct block_list *bl,va_list ap) {
	struct block_list *target;
	struct npc_data **target_nd;
	struct npc_data *nd;
	int *min_distance;
	int cur_distance;

	target= va_arg(ap, struct block_list*);
	target_nd= va_arg(ap, struct npc_data**);
	min_distance= va_arg(ap, int*);

	nd = (TBL_NPC*) bl;

	if(nd->subtype != WARP)
		return 0; //Not a warp

	if(nd->u.warp.mapindex != map[target->m].index)
		return 0; //Does not lead to the same map.

	cur_distance = distance_blxy(target, nd->u.warp.x, nd->u.warp.y);
	if (cur_distance < *min_distance)
	{	//Pick warp that leads closest to target.
		*target_nd = nd;
		*min_distance = cur_distance;
		return 1;
	}
	return 0;
}

int char_warpchase(struct map_session_data *sd, struct block_list *target)
{
	struct npc_data *warp = NULL;
	int distance = AREA_SIZE;

	if (target->m == sd->bl.m && check_distance_bl(&sd->bl, target, AREA_SIZE))
		return 0; //No need to do a warp chase.

	if (sd->ud.walktimer != INVALID_TIMER &&
		map_getcell(sd->bl.m,sd->ud.to_x,sd->ud.to_y,CELL_CHKNPC))
		return 1; //Already walking to a warp.

	//Search for warps within mob's viewing range.
	map_foreachinrange(char_warpchase_sub, &sd->bl, AREA_SIZE, BL_NPC, target, &warp, &distance);

	if (warp && unit_walktobl(&sd->bl, &warp->bl, 1, 1))
		return 1;
	return 0;
}

/*====================================================
 * Timered function to make id follow a target.
 * @id = bl.id (player only atm)
 * target is define in sd->followtarget (bl.id)
 * used by pc_follow
 *----------------------------------------------------*/
int pc_follow_timer(int tid, unsigned int tick, int id, intptr_t data)
{
	struct map_session_data *sd;
	struct block_list *tbl;

	sd = map_id2sd(id);
	nullpo_ret(sd);

	if (sd->followtimer != tid){
		ShowError("pc_follow_timer %d != %d\n",sd->followtimer,tid);
		sd->followtimer = INVALID_TIMER;
		return 0;
	}

	sd->followtimer = INVALID_TIMER;
	tbl = map_id2bl(sd->followtarget);

	if (tbl == NULL || pc_isdead(sd) || status_isdead(tbl))
	{
		pc_stop_following(sd);
		return 0;
	}

	// either player or target is currently detached from map blocks (could be teleporting),
	// but still connected to this map, so we'll just increment the timer and check back later
	if (sd->bl.prev != NULL && tbl->prev != NULL &&
		sd->ud.skilltimer == INVALID_TIMER && sd->ud.attacktimer == INVALID_TIMER && sd->ud.walktimer == INVALID_TIMER)
	{
		if((sd->bl.m == tbl->m) && unit_can_reach_bl(&sd->bl,tbl, AREA_SIZE, 0, NULL, NULL)) {
			if (!check_distance_bl(&sd->bl, tbl, 3))
				unit_walktobl(&sd->bl, tbl, 3, 0);
		} else {
			if (!char_warpchase(sd, tbl)) {
				clif_displaymessage(sd->fd, msg_txt(sd,3)); // Character not found.
				pc_stop_following(sd);
				clif_displaymessage(sd->fd, msg_txt(sd,1159)); // Follow mode OFF.
				return 0; //Not chasing this target.
			}
		}
	}
	sd->followtimer = add_timer(
		tick + 1000,	// increase time a bit to loosen up map's load
		pc_follow_timer, sd->bl.id, 0);
	return 0;
}

What it does now:

If the target is within visual range it will locate and follow them. If they warp through a portal it will attempt to follow them through the portal.

 

The messages that appear when you search for a player, that is online but out of range, are a little off because of the original commands structure. I have a fix for it but it requires more changes in different files. I'm not sure if something so trivial is worth the extra copy and paste.

  • Upvote 1
Posted

 

 

Something like that can't be done in script... Well it could but poorly. Anyways I found some bits of code lying in the source and adapted them to the @follow command.

 

I'm not saying it's perfect but it works. xD

 

What it does now:

If the target is within visual range it will locate and follow them. If they warp through a portal it will attempt to follow them through the portal.

 

The messages that appear when you search for a player that is online but out of range are a little off because of the original commands structure. I have a fix for it but it requires more changes in different files. I'm not sure if something so trivial is worth the extra copy and paste.

 

Hi,

Thank you for response.

anyway i have to test this :)

thank you..

there is no side effect changing my pc.c right? this only affect the @follow command?

Posted

That all depends on if you modify it correctly.

 

Search for this and paste the above code over it.

/*====================================================
 * Timered function to make id follow a target.
 * @id = bl.id (player only atm)
 * target is define in sd->followtarget (bl.id)
 * used by pc_follow
 *----------------------------------------------------*/
int pc_follow_timer(int tid, unsigned int tick, int id, intptr_t data)
{
	struct map_session_data *sd;
	struct block_list *tbl;

	sd = map_id2sd(id);
	nullpo_ret(sd);

	if (sd->followtimer != tid){
		ShowError("pc_follow_timer %d != %d\n",sd->followtimer,tid);
		sd->followtimer = INVALID_TIMER;
		return 0;
	}

	sd->followtimer = INVALID_TIMER;
	tbl = map_id2bl(sd->followtarget);

	if (tbl == NULL || pc_isdead(sd) || status_isdead(tbl))
	{
		pc_stop_following(sd);
		return 0;
	}

	// either player or target is currently detached from map blocks (could be teleporting),
	// but still connected to this map, so we'll just increment the timer and check back later
	if (sd->bl.prev != NULL && tbl->prev != NULL &&
		sd->ud.skilltimer == INVALID_TIMER && sd->ud.attacktimer == INVALID_TIMER && sd->ud.walktimer == INVALID_TIMER)
	{
		if((sd->bl.m == tbl->m) && unit_can_reach_bl(&sd->bl,tbl, AREA_SIZE, 0, NULL, NULL)) {
			if (!check_distance_bl(&sd->bl, tbl, 5))
				unit_walktobl(&sd->bl, tbl, 5, 0);
		} else
			pc_setpos(sd, map_id2index(tbl->m), tbl->x, tbl->y, CLR_TELEPORT);
	}
	sd->followtimer = add_timer(
		tick + 1000,	// increase time a bit to loosen up map's load
		pc_follow_timer, sd->bl.id, 0);
	return 0;
}
  • Upvote 1
Posted

 

That all depends on if you modify it correctly.

 

Search for this and paste the above code over it.

 

haha wait >.<

can you please provide a patch? :)

xD im having difficulty on understanding xD

If its okay for you.

Posted (edited)

Alright. attachicon.gif@follow.patch

Thank you so much sir! :)

 

Edit:

Ive got error

 
pc.c:5542: error: âfdâ undeclared (first use in this function)
pc.c:5542: error: (Each undeclared identifier is reported only once
pc.c:5542: error: for each function it appears in.)

clif_displaymessage(fd, "Character Not Found!!.");

 
Edited by Skorm
Posted

Are you using rAthena? I'll attempt the patch on a fresh server.

 

Edit: I modified a few things to make it work at a further range and I added updated error messages to the patch file.

 

Tested and working with the latest revision of rA at the time of this post.

 

@follow.patch

Posted

Are you using rAthena? I'll attempt the patch on a fresh server.

 

Edit: I modified a few things to make it work at a further range and I added updated error messages to the patch file.

 

Tested and working with the latest revision of rA at the time of this post.

 

attachicon.gif@follow.patch

Thank you.

I will try this.

Posted

Are you using rAthena? I'll attempt the patch on a fresh server.

 

Edit: I modified a few things to make it work at a further range and I added updated error messages to the patch file.

 

Tested and working with the latest revision of rA at the time of this post.

 

attachicon.gif@follow.patch

Hello skorm.

Can you please Update your script upto the latest version of rathena?

cause i got an error when i apply this.

 

pc.c: In function 'char_warpchase_sub':
pc.c:6081: error: 'WARP' undeclared (first use in this function)
pc.c:6081: error: (Each undeclared identifier is reported only once
pc.c:6081: error: for each function it appears in.)
Posted

Hello skorm.

Can you please Update your script upto the latest version of rathena?

cause i got an error when i apply this.

 

pc.c: In function 'char_warpchase_sub':
pc.c:6081: error: 'WARP' undeclared (first use in this function)
pc.c:6081: error: (Each undeclared identifier is reported only once
pc.c:6081: error: for each function it appears in.)

 

 

Here's an updated version...

 

@follow.patch

  • Upvote 1

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...