Browse Source

* Added script command pushpc, which is required by newer scripts.
- Moved knockback-part of skill_blown into unit_blown, to allow unconditional knockback required by pushpc without copy-pasting code.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@14492 54d463be-8e91-2dee-dedb-b68131a5f0ec

ai4rei 14 years ago
parent
commit
1b9c1fc3d1
7 changed files with 120 additions and 39 deletions
  1. 3 0
      Changelog-Trunk.txt
  2. 9 0
      db/const.txt
  3. 18 0
      doc/script_commands.txt
  4. 39 0
      src/map/script.c
  5. 2 39
      src/map/skill.c
  6. 48 0
      src/map/unit.c
  7. 1 0
      src/map/unit.h

+ 3 - 0
Changelog-Trunk.txt

@@ -1,5 +1,8 @@
 Date	Added
 
+2010/11/23
+	* Added script command pushpc, which is required by newer scripts. [Ai4rei]
+	- Moved knockback-part of skill_blown into unit_blown, to allow unconditional knockback required by pushpc without copy-pasting code.
 2010/11/22
 	* mail_deliveryfail no longer attempts to log (since r12910) and give items (since r11855), when there is no item attached to the mail (bugreport:3239). [Ai4rei]
 	* Fixed a crash when shutting down char-server (TXT only), after it failed to load storage save data (since r1275). [Ai4rei]

+ 9 - 0
db/const.txt

@@ -1842,3 +1842,12 @@ VAR_HEADPALETTE	6
 VAR_BODYPALETTE	7
 VAR_SHIELD	8
 VAR_SHOES	9
+
+DIR_NORTH	0
+DIR_NORTHWEST	1
+DIR_WEST	2
+DIR_SOUTHWEST	3
+DIR_SOUTH	4
+DIR_SOUTHEAST	5
+DIR_EAST	6
+DIR_NORTHEAST	7

+ 18 - 0
doc/script_commands.txt

@@ -135,6 +135,8 @@
 //= 3.28.20091119
 //=       Added showevent and searchitem commands [Skotlex]
 //=       Added info on strcharinfo(3) [Skotlex]
+//= 3.29.20101123
+//=       Added 'pushpc' command. [Ai4rei]
 //=========================================================
 
 This document is a reference manual for all the scripting commands and functions 
@@ -3869,6 +3871,22 @@ example, there is a Stylist script inside the default eAthena installation that
 you can look at, this may help you create a Stylist of your own: 
 'custom\dye.txt'
 
+---------------------------------------
+
+*pushpc <direction>,<cells>;
+
+This command will push the currently attached player to given direction by given
+amount of square cells. Direction is the same as used when declaring npcs, and
+can be specified by using one of the DIR_* constants (db/const.txt).
+
+The knock-back is not restricted by items or map flags, only obstacles are taken
+into account. If there is not enough space to perform the push (e.g. due to a
+wall), the character is pushed only up to the obstacle.
+
+    // pushes the character 5 cells in 3 o'clock direction from it's
+    // current position.
+    pushpc DIR_EAST, 5;
+
 ---------------------------------------
 \\
 4,1.- Item-related commands

+ 39 - 0
src/map/script.c

@@ -14380,6 +14380,44 @@ BUILDIN_FUNC(progressbar)
     return 0;
 }
 
+BUILDIN_FUNC(pushpc)
+{
+	int direction, cells, dx, dy;
+	struct map_session_data* sd;
+
+	if((sd = script_rid2sd(st))==NULL)
+	{
+		return 0;
+	}
+
+	direction = script_getnum(st,2);
+	cells     = script_getnum(st,3);
+
+	if(direction<0 || direction>7)
+	{
+		ShowWarning("buildin_pushpc: Invalid direction %d specified.\n", direction);
+		script_reportsrc(st);
+
+		direction%= 8;  // trim spin-over
+	}
+
+	if(!cells)
+	{// zero distance
+		return 0;
+	}
+	else if(cells<0)
+	{// pushing backwards
+		direction = (direction+4)%8;  // turn around
+		cells     = -cells;
+	}
+
+	dx = dirx[direction];
+	dy = diry[direction];
+
+	unit_blown(&sd->bl, dx, dy, cells, 0);
+	return 0;
+}
+
 // declarations that were supposed to be exported from npc_chat.c
 #ifdef PCRE_SUPPORT
 BUILDIN_FUNC(defpattern);
@@ -14739,6 +14777,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(setfont,"i"),
 	BUILDIN_DEF(areamobuseskill,"siiiiviiiii"),
 	BUILDIN_DEF(progressbar, "si"),
+	BUILDIN_DEF(pushpc,"ii"),
 	// WoE SE
 	BUILDIN_DEF(agitstart2,""),
 	BUILDIN_DEF(agitend2,""),

+ 2 - 39
src/map/skill.c

@@ -1467,8 +1467,7 @@ int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int
  -------------------------------------------------------------------------*/
 int skill_blown(struct block_list* src, struct block_list* target, int count, int direction, int flag)
 {
-	int dx = 0, dy = 0, nx, ny;
-	int ret;
+	int dx = 0, dy = 0;
 	struct skill_unit* su = NULL;
 
 	nullpo_ret(src);
@@ -1514,43 +1513,7 @@ int skill_blown(struct block_list* src, struct block_list* target, int count, in
 		dy = -diry[direction];
 	}
 
-	ret=path_blownpos(target->m,target->x,target->y,dx,dy,count);
-	nx = ret>>16;
-	ny = ret&0xffff;
-
-	if (!su)
-		unit_stop_walking(target,0);
-
-	dx = nx - target->x;
-	dy = ny - target->y;
-
-	if (!dx && !dy) //Could not knockback.
-		return 0;
-
-	map_foreachinmovearea(clif_outsight, target, AREA_SIZE, dx, dy, target->type == BL_PC ? BL_ALL : BL_PC, target);
-
-	if(su)
-		skill_unit_move_unit_group(su->group,target->m,dx,dy);
-	else
-		map_moveblock(target, nx, ny, gettick());
-
-	map_foreachinmovearea(clif_insight, target, AREA_SIZE, -dx, -dy, target->type == BL_PC ? BL_ALL : BL_PC, target);
-
-	if(!(flag&0x1))
-		clif_blown(target);
-
-	if( target->type == BL_PC )
-	{
-		TBL_PC *sd = (TBL_PC*)target;
-		if( sd->touching_id )
-			npc_touchnext_areanpc(sd,false);
-		if( map_getcell(target->m,target->x,target->y,CELL_CHKNPC) )
-			npc_touch_areanpc(sd,target->m,target->x,target->y);
-		else
-			sd->areanpc_id=0;
-	}
-
-	return count; //Return amount of knocked back cells.
+	return unit_blown(target, dx, dy, count, flag&0x1);
 }
 
 

+ 48 - 0
src/map/unit.c

@@ -566,6 +566,54 @@ uint8 unit_getdir(struct block_list *bl)
 	return ud->dir;
 }
 
+// Pushes a unit by given amount of cells into given direction. Only
+// map cell restrictions are respected.
+// flag:
+//  &1  Do not send position update packets.
+int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag)
+{
+	int nx, ny, ret;
+	struct skill_unit* su = BL_CAST(BL_SKILL, bl);
+
+	ret=path_blownpos(bl->m,bl->x,bl->y,dx,dy,count);
+	nx = ret>>16;
+	ny = ret&0xffff;
+
+	if (!su)
+		unit_stop_walking(bl,0);
+
+	dx = nx - bl->x;
+	dy = ny - bl->y;
+
+	if (!dx && !dy) //Could not knockback.
+		return 0;
+
+	map_foreachinmovearea(clif_outsight, bl, AREA_SIZE, dx, dy, bl->type == BL_PC ? BL_ALL : BL_PC, bl);
+
+	if(su)
+		skill_unit_move_unit_group(su->group,bl->m,dx,dy);
+	else
+		map_moveblock(bl, nx, ny, gettick());
+
+	map_foreachinmovearea(clif_insight, bl, AREA_SIZE, -dx, -dy, bl->type == BL_PC ? BL_ALL : BL_PC, bl);
+
+	if(!(flag&0x1))
+		clif_blown(bl);
+
+	if( bl->type == BL_PC )
+	{
+		TBL_PC *sd = (TBL_PC*)bl;
+		if( sd->touching_id )
+			npc_touchnext_areanpc(sd,false);
+		if( map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC) )
+			npc_touch_areanpc(sd,bl->m,bl->x,bl->y);
+		else
+			sd->areanpc_id=0;
+	}
+
+	return count; //Return amount of knocked back cells.
+}
+
 //Warps a unit/ud to a given map/position. 
 //In the case of players, pc_setpos is used.
 //it respects the no warp flags, so it is safe to call this without doing nowarpto/nowarp checks.

+ 1 - 0
src/map/unit.h

@@ -84,6 +84,7 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool
 int unit_warp(struct block_list *bl, short map, short x, short y, int type);
 int unit_setdir(struct block_list *bl,unsigned char dir);
 uint8 unit_getdir(struct block_list *bl);
+int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag);
 
 // そこまで歩行でたどり着けるかの判定
 bool unit_can_reach_pos(struct block_list *bl,int x,int y,int easy);