Parcourir la source

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!
Aleos il y a 7 ans
Parent
commit
d86c8a81be
5 fichiers modifiés avec 43 ajouts et 13 suppressions
  1. 9 1
      doc/script_commands.txt
  2. 7 3
      src/map/script.c
  3. 8 0
      src/map/script_constants.h
  4. 9 9
      src/map/unit.c
  5. 10 0
      src/map/unit.h

+ 9 - 1
doc/script_commands.txt

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

+ 7 - 3
src/map/script.c

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

+ 8 - 0
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

+ 9 - 9
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]

+ 10 - 0
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