#This snippet add some commands that will make the player follow/walk to somewhere
#and until he reach the destination he can't act (walk, attack, use skills, etc).
#Added commands:
#- pc_locked_walk(sd, x, y) [SRC]
#- pc_locked_follow(sd, target) [SRC]
#- lockedwalk <x> <y> [Script]
#- lockedfollow <target> [Script]
#- @lockedwalk <x> <y> [Atcommand]
#- @lockedfollow <target> [Atcommand]
Index: src/map/atcommand.c
===================================================================
--- src/map/atcommand.c (revision 15938)
+++ src/map/atcommand.c (working copy)
@@ -8457,6 +8457,45 @@
return 0;
}
+ACMD_FUNC(lockedwalk)
+{
+ int x, y;
+
+ if (sd == NULL)
+ return 0;
+
+ if (sscanf(message, "%d %d", &x, &y) == 2)
+ {
+ pc_locked_walk(sd, x, y);
+ }
+ else
+ {
+ clif_displaymessage(sd->fd, "usage: @lockedwalk x y");
+ }
+
+ return 0;
+}
+
+ACMD_FUNC(lockedfollow)
+{
+ struct block_list *tbl;
+
+ if (sd == NULL)
+ return 0;
+
+ tbl = (struct block_list *)npc_name2id(message);
+
+ if (tbl == NULL || tbl == (struct block_list *)sd)
+ tbl = (struct block_list *)map_nick2sd(message);
+
+ if (tbl == NULL || tbl == (struct block_list *)sd)
+ return 0;
+
+ pc_locked_follow(sd, tbl->id);
+
+ return 0;
+}
+
/**
* Fills the reference of available commands in atcommand DBMap
**/
@@ -8467,6 +8506,8 @@
* Command reference list, place the base of your commands here
**/
AtCommandInfo atcommand_base[] = {
+ ACMD_DEF(lockedwalk),
+ ACMD_DEF(lockedfollow),
ACMD_DEF2("warp", mapmove),
ACMD_DEF(where),
ACMD_DEF(jumpto),
Index: src/map/pc.c
===================================================================
--- src/map/pc.c (revision 15938)
+++ src/map/pc.c (working copy)
@@ -5260,6 +5260,9 @@
}
sd->followtarget = -1;
+ if (sd->state.locked_walk)
+ sd->state.locked_walk = 0;
+
return 0;
}
@@ -5277,6 +5280,22 @@
return 0;
}
+int pc_locked_follow(struct map_session_data *sd,int target_id)
+{
+ pc_follow(sd, target_id);
+ sd->state.locked_walk = 1;
+
+ return 0;
+}
+
+int pc_locked_walk(struct map_session_data *sd,int x,int y)
+{
+ if (unit_walktoxy(&sd->bl,x,y,4))
+ sd->state.locked_walk = 1;
+
+ return 0;
+}
+
int pc_checkbaselevelup(struct map_session_data *sd)
{
unsigned int next = pc_nextbaseexp(sd);
Index: src/map/pc.h
===================================================================
--- src/map/pc.h (revision 15938)
+++ src/map/pc.h (working copy)
@@ -146,6 +146,9 @@
struct guild *gmaster_flag;
unsigned int prevend : 1;//used to flag wheather you've spent 40sp to open the vending or not.
unsigned int warping : 1;//states whether you're in the middle of a warp processing
+
+ // Locked follow/walk [GreenBox]
+ unsigned int locked_walk : 1;
} state;
struct {
unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
@@ -605,7 +608,7 @@
#define pc_issit(sd) ( (sd)->vd.dead_sit == 2 )
#define pc_isidle(sd) ( (sd)->chatID || (sd)->state.vending || (sd)->state.buyingstore || DIFF_TICK(last_tick, (sd)->idletime) >= battle_config.idle_no_share )
#define pc_istrading(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->state.trading )
-#define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chatID || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag )
+#define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chatID || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.locked_walk )
#define pc_setdir(sd,b,h) ( (sd)->ud.dir = (b) ,(sd)->head_dir = (h) )
#define pc_setchatid(sd,n) ( (sd)->chatID = n )
#define pc_ishiding(sd) ( (sd)->sc.option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) )
@@ -753,8 +756,11 @@
int pc_modifysellvalue(struct map_session_data*,int);
int pc_follow(struct map_session_data*, int); // [MouseJstr]
+int pc_locked_follow(struct map_session_data *sd,int target_id); // [GreenBox]
int pc_stop_following(struct map_session_data*);
+int pc_locked_walk(struct map_session_data *sd,int x,int y); // [GreenBox]
+
unsigned int pc_maxbaselv(struct map_session_data *sd);
unsigned int pc_maxjoblv(struct map_session_data *sd);
int pc_checkbaselevelup(struct map_session_data *sd);
Index: src/map/script.c
===================================================================
--- src/map/script.c (revision 15938)
+++ src/map/script.c (working copy)
@@ -15887,6 +15887,48 @@
BUILDIN_FUNC(deletepset);
#endif
+BUILDIN_FUNC(lockedwalk)
+{
+ int x, y;
+ struct map_session_data *sd;
+
+ if((sd = script_rid2sd(st)) == NULL)
+ return 0;
+
+ if (!script_hasdata(st,2) || !script_hasdata(st,3))
+ {
+ ShowError("buildin_lockedwalk: Missing parameters!");
+ return 0;
+ }
+
+ x = script_hasdata(st,2);
+ y = script_hasdata(st,3);
+
+ pc_locked_walk(sd, x, y);
+
+ return 0;
+}
+
+BUILDIN_FUNC(lockedfollow)
+{
+ int id, targetid;
+ TBL_PC *sd = NULL;
+
+
+ id = script_getnum(st,2);
+ targetid = script_getnum(st,3);
+
+ if(id)
+ sd = map_id2sd(id);
+ else
+ sd = script_rid2sd(st);
+
+ if(sd)
+ pc_locked_follow(sd, targetid);
+
+ return 0;
+}
+
/// script command definitions
/// for an explanation on args, see add_buildin_func
struct script_function buildin_func[] = {
@@ -16315,5 +16357,10 @@
BUILDIN_DEF(checkquest, "i?"),
BUILDIN_DEF(changequest, "ii"),
BUILDIN_DEF(showevent, "ii"),
+
+ // Locked follow/walk [GreenBox]
+ BUILDIN_DEF(lockedwalk,"ii"),
+ BUILDIN_DEF(lockedfollow,"ii"),
+
{NULL,NULL,NULL},
};
Index: src/map/unit.c
===================================================================
--- src/map/unit.c (revision 15938)
+++ src/map/unit.c (working copy)
@@ -185,6 +185,9 @@
{// mercenary is too far from the master so warp the master's position
unit_warp( &sd->md->bl, sd->bl.m, sd->bl.x, sd->bl.y, CLR_TELEPORT );
}
+
+ if (sd->state.locked_walk && ud->to_x == sd->bl.x && ud->to_y == sd->bl.y)
+ sd->state.locked_walk = 0;
} else if (md) {
if( map_getcell(bl->m,x,y,CELL_CHKNPC) ) {
if( npc_touch_areanpc2(md) ) return 0; // Warped