Expanded script command unitstopwalk (#2258)

Fixes #2254.
Added an optional flag to specify the types of methods to stop a unit from walking.
Created an enum for the unit_stop_walking flags.
Thanks to @Yuchinin and @Lemongrass3110!
This commit is contained in:
Aleos 2017-07-16 10:05:17 -04:00 committed by Lemongrass3110
parent 574c753945
commit d86c8a81be
5 changed files with 43 additions and 13 deletions

View File

@ -7370,7 +7370,7 @@ This command will make a <GID> stop attacking.
---------------------------------------
*unitstopwalk <GID>;
*unitstopwalk <GID>{,<flag>};
This command will make a <GID> 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 <flag> 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 <GID>,"<text>"{,flag};

View File

@ -18317,13 +18317,17 @@ BUILDIN_FUNC(unitstopattack)
/// Makes the unit stop walking.
///
/// unitstopwalk <unit_id>;
/// unitstopwalk <unit_id>{,<flag>};
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]

View File

@ -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

View File

@ -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]

View File

@ -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