summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt5
-rw-r--r--src/map/atcommand.c12
-rw-r--r--src/map/mob.c21
-rw-r--r--src/map/npc.c10
-rw-r--r--src/map/npc.h2
5 files changed, 31 insertions, 19 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index c12fcf0a2..64127e3fb 100644
--- a/Changelog-Trunk.txt
+++ b/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
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 089c88c3c..b7d172f35 100644
--- a/src/map/atcommand.c
+++ b/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;
diff --git a/src/map/mob.c b/src/map/mob.c
index 68addb39c..f717f4f50 100644
--- a/src/map/mob.c
+++ b/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)
diff --git a/src/map/npc.c b/src/map/npc.c
index 13e1cc195..da1487809 100644
--- a/src/map/npc.c
+++ b/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]
diff --git a/src/map/npc.h b/src/map/npc.h
index 286fd6050..e05687969 100644
--- a/src/map/npc.h
+++ b/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);