diff --git a/doc/script_commands.txt b/doc/script_commands.txt index da1ef38a82..b0e20c81d5 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -7370,7 +7370,7 @@ This command will make a stop attacking. --------------------------------------- -*unitstopwalk ; +*unitstopwalk {,}; This command will make a stop moving. @@ -7378,6 +7378,14 @@ Note: If this is called from OnTouch, then the walktimer attached to the unit is removed from OnTouch which causes this command to not stop the unit from walking. Suggest to use 'unitblockmove' to forcefully stop the unit with OnTouch. +The value affects how the unit is stopped. The following flags are bitwise +values (can be combined using the pipe operator): + USW_NONE = Unit will keep walking to their original destination. + USW_FIXPOS = Issue a fixpos packet afterwards. + USW_MOVE_ONCE = Force the unit to move one cell if it hasn't yet. + USW_MOVE_FULL_CELL = Enable moving to the next cell when unit was already half-way there (may cause on-touch/place side-effects, such as a scripted map change). + USW_FORCE_STOP = Force stop moving. + --------------------------------------- *unittalk ,""{,flag}; diff --git a/src/map/script.c b/src/map/script.c index 1303898aba..a5fa34db4d 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -18317,13 +18317,17 @@ BUILDIN_FUNC(unitstopattack) /// Makes the unit stop walking. /// -/// unitstopwalk ; +/// unitstopwalk {,}; BUILDIN_FUNC(unitstopwalk) { struct block_list* bl; + int flag = USW_NONE; + + if (script_hasdata(st, 3)) + flag = script_getnum(st, 3); if(script_rid2bl(2,bl)) - unit_stop_walking(bl, 0); + unit_stop_walking(bl, flag); return SCRIPT_CMD_SUCCESS; } @@ -23592,7 +23596,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(unitwarp,"isii"), BUILDIN_DEF(unitattack,"iv?"), BUILDIN_DEF(unitstopattack,"i"), - BUILDIN_DEF(unitstopwalk,"i"), + BUILDIN_DEF(unitstopwalk,"i?"), BUILDIN_DEF(unittalk,"is?"), BUILDIN_DEF(unitemote,"ii"), BUILDIN_DEF(unitskilluseid,"ivi??"), // originally by Qamera [Celest] diff --git a/src/map/script_constants.h b/src/map/script_constants.h index daf216e664..e74786e024 100644 --- a/src/map/script_constants.h +++ b/src/map/script_constants.h @@ -3814,6 +3814,14 @@ export_constant(IG_SPECIAL_CHRISTMAS_BOX); export_constant(IG_SANTA_GIFT); + /* unit stop walking */ + export_constant(USW_NONE); + export_constant(USW_FIXPOS); + export_constant(USW_MOVE_ONCE); + export_constant(USW_MOVE_FULL_CELL); + export_constant(USW_FORCE_STOP); + export_constant(USW_ALL); + #undef export_constant #undef export_constant2 #undef export_parameter diff --git a/src/map/unit.c b/src/map/unit.c index 8ca27a7f1e..91a47ead58 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1233,11 +1233,11 @@ int unit_warp(struct block_list *bl,short m,short x,short y,clr_type type) * Stops a unit from walking * @param bl: Object to stop walking * @param type: Options - * &0x1: Issue a fixpos packet afterwards - * &0x2: Force the unit to move one cell if it hasn't yet - * &0x4: Enable moving to the next cell when unit was already half-way there + * USW_FIXPOS: Issue a fixpos packet afterwards + * USW_MOVE_ONCE: Force the unit to move one cell if it hasn't yet + * USW_MOVE_FULL_CELL: Enable moving to the next cell when unit was already half-way there * (may cause on-touch/place side-effects, such as a scripted map change) - * &0x8: Force stop moving, even if walktimer is currently INVALID_TIMER + * USW_FORCE_STOP: Force stop moving, even if walktimer is currently INVALID_TIMER * @return Success(1); Failed(0); */ int unit_stop_walking(struct block_list *bl,int type) @@ -1250,7 +1250,7 @@ int unit_stop_walking(struct block_list *bl,int type) ud = unit_bl2ud(bl); - if(!ud || (!(type&0x08) && ud->walktimer == INVALID_TIMER)) + if(!ud || (!(type&USW_FORCE_STOP) && ud->walktimer == INVALID_TIMER)) return 0; // NOTE: We are using timer data after deleting it because we know the @@ -1264,14 +1264,14 @@ int unit_stop_walking(struct block_list *bl,int type) ud->state.change_walk_target = 0; tick = gettick(); - if( (type&0x02 && !ud->walkpath.path_pos) // Force moving at least one cell. - || (type&0x04 && td && DIFF_TICK(td->tick, tick) <= td->data/2) // Enough time has passed to cover half-cell + if( (type&USW_MOVE_ONCE && !ud->walkpath.path_pos) // Force moving at least one cell. + || (type&USW_MOVE_FULL_CELL && td && DIFF_TICK(td->tick, tick) <= td->data/2) // Enough time has passed to cover half-cell ) { ud->walkpath.path_len = ud->walkpath.path_pos+1; unit_walktoxy_timer(INVALID_TIMER, tick, bl->id, ud->walkpath.path_pos); } - if(type&0x01) + if(type&USW_FIXPOS) clif_fixpos(bl); ud->walkpath.path_len = 0; @@ -1279,7 +1279,7 @@ int unit_stop_walking(struct block_list *bl,int type) ud->to_x = bl->x; ud->to_y = bl->y; - if(bl->type == BL_PET && type&~0xff) + if(bl->type == BL_PET && type&~USW_ALL) ud->canmove_tick = gettick() + (type>>8); // Re-added, the check in unit_set_walkdelay means dmg during running won't fall through to this place in code [Kevin] diff --git a/src/map/unit.h b/src/map/unit.h index f2d888c804..12af60a705 100644 --- a/src/map/unit.h +++ b/src/map/unit.h @@ -95,6 +95,16 @@ enum e_unit_blown { UB_TARGET_TRAP, // Target is a trap that cannot be knocked back }; +/// Enum for unit_stop_walking +enum e_unit_stop_walking { + USW_NONE = 0x0, /// Unit will keep walking to their original destination + USW_FIXPOS = 0x1, /// Issue a fixpos packet afterwards + USW_MOVE_ONCE = 0x2, /// Force the unit to move one cell if it hasn't yet + USW_MOVE_FULL_CELL = 0x4, /// Enable moving to the next cell when unit was already half-way there (may cause on-touch/place side-effects, such as a scripted map change) + USW_FORCE_STOP = 0x8, /// Force stop moving, even if walktimer is currently INVALID_TIMER + USW_ALL = 0xf, +}; + // PC, MOB, PET // Does walk action for unit