Преглед изворни кода

- Fixed @movenpc
- Cleaned up and improved the lootsearch routine to pick nearest item.
- Added INVISIBLE_CLASS to the list of classes supported by npc_get_viewdata
- Fixed trying to set the view_data for npcs who are located on a map, but have no visual data.


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

skotlex пре 19 година
родитељ
комит
07c8dd3902
5 измењених фајлова са 31 додато и 19 уклоњено
  1. 5 0
      Changelog-Trunk.txt
  2. 9 3
      src/map/atcommand.c
  3. 9 12
      src/map/mob.c
  4. 7 3
      src/map/npc.c
  5. 1 1
      src/map/npc.h

+ 5 - 0
Changelog-Trunk.txt

@@ -4,6 +4,11 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2006/04/08
+	* Fixed @movenpc [Skotlex]
+	* Cleaned up and improved the lootsearch routine to pick nearest item.
+	  [Skotlex]
+	* Fixed trying to set the view_data for npcs who are located on a map, but
+	  have no visual data. [Skotlex]
 	* Added irc_athena.conf :) from now on, set your irc configuration in
 	  conf/irc_athena.conf [Zido]
 	* Removed the baby class check when using "changebase" to change to the

+ 9 - 3
src/map/atcommand.c

@@ -6999,7 +6999,7 @@ int
 atcommand_npcmove(const int fd, struct map_session_data* sd,
 	const char* command, const char* message)
 {
-	int x = 0, y = 0;
+	int x = 0, y = 0, m;
 	struct npc_data *nd = 0;
 	nullpo_retr(-1, sd);
 
@@ -7020,9 +7020,15 @@ atcommand_npcmove(const int fd, struct map_session_data* sd,
 	if ((nd = npc_name2id(atcmd_player_name)) == NULL)
 		return -1;
 
+	if ((m=nd->bl.m) < 0 || nd->bl.prev == NULL)
+		return -1;	//Not on a map.
+	
 	npc_enable(atcmd_player_name, 0);
-	nd->bl.x = x;
-	nd->bl.y = y;
+	if (x < 0) x = 0;
+	else if (x >= map[m].xs) x = map[m].xs-1;
+	if (y < 0) y = 0;
+	else if (y >= map[m].ys) y = map[m].ys-1;
+	map_moveblock(&nd->bl, x, y, gettick());
 	npc_enable(atcmd_player_name, 1);
 
 	return 0;

+ 9 - 12
src/map/mob.c

@@ -888,19 +888,17 @@ static int mob_ai_sub_hard_changechase(struct block_list *bl,va_list ap)
 static int mob_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap)
 {
 	struct mob_data* md;
-	int dist,*itc;
+	struct block_list **target;
+	int dist;
 
-	nullpo_retr(0, bl);
-	nullpo_retr(0, ap);
-	nullpo_retr(0, md=va_arg(ap,struct mob_data *));
-	nullpo_retr(0, itc=va_arg(ap,int *));
+	md=va_arg(ap,struct mob_data *);
+	target= va_arg(ap,struct block_list**);
 
-	if(!md->lootitem || (battle_config.monster_loot_type == 1 && md->lootitem_count >= LOOTITEM_SIZE))
-		return 0;
-	
 	if((dist=distance_bl(&md->bl, bl)) < md->db->range2 &&
-		mob_can_reach(md,bl,dist, MSS_LOOT) && rand()%1000<1000/(++(*itc)))
-	{	// It is made a probability, such as within the limits PC.
+		mob_can_reach(md,bl,dist, MSS_LOOT) && 
+		((*target) == NULL || !check_distance_bl(&md->bl, *target, dist)) //New target closer than previous one.
+	) {
+		(*target) = bl;
 		md->target_id=bl->id;
 		md->min_chase=md->db->range3;
 		md->next_walktime = gettick() + 500; //So that the mob may go after the item inmediately.
@@ -1216,9 +1214,8 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
 	} else if (!tbl && mode&MD_LOOTER && md->lootitem && 
 		(md->lootitem_count < LOOTITEM_SIZE || battle_config.monster_loot_type != 1))
 	{	// Scan area for items to loot, avoid trying to loot of the mob is full and can't consume the items.
-		i = 0;
 		map_foreachinrange (mob_ai_sub_hard_lootsearch, &md->bl,
-			view_range, BL_ITEM, md, &i);
+			view_range, BL_ITEM, md, &tbl);
 	}
 
 	if (tbl)

+ 7 - 3
src/map/npc.c

@@ -68,6 +68,8 @@ static struct view_data npc_viewdb[MAX_NPC_CLASS];
 
 struct view_data* npc_get_viewdata(int class_)
 {	//Returns the viewdata for normal npc classes.
+	if (class_ == INVISIBLE_CLASS)
+		return &npc_viewdb[0];
 	if (npcdb_checkid(class_) || class_ == WARP_CLASS)
 		return &npc_viewdb[class_];
 	return NULL;
@@ -1887,7 +1889,8 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
 		nd->eventtimer[i] = -1;
 	if (m >= 0) {
 		nd->n = map_addnpc(m, nd);
-		status_set_viewdata(&nd->bl, nd->class_);
+		if (class_ >= 0)
+			status_set_viewdata(&nd->bl, nd->class_);
 		status_change_init(&nd->bl);
 		unit_dataset(&nd->bl);
 		nd->ud.dir = dir;
@@ -2688,7 +2691,7 @@ static void npc_debug_warps_sub(struct npc_data *nd)
 	
 }
 
-static void npc_debug_warps()
+static void npc_debug_warps(void)
 {
 	int m, i;
 	for (m = 0; m < map_num; m++)
@@ -2709,7 +2712,8 @@ int do_init_npc(void)
 
 	//Stock view data for normal npcs.
 	memset(&npc_viewdb, 0, sizeof(npc_viewdb));
-	for (busy = 0; busy < MAX_NPC_CLASS; busy++) 
+	npc_viewdb[0].class_ = INVISIBLE_CLASS; //Invisible class is stored here.
+	for (busy = 1; busy < MAX_NPC_CLASS; busy++) 
 		npc_viewdb[busy].class_ = busy;
 	busy = 0;
 	// indoorrswtable.txt and etcinfo.txt [Celest]

+ 1 - 1
src/map/npc.h

@@ -13,7 +13,7 @@
 #define MAX_NPC_CLASS 1000
 //Checks if a given id is a valid npc id. [Skotlex]
 //Since new npcs are added all the time, the max valid value is the one before the first mob (Scorpion = 1001)
-#define npcdb_checkid(id) ((id >=  46 && id <= 125) || id == 139 || (id >= 700 && id <= MAX_NPC_CLASS))
+#define npcdb_checkid(id) ((id >=  46 && id <= 125) || id == 139 || (id >= 700 && id <= MAX_NPC_CLASS) || id == INVISIBLE_CLASS)
 
 #ifdef PCRE_SUPPORT
 void npc_chat_finalize(struct npc_data *nd);