#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 [Script] #- lockedfollow [Script] #- @lockedwalk [Atcommand] #- @lockedfollow [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