summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorKenpachi Developer <Kenpachi.Developer@gmx.de>2019-11-27 02:50:08 +0100
committerHaru <haru@dotalux.com>2020-02-09 20:19:12 +0100
commit30c175a9041a17e0d2ef1d4750163c19ab3a7959 (patch)
tree8d4accec56aa49efaf40e2e4d3b8ac40a03f0259 /src/map
parentc76c63d2dddb8c7ec4461dd660b7bb0210f4db96 (diff)
downloadhercules-30c175a9041a17e0d2ef1d4750163c19ab3a7959.tar.gz
hercules-30c175a9041a17e0d2ef1d4750163c19ab3a7959.tar.bz2
hercules-30c175a9041a17e0d2ef1d4750163c19ab3a7959.tar.xz
hercules-30c175a9041a17e0d2ef1d4750163c19ab3a7959.zip
Change unload NPC behavior to kill mobs that were spawned by unloaded NPC (non-permanent monster spawns) [Issue #2530]
Mobs spawned by NPC will be removed on @reloadnpc, @unloadnpc, and @unloadnpcfile. Additionally OnNPCUnload NPC label was added, to revert other changes made by NPC. For example set/removed mapflags or added mob drops.
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.c42
-rw-r--r--src/map/clif.c4
-rw-r--r--src/map/instance.c2
-rw-r--r--src/map/map.c2
-rw-r--r--src/map/mob.c21
-rw-r--r--src/map/mob.h9
-rw-r--r--src/map/npc.c51
-rw-r--r--src/map/npc.h7
-rw-r--r--src/map/script.c6
-rw-r--r--src/map/skill.c12
10 files changed, 97 insertions, 59 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 5d95e2c14..7bc10edf0 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -4487,11 +4487,12 @@ ACMD(unloadnpc)
{
struct npc_data *nd;
char NPCname[NAME_LENGTH+1];
+ short flag = 1;
memset(NPCname, '\0', sizeof(NPCname));
- if (!*message || sscanf(message, "%24[^\n]", NPCname) < 1) {
- clif->message(fd, msg_fd(fd,1133)); // Please enter a NPC name (usage: @npcoff <NPC_name>).
+ if (!*message || sscanf(message, "%24s %5hd", NPCname, &flag) < 1) {
+ clif->message(fd, msg_fd(fd, 1133)); // Please enter a NPC name (Usage: @unloadnpc <NPC_name> {<flag>}).
return false;
}
@@ -4500,24 +4501,28 @@ ACMD(unloadnpc)
return false;
}
- npc->unload_duplicates(nd);
- npc->unload(nd,true);
+ npc->unload_duplicates(nd, (flag != 0));
+ npc->unload(nd, true, (flag != 0));
npc->read_event_script();
clif->message(fd, msg_fd(fd,112)); // Npc Disabled.
return true;
}
/// Unload existing NPC within the NPC file and reload it.
-/// Usage: @reloadnpc npc/sample_npc.txt
+/// Usage: @reloadnpc npc/sample_npc.txt {flag}
+/// Note: Be aware that some changes made by NPC are not reverted on unload. See doc/atcommands.txt for details.
ACMD(reloadnpc)
{
- if (!*message) {
- clif->message(fd, msg_fd(fd, 1385)); // Usage: @unloadnpcfile <file name>
+ char file_path[100];
+ short flag = 1;
+
+ if (!*message || (sscanf(message, "%99s %5hd", file_path, &flag) < 1)) {
+ clif->message(fd, msg_fd(fd, 1516)); // Usage: @reloadnpc <path> {<flag>}
return false;
- } else if (npc->unloadfile(message) == true) {
- clif->message(fd, msg_fd(fd, 1386)); // File unloaded. Be aware that mapflags and monsters spawned directly are not removed.
+ } else if (npc->unloadfile(file_path, (flag != 0)) == true) {
+ clif->message(fd, msg_fd(fd, 1386)); // File unloaded. Be aware that...
- FILE *fp = fopen(message, "r");
+ FILE *fp = fopen(file_path, "r");
// check if script file exists
if (fp == NULL) {
clif->message(fd, msg_fd(fd, 261));
@@ -4526,8 +4531,8 @@ ACMD(reloadnpc)
fclose(fp);
// add to list of script sources and run it
- npc->addsrcfile(message);
- npc->parsesrcfile(message, true);
+ npc->addsrcfile(file_path);
+ npc->parsesrcfile(file_path, true);
npc->read_event_script();
clif->message(fd, msg_fd(fd, 262));
@@ -6603,7 +6608,7 @@ ACMD(summon)
return false;
}
- md = mob->once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, DEFAULT_MOB_JNAME, mob_id, "", SZ_SMALL, AI_NONE);
+ md = mob->once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, DEFAULT_MOB_JNAME, mob_id, "", SZ_SMALL, AI_NONE, 0);
if(!md)
return false;
@@ -9011,13 +9016,16 @@ ACMD(addperm)
ACMD(unloadnpcfile)
{
- if (!*message) {
- clif->message(fd, msg_fd(fd,1385)); // Usage: @unloadnpcfile <file name>
+ char file_path[100];
+ short flag = 1;
+
+ if (!*message || (sscanf(message, "%99s %5hd", file_path, &flag) < 1)) {
+ clif->message(fd, msg_fd(fd, 1385)); // Usage: @unloadnpcfile <path> {<flag>}
return false;
}
- if (npc->unloadfile(message)) {
- clif->message(fd, msg_fd(fd,1386)); // File unloaded. Be aware that mapflags and monsters spawned directly are not removed.
+ if (npc->unloadfile(file_path, (flag != 0))) {
+ clif->message(fd, msg_fd(fd, 1386)); // File unloaded. Be aware that...
} else {
clif->message(fd, msg_fd(fd,1387)); // File not found.
return false;
diff --git a/src/map/clif.c b/src/map/clif.c
index 942e492c2..1223d2b7e 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -15273,8 +15273,8 @@ static void clif_parse_GMKick(int fd, struct map_session_data *sd)
clif->GM_kickack(sd, 0);
return;
}
- npc->unload_duplicates(nd);
- npc->unload(nd,true);
+ npc->unload_duplicates(nd, true);
+ npc->unload(nd, true, true);
npc->read_event_script();
}
break;
diff --git a/src/map/instance.c b/src/map/instance.c
index 90f2217b1..1104b7e88 100644
--- a/src/map/instance.c
+++ b/src/map/instance.c
@@ -446,7 +446,7 @@ static int instance_cleanup_sub(struct block_list *bl, va_list ap)
map->quit(BL_UCAST(BL_PC, bl));
break;
case BL_NPC:
- npc->unload(BL_UCAST(BL_NPC, bl), true);
+ npc->unload(BL_UCAST(BL_NPC, bl), true, true);
break;
case BL_MOB:
unit->free(bl,CLR_OUTSIGHT);
diff --git a/src/map/map.c b/src/map/map.c
index 9a45c4d21..8b52fc761 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -6092,7 +6092,7 @@ static int cleanup_sub(struct block_list *bl, va_list ap)
map->quit(BL_UCAST(BL_PC, bl));
break;
case BL_NPC:
- npc->unload(BL_UCAST(BL_NPC, bl), false);
+ npc->unload(BL_UCAST(BL_NPC, bl), false, true);
break;
case BL_MOB:
unit->free(bl,CLR_OUTSIGHT);
diff --git a/src/map/mob.c b/src/map/mob.c
index 4b74abc8f..8495dfa06 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -340,7 +340,7 @@ static int mob_parse_dataset(struct spawn_data *data)
/*==========================================
* Generates the basic mob data using the spawn_data provided.
*------------------------------------------*/
-static struct mob_data *mob_spawn_dataset(struct spawn_data *data)
+static struct mob_data *mob_spawn_dataset(struct spawn_data *data, int npc_id)
{
struct mob_data *md = NULL;
nullpo_retr(NULL, data);
@@ -364,6 +364,7 @@ static struct mob_data *mob_spawn_dataset(struct spawn_data *data)
memcpy(md->npc_event, data->eventname, 50);
if(md->db->status.mode&MD_LOOTER)
md->lootitem = (struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item));
+ md->npc_id = npc_id;
md->spawn_timer = INVALID_TIMER;
md->deletetimer = INVALID_TIMER;
md->skill_idx = -1;
@@ -503,7 +504,7 @@ static bool mob_ksprotected(struct block_list *src, struct block_list *target)
return false;
}
-static struct mob_data *mob_once_spawn_sub(struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai)
+static struct mob_data *mob_once_spawn_sub(struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai, int npc_id)
{
struct spawn_data data;
@@ -538,7 +539,7 @@ static struct mob_data *mob_once_spawn_sub(struct block_list *bl, int16 m, int16
if (!mob->parse_dataset(&data))
return NULL;
- return mob->spawn_dataset(&data);
+ return mob->spawn_dataset(&data, npc_id);
}
/*==========================================
@@ -562,7 +563,7 @@ static int mob_once_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y
for (count = 0; count < amount; count++) {
int c = (class_ >= 0) ? class_ : mob->get_random_id(-class_ - 1, (battle_config.random_monster_checklv) ? 3 : 1, lv);
- md = mob->once_spawn_sub((sd) ? &sd->bl : NULL, m, x, y, mobname, c, event, size, ai);
+ md = mob->once_spawn_sub((sd != NULL) ? &sd->bl : NULL, m, x, y, mobname, c, event, size, ai, (sd != NULL) ? sd->npc_id : 0);
if (!md)
continue;
@@ -698,7 +699,7 @@ static int mob_spawn_guardian_sub(int tid, int64 tick, int id, intptr_t data)
/*==========================================
* Summoning Guardians [Valaris]
*------------------------------------------*/
-static int mob_spawn_guardian(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index)
+static int mob_spawn_guardian(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index, int npc_id)
{
struct mob_data *md=NULL;
struct spawn_data data;
@@ -767,7 +768,7 @@ static int mob_spawn_guardian(const char *mapname, short x, short y, const char
}
}
- md = mob->spawn_dataset(&data);
+ md = mob->spawn_dataset(&data, npc_id);
md->guardian_data = (struct guardian_data*)aCalloc(1, sizeof(struct guardian_data));
md->guardian_data->number = guardian;
md->guardian_data->castle = gc;
@@ -798,7 +799,7 @@ static int mob_spawn_guardian(const char *mapname, short x, short y, const char
/*==========================================
* Summoning BattleGround [Zephyrus]
*------------------------------------------*/
-static int mob_spawn_bg(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id)
+static int mob_spawn_bg(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id, int npc_id)
{
struct mob_data *md = NULL;
struct spawn_data data;
@@ -835,7 +836,7 @@ static int mob_spawn_bg(const char *mapname, short x, short y, const char *mobna
if( !mob->parse_dataset(&data) )
return 0;
- md = mob->spawn_dataset(&data);
+ md = mob->spawn_dataset(&data, npc_id);
mob->spawn(md);
md->bg_id = bg_id; // BG Team ID
@@ -3161,7 +3162,7 @@ static int mob_summonslave(struct mob_data *md2, int *value, int amount, uint16
if (!mob->parse_dataset(&data))
continue;
- md= mob->spawn_dataset(&data);
+ md = mob->spawn_dataset(&data, 0);
if(skill_id == NPC_SUMMONSLAVE){
md->master_id=md2->bl.id;
md->special_state.ai = md2->special_state.ai;
@@ -3773,7 +3774,7 @@ static int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16
sd->fd = fd;
//Finally, spawn it.
- md = mob->once_spawn_sub(&sd->bl, m, x, y, DEFAULT_MOB_NAME, class_, event, SZ_SMALL, AI_NONE);
+ md = mob->once_spawn_sub(&sd->bl, m, x, y, DEFAULT_MOB_NAME, class_, event, SZ_SMALL, AI_NONE, 0);
if (!md) return 0; //Failed?
md->special_state.clone = 1;
diff --git a/src/map/mob.h b/src/map/mob.h
index 8fd16f191..8839809f2 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -255,6 +255,7 @@ struct mob_data {
int areanpc_id; //Required in OnTouchNPC (to avoid multiple area touchs)
unsigned int bg_id; // BattleGround System
int clan_id; // Clan System
+ int npc_id; // NPC ID if spawned with monster/areamonster/guardian/bg_monster/atcommand("@monster xy") (Used to kill mob on NPC unload.)
int64 next_walktime, last_thinktime, last_linktime, last_pcneartime, dmgtick;
short move_fail_count;
@@ -507,14 +508,14 @@ struct mob_interface {
int (*db_checkid) (const int id);
struct view_data* (*get_viewdata) (int class_);
int (*parse_dataset) (struct spawn_data *data);
- struct mob_data* (*spawn_dataset) (struct spawn_data *data);
+ struct mob_data* (*spawn_dataset) (struct spawn_data *data, int npc_id);
int (*get_random_id) (int type, int flag, int lv);
bool (*ksprotected) (struct block_list *src, struct block_list *target);
- struct mob_data* (*once_spawn_sub) (struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai);
+ struct mob_data* (*once_spawn_sub) (struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai, int npc_id);
int (*once_spawn) (struct map_session_data *sd, int16 m, int16 x, int16 y, const char *mobname, int class_, int amount, const char *event, unsigned int size, unsigned int ai);
int (*once_spawn_area) (struct map_session_data *sd, int16 m, int16 x0, int16 y0, int16 x1, int16 y1, const char *mobname, int class_, int amount, const char *event, unsigned int size, unsigned int ai);
- int (*spawn_guardian) (const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index);
- int (*spawn_bg) (const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id);
+ int (*spawn_guardian) (const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index, int npc_id);
+ int (*spawn_bg) (const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id, int npc_id);
int (*can_reach) (struct mob_data *md, struct block_list *bl, int range, int state);
int (*linksearch) (struct block_list *bl, va_list ap);
int (*delayspawn) (int tid, int64 tick, int id, intptr_t data);
diff --git a/src/map/npc.c b/src/map/npc.c
index 657fb987e..8aed1d2fc 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -2939,25 +2939,42 @@ static int npc_unload_ev_label(union DBKey key, struct DBData *data, va_list ap)
//Sub-function used to find duplicates.
static int npc_unload_dup_sub(struct npc_data *nd, va_list args)
{
- int src_id;
-
nullpo_ret(nd);
- src_id = va_arg(args, int);
+ int src_id = va_arg(args, int);
+ int unload_mobs = va_arg(args, int);
+
if (nd->src_id == src_id)
- npc->unload(nd, true);
+ npc->unload(nd, true, (unload_mobs == 1));
+
return 0;
}
//Removes all npcs that are duplicates of the passed one. [Skotlex]
-static void npc_unload_duplicates(struct npc_data *nd)
+static void npc_unload_duplicates(struct npc_data *nd, bool unload_mobs)
{
nullpo_retv(nd);
- map->foreachnpc(npc->unload_dup_sub,nd->bl.id);
+ // passing unload_mobs as int, because va_arg() would promote bool to int and cause compiler warnings
+ map->foreachnpc(npc->unload_dup_sub, nd->bl.id, unload_mobs ? 1 : 0);
+}
+
+//Removes mobs spawned by NPC (monster/areamonster/guardian/bg_monster/atcommand("@monster xy"))
+static int npc_unload_mob(struct mob_data *md, va_list args)
+{
+ nullpo_ret(md);
+ int npc_id = va_arg(args, int);
+
+ if (md->npc_id == npc_id) {
+ md->state.npc_killmonster = 1;
+ status_kill(&md->bl);
+ return 1;
+ }
+
+ return 0;
}
//Removes an npc from map and db.
//Single is to free name (for duplicates).
-static int npc_unload(struct npc_data *nd, bool single)
+static int npc_unload(struct npc_data *nd, bool single, bool unload_mobs)
{
nullpo_ret(nd);
@@ -2991,6 +3008,12 @@ static int npc_unload(struct npc_data *nd, bool single)
struct s_mapiterator *iter;
struct map_session_data *sd = NULL;
+ char evname[EVENT_NAME_LENGTH];
+ struct event_data *ev;
+ snprintf(evname, ARRAYLENGTH(evname), "%s::OnNPCUnload", nd->exname);
+ if ((ev = (struct event_data*)strdb_get(npc->ev_db, evname)) != NULL)
+ script->run_npc(nd->u.scr.script, ev->pos, 0, nd->bl.id); // Run OnNPCUnload
+
if( single ) {
npc->ev_db->foreach(npc->ev_db,npc->unload_ev,nd->exname); //Clean up all events related
npc->ev_label_db->foreach(npc->ev_label_db,npc->unload_ev_label,nd);
@@ -3051,6 +3074,9 @@ static int npc_unload(struct npc_data *nd, bool single)
nd->ud = NULL;
}
+ if (unload_mobs)
+ map->foreachmob(npc->unload_mob, nd->bl.id);
+
HPM->data_store_destroy(&nd->hdata);
aFree(nd);
@@ -4442,7 +4468,7 @@ static void npc_parse_mob2(struct spawn_data *mobspawn)
nullpo_retv(mobspawn);
for( i = mobspawn->active; i < mobspawn->num; ++i ) {
- struct mob_data* md = mob->spawn_dataset(mobspawn);
+ struct mob_data *md = mob->spawn_dataset(mobspawn, 0);
md->spawn = mobspawn;
md->spawn->active++;
mob->spawn(md);
@@ -5528,7 +5554,7 @@ static int npc_reload(void)
switch(bl->type) {
case BL_NPC:
if( bl->id != npc->fake_nd->bl.id )// don't remove fake_nd
- npc->unload(BL_UCAST(BL_NPC, bl), false);
+ npc->unload(BL_UCAST(BL_NPC, bl), false, false);
break;
case BL_MOB:
unit->free(bl,CLR_OUTSIGHT);
@@ -5603,7 +5629,7 @@ static int npc_reload(void)
}
//Unload all npc in the given file
-static bool npc_unloadfile(const char *filepath)
+static bool npc_unloadfile(const char *filepath, bool unload_mobs)
{
struct DBIterator *iter = db_iterator(npc->name_db);
struct npc_data* nd = NULL;
@@ -5614,8 +5640,8 @@ static bool npc_unloadfile(const char *filepath)
for( nd = dbi_first(iter); dbi_exists(iter); nd = dbi_next(iter) ) {
if( nd->path && strcasecmp(nd->path,filepath) == 0 ) { // FIXME: This can break in case-sensitive file systems
found = true;
- npc->unload_duplicates(nd);/* unload any npcs which could duplicate this but be in a different file */
- npc->unload(nd, true);
+ npc->unload_duplicates(nd, unload_mobs);/* unload any npcs which could duplicate this but be in a different file */
+ npc->unload(nd, true, unload_mobs);
}
}
@@ -5854,6 +5880,7 @@ void npc_defaults(void)
npc->unload_ev_label = npc_unload_ev_label;
npc->unload_dup_sub = npc_unload_dup_sub;
npc->unload_duplicates = npc_unload_duplicates;
+ npc->unload_mob = npc_unload_mob;
npc->unload = npc_unload;
npc->clearsrcfile = npc_clearsrcfile;
npc->addsrcfile = npc_addsrcfile;
diff --git a/src/map/npc.h b/src/map/npc.h
index 392911046..65c9796d9 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -270,8 +270,9 @@ struct npc_interface {
int (*unload_ev) (union DBKey key, struct DBData *data, va_list ap);
int (*unload_ev_label) (union DBKey key, struct DBData *data, va_list ap);
int (*unload_dup_sub) (struct npc_data *nd, va_list args);
- void (*unload_duplicates) (struct npc_data *nd);
- int (*unload) (struct npc_data *nd, bool single);
+ void (*unload_duplicates) (struct npc_data *nd, bool unload_mobs);
+ int (*unload_mob) (struct mob_data *md, va_list args);
+ int (*unload) (struct npc_data *nd, bool single, bool unload_mobs);
void (*clearsrcfile) (void);
void (*addsrcfile) (const char *name);
void (*delsrcfile) (const char *name);
@@ -313,7 +314,7 @@ struct npc_interface {
int (*path_db_clear_sub) (union DBKey key, struct DBData *data, va_list args);
int (*ev_label_db_clear_sub) (union DBKey key, struct DBData *data, va_list args);
int (*reload) (void);
- bool (*unloadfile) (const char *filepath);
+ bool (*unloadfile) (const char *filepath, bool unload_mobs);
void (*do_clear_npc) (void);
void (*debug_warps_sub) (struct npc_data *nd);
void (*debug_warps) (void);
diff --git a/src/map/script.c b/src/map/script.c
index 1d5919d3b..fe8052c65 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -14565,7 +14565,7 @@ static BUILDIN(guardian)
}
script->check_event(st, evt);
- script_pushint(st, mob->spawn_guardian(mapname,x,y,str,class_,evt,guardian,has_index));
+ script_pushint(st, mob->spawn_guardian(mapname, x, y, str, class_, evt, guardian, has_index, st->oid));
return true;
}
@@ -16915,7 +16915,7 @@ static BUILDIN(summon)
clif->skill_poseffect(&sd->bl,AM_CALLHOMUN,1,sd->bl.x,sd->bl.y,tick);
- md = mob->once_spawn_sub(&sd->bl, sd->bl.m, sd->bl.x, sd->bl.y, str, class_, event, SZ_SMALL, AI_NONE);
+ md = mob->once_spawn_sub(&sd->bl, sd->bl.m, sd->bl.x, sd->bl.y, str, class_, event, SZ_SMALL, AI_NONE, 0);
if (md) {
md->master_id=sd->bl.id;
md->special_state.ai = AI_ATTACK;
@@ -22353,7 +22353,7 @@ static BUILDIN(bg_monster)
class_ = script_getnum(st,7);
if( script_hasdata(st,8) ) evt = script_getstr(st,8);
script->check_event(st, evt);
- script_pushint(st, mob->spawn_bg(mapname,x,y,str,class_,evt,bg_id));
+ script_pushint(st, mob->spawn_bg(mapname, x, y, str, class_, evt, bg_id, st->oid));
return true;
}
diff --git a/src/map/skill.c b/src/map/skill.c
index 09e216804..a488e3eaf 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -10417,7 +10417,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
if(sd) {
struct mob_data *summon_md;
- summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, clif->get_bl_name(src), MOBID_KO_KAGE, "", SZ_SMALL, AI_NONE);
+ summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, clif->get_bl_name(src), MOBID_KO_KAGE, "", SZ_SMALL, AI_NONE, 0);
if( summon_md ) {
summon_md->master_id = src->id;
summon_md->special_state.ai = AI_ZANZOU;
@@ -10600,7 +10600,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
for (i = 0; i < summons[skill_lv-1].quantity; i++) {
struct mob_data *summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, clif->get_bl_name(src),
- summons[skill_lv-1].mob_id, "", SZ_SMALL, AI_ATTACK);
+ summons[skill_lv-1].mob_id, "", SZ_SMALL, AI_ATTACK, 0);
if (summon_md != NULL) {
summon_md->master_id = src->id;
if (summon_md->deletetimer != INVALID_TIMER)
@@ -11383,7 +11383,7 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill
}
// Correct info, don't change any of this! [Celest]
- md = mob->once_spawn_sub(src, src->m, x, y, clif->get_bl_name(src), class_, "", SZ_SMALL, AI_NONE);
+ md = mob->once_spawn_sub(src, src->m, x, y, clif->get_bl_name(src), class_, "", SZ_SMALL, AI_NONE, 0);
if (md) {
md->master_id = src->id;
md->special_state.ai = (skill_id == AM_SPHEREMINE) ? AI_SPHERE : AI_FLORA;
@@ -11485,7 +11485,7 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill
clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0);
} else {
int mob_id = skill_lv < 2 ? MOBID_BLACK_MUSHROOM + rnd()%2 : MOBID_RED_PLANT + rnd()%6;
- struct mob_data *md = mob->once_spawn_sub(src, src->m, x, y, DEFAULT_MOB_JNAME, mob_id, "", SZ_SMALL, AI_NONE);
+ struct mob_data *md = mob->once_spawn_sub(src, src->m, x, y, DEFAULT_MOB_JNAME, mob_id, "", SZ_SMALL, AI_NONE, 0);
int i;
if (md == NULL)
break;
@@ -11631,7 +11631,7 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill
case NC_SILVERSNIPER:
{
- struct mob_data *md = mob->once_spawn_sub(src, src->m, x, y, clif->get_bl_name(src), MOBID_SILVERSNIPER, "", SZ_SMALL, AI_NONE);
+ struct mob_data *md = mob->once_spawn_sub(src, src->m, x, y, clif->get_bl_name(src), MOBID_SILVERSNIPER, "", SZ_SMALL, AI_NONE, 0);
if (md) {
md->master_id = src->id;
md->special_state.ai = AI_FLORA;
@@ -18793,7 +18793,7 @@ static int skill_magicdecoy(struct map_session_data *sd, int nameid)
break;
}
- md = mob->once_spawn_sub(&sd->bl, sd->bl.m, x, y, sd->status.name, class_, "", SZ_SMALL, AI_NONE);
+ md = mob->once_spawn_sub(&sd->bl, sd->bl.m, x, y, sd->status.name, class_, "", SZ_SMALL, AI_NONE, 0);
if( md ) {
md->master_id = sd->bl.id;
md->special_state.ai = AI_FLORA;