summaryrefslogtreecommitdiff
path: root/src/map/npc.c
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2013-05-30 21:00:22 -0300
committershennetsind <ind@henn.et>2013-05-30 21:00:22 -0300
commit20bdc01fa687b174a732be4483ddea4982d67ce9 (patch)
tree3336c1c449a78d52d25d2534acbd319d10c56b45 /src/map/npc.c
parent21bbfad48084190b8a6881ee3b277993418a5137 (diff)
downloadhercules-20bdc01fa687b174a732be4483ddea4982d67ce9.tar.gz
hercules-20bdc01fa687b174a732be4483ddea4982d67ce9.tar.bz2
hercules-20bdc01fa687b174a732be4483ddea4982d67ce9.tar.xz
hercules-20bdc01fa687b174a732be4483ddea4982d67ce9.zip
Memory Slasher - May 30 Patch
http://hercules.ws/board/topic/928-memory-slasher-may-30-patch/ Signed-off-by: shennetsind <ind@henn.et>
Diffstat (limited to 'src/map/npc.c')
-rw-r--r--src/map/npc.c327
1 files changed, 145 insertions, 182 deletions
diff --git a/src/map/npc.c b/src/map/npc.c
index 7d0d5c6e1..bff6be30c 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -122,7 +122,7 @@ struct view_data* npc_get_viewdata(int class_)
static int npc_isnear_sub(struct block_list* bl, va_list args) {
struct npc_data *nd = (struct npc_data*)bl;
- if( nd->sc.option & (OPTION_HIDE|OPTION_INVISIBLE) )
+ if( nd->option & (OPTION_HIDE|OPTION_INVISIBLE) )
return 0;
return 1;
@@ -175,7 +175,7 @@ int npc_enable_sub(struct block_list *bl, va_list ap)
{
TBL_PC *sd = (TBL_PC*)bl;
- if (nd->sc.option&OPTION_INVISIBLE)
+ if (nd->option&OPTION_INVISIBLE)
return 1;
if( npc_ontouch_event(sd,nd) > 0 && npc_ontouch2_event(sd,nd) > 0 )
@@ -204,20 +204,20 @@ int npc_enable(const char* name, int flag)
}
if (flag&1) {
- nd->sc.option&=~OPTION_INVISIBLE;
+ nd->option&=~OPTION_INVISIBLE;
clif->spawn(&nd->bl);
} else if (flag&2)
- nd->sc.option&=~OPTION_HIDE;
+ nd->option&=~OPTION_HIDE;
else if (flag&4)
- nd->sc.option|= OPTION_HIDE;
+ nd->option|= OPTION_HIDE;
else { //Can't change the view_data to invisible class because the view_data for all npcs is shared! [Skotlex]
- nd->sc.option|= OPTION_INVISIBLE;
+ nd->option|= OPTION_INVISIBLE;
clif->clearunit_area(&nd->bl,CLR_OUTSIGHT); // Hack to trick maya purple card [Xazax]
}
if (nd->class_ == WARP_CLASS || nd->class_ == FLAG_CLASS)
{ //Client won't display option changes for these classes [Toms]
- if (nd->sc.option&(OPTION_HIDE|OPTION_INVISIBLE))
+ if (nd->option&(OPTION_HIDE|OPTION_INVISIBLE))
clif->clearunit_area(&nd->bl, CLR_OUTSIGHT);
else
clif->spawn(&nd->bl);
@@ -385,8 +385,7 @@ static int npc_event_do_sub(DBKey key, DBData *data, va_list ap)
nullpo_ret(c = va_arg(ap, int *));
nullpo_ret(name = va_arg(ap, const char *));
- if( p && strcmpi(name, p) == 0 )
- {
+ if( p && strcmpi(name, p) == 0 ) {
run_script(ev->nd->u.scr.script,ev->pos,0,ev->nd->bl.id);
(*c)++;
}
@@ -815,7 +814,7 @@ int npc_event_sub(struct map_session_data* sd, struct event_data* ev, const char
ShowWarning("npc_event: player's event queue is full, can't add event '%s' !\n", eventname);
return 1;
}
- if( ev->nd->sc.option&OPTION_INVISIBLE )
+ if( ev->nd->option&OPTION_INVISIBLE )
{
//Disabled npc, shouldn't trigger event.
npc_event_dequeue(sd);
@@ -835,22 +834,20 @@ int npc_event(struct map_session_data* sd, const char* eventname, int ontouch)
nullpo_ret(sd);
- if( ev == NULL || (nd = ev->nd) == NULL )
- {
+ if( ev == NULL || (nd = ev->nd) == NULL ) {
if( !ontouch )
ShowError("npc_event: event not found [%s]\n", eventname);
return ontouch;
}
- switch(ontouch)
- {
- case 1:
- nd->touching_id = sd->bl.id;
- sd->touching_id = nd->bl.id;
- break;
- case 2:
- sd->areanpc_id = nd->bl.id;
- break;
+ switch(ontouch) {
+ case 1:
+ nd->touching_id = sd->bl.id;
+ sd->touching_id = nd->bl.id;
+ break;
+ case 2:
+ sd->areanpc_id = nd->bl.id;
+ break;
}
return npc_event_sub(sd,ev,eventname);
@@ -928,9 +925,8 @@ int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y)
//if(sd->npc_id)
// return 1;
- for(i=0;i<map[m].npc_num;i++)
- {
- if (map[m].npc[i]->sc.option&OPTION_INVISIBLE) {
+ for(i=0;i<map[m].npc_num;i++) {
+ if (map[m].npc[i]->option&OPTION_INVISIBLE) {
f=0; // a npc was found, but it is disabled; don't print warning
continue;
}
@@ -1008,13 +1004,11 @@ int npc_touch_areanpc2(struct mob_data *md)
struct event_data* ev;
int xs, ys;
- for( i = 0; i < map[m].npc_num; i++ )
- {
- if( map[m].npc[i]->sc.option&OPTION_INVISIBLE )
+ for( i = 0; i < map[m].npc_num; i++ ) {
+ if( map[m].npc[i]->option&OPTION_INVISIBLE )
continue;
- switch( map[m].npc[i]->subtype )
- {
+ switch( map[m].npc[i]->subtype ) {
case WARP:
if( !( battle_config.mob_warp&1 ) )
continue;
@@ -1087,27 +1081,25 @@ int npc_check_areanpc(int flag, int16 m, int16 x, int16 y, int16 range)
if (!i) return 0; //No NPC_CELLs.
//Now check for the actual NPC on said range.
- for(i=0;i<map[m].npc_num;i++)
- {
- if (map[m].npc[i]->sc.option&OPTION_INVISIBLE)
+ for(i=0;i<map[m].npc_num;i++) {
+ if (map[m].npc[i]->option&OPTION_INVISIBLE)
continue;
- switch(map[m].npc[i]->subtype)
- {
- case WARP:
- if (!(flag&1))
- continue;
- xs=map[m].npc[i]->u.warp.xs;
- ys=map[m].npc[i]->u.warp.ys;
- break;
- case SCRIPT:
- if (!(flag&2))
+ switch(map[m].npc[i]->subtype) {
+ case WARP:
+ if (!(flag&1))
+ continue;
+ xs=map[m].npc[i]->u.warp.xs;
+ ys=map[m].npc[i]->u.warp.ys;
+ break;
+ case SCRIPT:
+ if (!(flag&2))
+ continue;
+ xs=map[m].npc[i]->u.scr.xs;
+ ys=map[m].npc[i]->u.scr.ys;
+ break;
+ default:
continue;
- xs=map[m].npc[i]->u.scr.xs;
- ys=map[m].npc[i]->u.scr.ys;
- break;
- default:
- continue;
}
if( x1 >= map[m].npc[i]->bl.x-xs && x0 <= map[m].npc[i]->bl.x+xs
@@ -1206,7 +1198,7 @@ int npc_click(struct map_session_data* sd, struct npc_data* nd)
if ((nd = npc_checknear(sd,&nd->bl)) == NULL)
return 1;
//Hidden/Disabled npc.
- if (nd->class_ < 0 || nd->sc.option&(OPTION_INVISIBLE|OPTION_HIDE))
+ if (nd->class_ < 0 || nd->option&(OPTION_INVISIBLE|OPTION_HIDE))
return 1;
switch(nd->subtype) {
@@ -1291,7 +1283,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type)
sd->npc_id=0;
return 1;
}
- if (nd->sc.option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?)
+ if (nd->option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?)
return 1;
if( nd->class_ < 0 && !sd->state.callshop )
{// not called through a script and is not a visible NPC so an invalid call
@@ -1759,8 +1751,7 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
//Atempt to remove an npc from a map
//This doesn't remove it from map_db
-int npc_remove_map(struct npc_data* nd)
-{
+int npc_remove_map(struct npc_data* nd) {
int16 m,i;
nullpo_retr(1, nd);
@@ -1892,6 +1883,11 @@ int npc_unload(struct npc_data* nd, bool single) {
guild->flag_remove(nd);
}
+ if( nd->ud != &npc_base_ud ) {
+ aFree(nd->ud);
+ nd->ud = NULL;
+ }
+
script_stop_sleeptimers(nd->bl.id);
aFree(nd);
@@ -2060,8 +2056,7 @@ static void npc_parsename(struct npc_data* nd, const char* name, const char* sta
}
//Add then display an npc warp on map
-struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y)
-{
+struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y) {
int i, flag = 0;
struct npc_data *nd;
@@ -2100,8 +2095,7 @@ struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short
npc_setcells(nd);
map_addblock(&nd->bl);
status_set_viewdata(&nd->bl, nd->class_);
- status_change_init(&nd->bl);
- unit_dataset(&nd->bl);
+ nd->ud = &npc_base_ud;
if( map[nd->bl.m].users )
clif->spawn(&nd->bl);
strdb_put(npcname_db, nd->exname, nd);
@@ -2166,8 +2160,7 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const
npc_setcells(nd);
map_addblock(&nd->bl);
status_set_viewdata(&nd->bl, nd->class_);
- status_change_init(&nd->bl);
- unit_dataset(&nd->bl);
+ nd->ud = &npc_base_ud;
if( map[nd->bl.m].users )
clif->spawn(&nd->bl);
strdb_put(npcname_db, nd->exname, nd);
@@ -2275,18 +2268,15 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
++npc_shop;
nd->bl.type = BL_NPC;
nd->subtype = type;
- if( m >= 0 )
- {// normal shop npc
+ if( m >= 0 ) {// normal shop npc
map_addnpc(m,nd);
map_addblock(&nd->bl);
status_set_viewdata(&nd->bl, nd->class_);
- status_change_init(&nd->bl);
- unit_dataset(&nd->bl);
- nd->ud.dir = dir;
+ nd->ud = &npc_base_ud;
+ nd->dir = dir;
if( map[nd->bl.m].users )
clif->spawn(&nd->bl);
- } else
- {// 'floating' shop?
+ } else {// 'floating' shop?
map_addiddb(&nd->bl);
}
strdb_put(npcname_db, nd->exname, nd);
@@ -2485,23 +2475,18 @@ static const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, cons
nd->bl.type = BL_NPC;
nd->subtype = SCRIPT;
- if( m >= 0 )
- {
+ if( m >= 0 ) {
map_addnpc(m, nd);
- status_change_init(&nd->bl);
- unit_dataset(&nd->bl);
- nd->ud.dir = dir;
+ nd->ud = &npc_base_ud;
+ nd->dir = dir;
npc_setcells(nd);
map_addblock(&nd->bl);
- if( class_ >= 0 )
- {
+ if( class_ >= 0 ) {
status_set_viewdata(&nd->bl, nd->class_);
if( map[nd->bl.m].users )
clif->spawn(&nd->bl);
}
- }
- else
- {
+ } else {
// we skip map_addnpc, but still add it to the list of ID's
map_addiddb(&nd->bl);
}
@@ -2576,13 +2561,10 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
type = dnd->subtype;
// get placement
- if( (type==SHOP || type==CASHSHOP || type==SCRIPT) && strcmp(w1, "-") == 0 )
- {// floating shop/chashshop/script
+ if( (type==SHOP || type==CASHSHOP || type==SCRIPT) && strcmp(w1, "-") == 0 ) {// floating shop/chashshop/script
x = y = dir = 0;
m = -1;
- }
- else
- {
+ } else {
if( sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 )// <map name>,<x>,<y>,<facing>
{
ShowError("npc_parse_duplicate: Invalid placement format for duplicate in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
@@ -2599,8 +2581,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
if( type == WARP && sscanf(w4, "%d,%d", &xs, &ys) == 2 );// <spanx>,<spany>
else if( type == SCRIPT && sscanf(w4, "%d,%d,%d", &class_, &xs, &ys) == 3);// <sprite id>,<triggerX>,<triggerY>
else if( type != WARP ) class_ = atoi(w4);// <sprite id>
- else
- {
+ else {
ShowError("npc_parse_duplicate: Invalid span format for duplicate warp in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
return end;// next line, try to continue
}
@@ -2618,56 +2599,50 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
nd->src_id = src_id;
nd->bl.type = BL_NPC;
nd->subtype = (enum npc_subtype)type;
- switch( type )
- {
- case SCRIPT:
- ++npc_script;
- nd->u.scr.xs = xs;
- nd->u.scr.ys = ys;
- nd->u.scr.script = dnd->u.scr.script;
- nd->u.scr.label_list = dnd->u.scr.label_list;
- nd->u.scr.label_list_num = dnd->u.scr.label_list_num;
- break;
-
- case SHOP:
- case CASHSHOP:
- ++npc_shop;
- nd->u.shop.shop_item = dnd->u.shop.shop_item;
- nd->u.shop.count = dnd->u.shop.count;
- break;
-
- case WARP:
- ++npc_warp;
- if( !battle_config.warp_point_debug )
- nd->class_ = WARP_CLASS;
- else
- nd->class_ = WARP_DEBUG_CLASS;
- nd->u.warp.xs = xs;
- nd->u.warp.ys = ys;
- nd->u.warp.mapindex = dnd->u.warp.mapindex;
- nd->u.warp.x = dnd->u.warp.x;
- nd->u.warp.y = dnd->u.warp.y;
- break;
+ switch( type ) {
+ case SCRIPT:
+ ++npc_script;
+ nd->u.scr.xs = xs;
+ nd->u.scr.ys = ys;
+ nd->u.scr.script = dnd->u.scr.script;
+ nd->u.scr.label_list = dnd->u.scr.label_list;
+ nd->u.scr.label_list_num = dnd->u.scr.label_list_num;
+ break;
+
+ case SHOP:
+ case CASHSHOP:
+ ++npc_shop;
+ nd->u.shop.shop_item = dnd->u.shop.shop_item;
+ nd->u.shop.count = dnd->u.shop.count;
+ break;
+
+ case WARP:
+ ++npc_warp;
+ if( !battle_config.warp_point_debug )
+ nd->class_ = WARP_CLASS;
+ else
+ nd->class_ = WARP_DEBUG_CLASS;
+ nd->u.warp.xs = xs;
+ nd->u.warp.ys = ys;
+ nd->u.warp.mapindex = dnd->u.warp.mapindex;
+ nd->u.warp.x = dnd->u.warp.x;
+ nd->u.warp.y = dnd->u.warp.y;
+ break;
}
//Add the npc to its location
- if( m >= 0 )
- {
+ if( m >= 0 ) {
map_addnpc(m, nd);
- status_change_init(&nd->bl);
- unit_dataset(&nd->bl);
- nd->ud.dir = dir;
+ nd->ud = &npc_base_ud;
+ nd->dir = dir;
npc_setcells(nd);
map_addblock(&nd->bl);
- if( class_ >= 0 )
- {
+ if( class_ >= 0 ) {
status_set_viewdata(&nd->bl, nd->class_);
if( map[nd->bl.m].users )
clif->spawn(&nd->bl);
}
- }
- else
- {
+ } else {
// we skip map_addnpc, but still add it to the list of ID's
map_addiddb(&nd->bl);
}
@@ -2694,25 +2669,21 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
int npc_duplicate4instance(struct npc_data *snd, int16 m) {
char newname[NAME_LENGTH];
- if( map[m].instance_id == 0 )
+ if( map[m].instance_id == -1 )
return 1;
snprintf(newname, ARRAYLENGTH(newname), "dup_%d_%d", map[m].instance_id, snd->bl.id);
- if( npc_name2id(newname) != NULL )
- { // Name already in use
+ if( npc_name2id(newname) != NULL ) { // Name already in use
ShowError("npc_duplicate4instance: the npcname (%s) is already in use while trying to duplicate npc %s in instance %d.\n", newname, snd->exname, map[m].instance_id);
return 1;
}
- if( snd->subtype == WARP )
- { // Adjust destination, if instanced
+ if( snd->subtype == WARP ) { // Adjust destination, if instanced
struct npc_data *wnd = NULL; // New NPC
int dm = map_mapindex2mapid(snd->u.warp.mapindex), im;
if( dm < 0 ) return 1;
- im = instance_mapid2imapid(dm, map[m].instance_id);
- if( im == -1 )
- {
+ if( ( im = instance->mapid2imapid(dm, map[m].instance_id) ) == -1 ) {
ShowError("npc_duplicate4instance: warp (%s) leading to instanced map (%s), but instance map is not attached to current instance.\n", map[dm].name, snd->exname);
return 1;
}
@@ -2738,18 +2709,15 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
npc_setcells(wnd);
map_addblock(&wnd->bl);
status_set_viewdata(&wnd->bl, wnd->class_);
- status_change_init(&wnd->bl);
- unit_dataset(&wnd->bl);
+ wnd->ud = &npc_base_ud;
if( map[wnd->bl.m].users )
clif->spawn(&wnd->bl);
strdb_put(npcname_db, wnd->exname, wnd);
- }
- else
- {
+ } else {
static char w1[50], w2[50], w3[50], w4[50];
const char* stat_buf = "- call from instancing subsystem -\n";
- snprintf(w1, sizeof(w1), "%s,%d,%d,%d", map[m].name, snd->bl.x, snd->bl.y, snd->ud.dir);
+ snprintf(w1, sizeof(w1), "%s,%d,%d,%d", map[m].name, snd->bl.x, snd->bl.y, snd->dir);
snprintf(w2, sizeof(w2), "duplicate(%s)", snd->exname);
snprintf(w3, sizeof(w3), "%s::%s", snd->name, newname);
@@ -2765,39 +2733,36 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
}
//Set mapcell CELL_NPC to trigger event later
-void npc_setcells(struct npc_data* nd)
-{
+void npc_setcells(struct npc_data* nd) {
int16 m = nd->bl.m, x = nd->bl.x, y = nd->bl.y, xs, ys;
int i,j;
- switch(nd->subtype)
- {
- case WARP:
- xs = nd->u.warp.xs;
- ys = nd->u.warp.ys;
- break;
- case SCRIPT:
- xs = nd->u.scr.xs;
- ys = nd->u.scr.ys;
- break;
- default:
- return; // Other types doesn't have touch area
+ switch(nd->subtype) {
+ case WARP:
+ xs = nd->u.warp.xs;
+ ys = nd->u.warp.ys;
+ break;
+ case SCRIPT:
+ xs = nd->u.scr.xs;
+ ys = nd->u.scr.ys;
+ break;
+ default:
+ return; // Other types doesn't have touch area
}
- if (m < 0 || xs < 0 || ys < 0) //invalid range or map
+ if (m < 0 || xs < 0 || ys < 0 || map[m].cell == (struct mapcell *)0xdeadbeaf) //invalid range or map
return;
for (i = y-ys; i <= y+ys; i++) {
for (j = x-xs; j <= x+xs; j++) {
if (map_getcell(m, j, i, CELL_CHKNOPASS))
continue;
- map_setcell(m, j, i, CELL_NPC, true);
+ map[m].setcell(m, j, i, CELL_NPC, true);
}
}
}
-int npc_unsetcells_sub(struct block_list* bl, va_list ap)
-{
+int npc_unsetcells_sub(struct block_list* bl, va_list ap) {
struct npc_data *nd = (struct npc_data*)bl;
int id = va_arg(ap,int);
if (nd->bl.id == id) return 0;
@@ -2805,8 +2770,7 @@ int npc_unsetcells_sub(struct block_list* bl, va_list ap)
return 1;
}
-void npc_unsetcells(struct npc_data* nd)
-{
+void npc_unsetcells(struct npc_data* nd) {
int16 m = nd->bl.m, x = nd->bl.x, y = nd->bl.y, xs, ys;
int i,j, x0, x1, y0, y1;
@@ -2818,7 +2782,7 @@ void npc_unsetcells(struct npc_data* nd)
ys = nd->u.scr.ys;
}
- if (m < 0 || xs < 0 || ys < 0)
+ if (m < 0 || xs < 0 || ys < 0 || map[m].cell == (struct mapcell *)0xdeadbeaf)
return;
//Locate max range on which we can locate npc cells
@@ -2831,7 +2795,7 @@ void npc_unsetcells(struct npc_data* nd)
//Erase this npc's cells
for (i = y-ys; i <= y+ys; i++)
for (j = x-xs; j <= x+xs; j++)
- map_setcell(m, j, i, CELL_NPC, false);
+ map[m].setcell(m, j, i, CELL_NPC, false);
//Re-deploy NPC cells for other nearby npcs.
map_foreachinarea( npc_unsetcells_sub, m, x0, y0, x1, y1, BL_NPC, nd->bl.id );
@@ -2910,7 +2874,7 @@ int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const c
return 1;
}
- if( ev->nd->sc.option&OPTION_INVISIBLE ) { // Disabled npc, shouldn't trigger event.
+ if( ev->nd->option&OPTION_INVISIBLE ) { // Disabled npc, shouldn't trigger event.
npc_event_dequeue(sd);
return 2;
}
@@ -2994,8 +2958,7 @@ void npc_parse_mob2(struct spawn_data* mob)
{
int i;
- for( i = mob->active; i < mob->num; ++i )
- {
+ for( i = mob->active; i < mob->num; ++i ) {
struct mob_data* md = mob_spawn_dataset(mob);
md->spawn = mob;
md->spawn->active++;
@@ -3150,19 +3113,17 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
memcpy(data, &mob, sizeof(struct spawn_data));
// spawn / cache the new mobs
- if( battle_config.dynamic_mobs && map_addmobtolist(data->m, data) >= 0 )
- {
+ if( battle_config.dynamic_mobs && map_addmobtolist(data->m, data) >= 0 ) {
data->state.dynamic = true;
npc_cache_mob += data->num;
// check if target map has players
// (usually shouldn't occur when map server is just starting,
// but not the case when we do @reloadscript
- if( map[data->m].users > 0 )
+ if( map[data->m].users > 0 ) {
npc_parse_mob2(data);
- }
- else
- {
+ }
+ } else {
data->state.dynamic = false;
npc_parse_mob2(data);
npc_delay_mob += data->num;
@@ -3282,16 +3243,11 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
else if (!strcmpi(drop_arg2,"all"))
drop_type = 3;
- if (drop_id != 0){
- int i;
- for (i = 0; i < MAX_DROP_PER_MAP; i++) {
- if (map[m].drop_list[i].drop_id == 0){
- map[m].drop_list[i].drop_id = drop_id;
- map[m].drop_list[i].drop_type = drop_type;
- map[m].drop_list[i].drop_per = drop_per;
- break;
- }
- }
+ if (drop_id != 0) {
+ RECREATE(map[m].drop_list, struct map_drop_list, ++map[m].drop_list_count);
+ map[m].drop_list[map[m].drop_list_count-1].drop_id = drop_id;
+ map[m].drop_list[map[m].drop_list_count-1].drop_type = drop_type;
+ map[m].drop_list[map[m].drop_list_count-1].drop_per = drop_per;
map[m].flag.pvp_nightmaredrop = 1;
}
} else if (!state) //Disable
@@ -3892,10 +3848,7 @@ int npc_reload(void) {
"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
- do_final_instance();
-
- for( i = 0; i < ARRAYLENGTH(instance); ++i )
- instance_init(instance[i].instance_id);
+ instance->final();
map_zone_init();
@@ -4002,8 +3955,18 @@ int do_init_npc(void)
struct npc_src_list *file;
int i;
+ memset(&npc_base_ud, 0, sizeof( struct unit_data) );
+ npc_base_ud.bl = NULL;
+ npc_base_ud.walktimer = INVALID_TIMER;
+ npc_base_ud.skilltimer = INVALID_TIMER;
+ npc_base_ud.attacktimer = INVALID_TIMER;
+ npc_base_ud.attackabletime =
+ npc_base_ud.canact_tick =
+ npc_base_ud.canmove_tick = gettick();
+
//Stock view data for normal npcs.
memset(&npc_viewdb, 0, sizeof(npc_viewdb));
+
npc_viewdb[0].class_ = INVISIBLE_CLASS; //Invisible class is stored here.
for( i = 1; i < MAX_NPC_CLASS; i++ )
npc_viewdb[i].class_ = i;
@@ -4030,7 +3993,7 @@ int do_init_npc(void)
"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n"
"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
-
+
map_zone_init();
npc->motd = npc_name2id("HerculesMOTD"); /* [Ind/Hercules] */
@@ -4068,6 +4031,6 @@ int do_init_npc(void)
}
void npc_defaults(void) {
npc = &npc_s;
-
+
npc->motd = NULL;
}