summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/script_commands.txt20
-rw-r--r--src/map/atcommand.c11
-rw-r--r--src/map/map.h23
-rw-r--r--src/map/mob.c95
-rw-r--r--src/map/mob.h27
-rw-r--r--src/map/npc.c9
-rw-r--r--src/map/npc.h1
-rw-r--r--src/map/script.c122
-rw-r--r--src/map/skill.c20
9 files changed, 179 insertions, 149 deletions
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index bcb632443..7d893f75d 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -5201,8 +5201,8 @@ Example(s):
==================================
---------------------------------------
-*monster "<map name>",<x>,<y>,"<name to show>",<mob id>,<amount>{,"<event label>"};
-*areamonster "<map name>",<x1>,<y1>,<x2>,<y2>,"<name to show>",<mob id>,<amount>{,"<event label>"};
+*monster "<map name>",<x>,<y>,"<name to show>",<mob id>,<amount>{,"<event label>",<size>,<ai>};
+*areamonster "<map name>",<x1>,<y1>,<x2>,<y2>,"<name to show>",<mob id>,<amount>{,"<event label>",<size>,<ai>};
This command will spawn a monster on the specified coordinates on the specified
map. If the script is invoked by a character, a special map name, "this", will
@@ -5224,11 +5224,17 @@ and upon the monster being killed, it will execute the script inside of the
specified NPC object starting from the label given. The RID of the player
attached at this execution will be the RID of the killing character.
-The Event field can be used alternatively to specify other mob properties. Use
-2 to specify that the mob should be small, 4 for big monsters, and 8 for
-special ai mobs (which by default attack other monsters instead of players).
-You can add these, so using 10 will spawn small monsters that attack other
-mobs (if you specify both 2 and 4, the small version takes priority).
+<size> can be:
+ 0 = medium (default)
+ 1 = small
+ 2 = big
+
+<ai> can be:
+ 0 = none (default)
+ 1 = attack/friendly
+ 2 = sphere (Alchemist skill)
+ 3 = flora (Alchemist skill)
+ 4 = zanzou (Kagerou/Oboro skill)
monster "place",60,100,"Poring",1002,1,"NPCNAME::OnLabel";
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index ab7e41c3f..2f54b110e 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -2077,6 +2077,7 @@ ACMD_FUNC(monster)
int count;
int i, k, range;
short mx, my;
+ unsigned int size;
nullpo_retr(-1, sd);
memset(name, '\0', sizeof(name));
@@ -2128,9 +2129,11 @@ ACMD_FUNC(monster)
number = battle_config.atc_spawn_quantity_limit;
if (strcmp(command+1, "monstersmall") == 0)
- strcpy(eventname, "2");
+ size = SZ_MEDIUM; // This is just gorgeous [mkbu95]
else if (strcmp(command+1, "monsterbig") == 0)
- strcpy(eventname, "4");
+ size = SZ_BIG;
+ else
+ size = SZ_SMALL;
if (battle_config.etc_log)
ShowInfo("%s monster='%s' name='%s' id=%d count=%d (%d,%d)\n", command, monster, name, mob_id, number, sd->bl.x, sd->bl.y);
@@ -2139,7 +2142,7 @@ ACMD_FUNC(monster)
range = (int)sqrt((float)number) +2; // calculation of an odd number (+ 4 area around)
for (i = 0; i < number; i++) {
map_search_freecell(&sd->bl, 0, &mx, &my, range, range, 0);
- k = mob_once_spawn(sd, sd->bl.m, mx, my, name, mob_id, 1, eventname);
+ k = mob_once_spawn(sd, sd->bl.m, mx, my, name, mob_id, 1, eventname, size, AI_NONE);
count += (k != 0) ? 1 : 0;
}
@@ -6368,7 +6371,7 @@ ACMD_FUNC(summon)
return -1;
}
- md = mob_once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, "--ja--", mob_id, "");
+ md = mob_once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, "--ja--", mob_id, "", SZ_SMALL, AI_NONE);
if(!md)
return -1;
diff --git a/src/map/map.h b/src/map/map.h
index 43bef63af..24753d058 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -319,23 +319,22 @@ struct block_list {
// Expanded to specify all mob-related spawn data by [Skotlex]
struct spawn_data {
short class_; //Class, used because a mob can change it's class
- unsigned short m,x,y; //Spawn information (map, point, spawn-area around point)
- signed short xs,ys;
+ unsigned short m, x, y; //Spawn information (map, point, spawn-area around point)
+ signed short xs, ys;
unsigned short num; //Number of mobs using this structure
- unsigned short active; //Number of mobs that are already spawned (for mob_remove_damaged: no)
- unsigned int delay1,delay2; //Spawn delay (fixed base + random variance)
+ unsigned short active;//Number of mobs that are already spawned (for mob_remove_damaged: no)
+ unsigned int delay1, delay2; //Spawn delay (fixed base + random variance)
struct {
- unsigned int size :2; //Holds if mob has to be tiny/large
- unsigned int ai :2; //Holds if mob is special ai.
- unsigned int dynamic :1; //Whether this data is indexed by a map's dynamic mob list
- unsigned int boss : 1;
+ unsigned int size : 2; //Holds if mob has to be tiny/large
+ unsigned int ai : 4; //Special ai for summoned monsters.
+ //0: Normal mob | 1: Standard summon, attacks mobs
+ //2: Alchemist Marine Sphere | 3: Alchemist Summon Flora | 4: Summon Zanzou
+ unsigned int dynamic : 1; //Whether this data is indexed by a map's dynamic mob list
+ unsigned int boss : 1; //0: Non-boss monster | 1: Boss monster
} state;
- char name[NAME_LENGTH],eventname[EVENT_NAME_LENGTH]; //Name/event
+ char name[NAME_LENGTH], eventname[EVENT_NAME_LENGTH]; //Name/event
};
-
-
-
struct flooritem_data {
struct block_list bl;
unsigned char subx,suby;
diff --git a/src/map/mob.c b/src/map/mob.c
index 3c485ee58..fe174ba22 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -240,34 +240,10 @@ int mob_parse_dataset(struct spawn_data *data)
{
size_t len;
- //FIXME: This implementation is not stable, npc scripts will stop working once MAX_MOB_DB changes value! [Skotlex]
- if(data->class_ > 2*MAX_MOB_DB){ // large/tiny mobs [Valaris]
- data->state.size=SZ_BIG;
- data->class_ -= 2*MAX_MOB_DB;
- } else if (data->class_ > MAX_MOB_DB) {
- data->state.size=SZ_MEDIUM;
- data->class_ -= MAX_MOB_DB;
- }
-
if ((!mobdb_checkid(data->class_) && !mob_is_clone(data->class_)) || !data->num)
return 0;
- if( npc_event_isspecial(data->eventname) )
- {//Portable monster big/small implementation. [Skotlex]
- int i = atoi(data->eventname);
-
- if( i )
- {
- if( i&2 )
- data->state.size = SZ_MEDIUM;
- else if( i&4 )
- data->state.size = SZ_BIG;
- if( i&8 )
- data->state.ai = 1;
- }
- data->eventname[0] = '\0'; //Clear event as it is not used.
- }
- else if( ( len = strlen(data->eventname) ) > 0 )
+ if( ( len = strlen(data->eventname) ) > 0 )
{
if( data->eventname[len-1] == '"' )
data->eventname[len-1] = '\0'; //Remove trailing quote.
@@ -442,7 +418,7 @@ bool mob_ksprotected (struct block_list *src, struct block_list *target)
return false;
}
-struct mob_data *mob_once_spawn_sub(struct block_list *bl, int m, short x, short y, const char *mobname, int class_, const char *event)
+struct mob_data *mob_once_spawn_sub(struct block_list *bl, int m, short x, short y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai)
{
struct spawn_data data;
@@ -450,13 +426,16 @@ struct mob_data *mob_once_spawn_sub(struct block_list *bl, int m, short x, short
data.m = m;
data.num = 1;
data.class_ = class_;
+ data.state.size = size;
+ data.state.ai = ai;
+
if (mobname)
safestrncpy(data.name, mobname, sizeof(data.name));
else
- if(battle_config.override_mob_names==1)
- strcpy(data.name,"--en--");
- else
- strcpy(data.name,"--ja--");
+ if (battle_config.override_mob_names == 1)
+ strcpy(data.name, "--en--");
+ else
+ strcpy(data.name, "--ja--");
if (event)
safestrncpy(data.eventname, event, sizeof(data.eventname));
@@ -481,7 +460,7 @@ struct mob_data *mob_once_spawn_sub(struct block_list *bl, int m, short x, short
/*==========================================
* Spawn a single mob on the specified coordinates.
*------------------------------------------*/
-int mob_once_spawn(struct map_session_data* sd, int m, short x, short y, const char* mobname, int class_, int amount, const char* event)
+int mob_once_spawn(struct map_session_data* sd, int m, short x, short y, const char* mobname, int class_, int amount, const char* event, unsigned int size, unsigned int ai)
{
struct mob_data* md = NULL;
int count, lv;
@@ -489,22 +468,22 @@ int mob_once_spawn(struct map_session_data* sd, int m, short x, short y, const c
if (m < 0 || amount <= 0)
return 0; // invalid input
- if(sd)
- lv = sd->status.base_level;
- else
- lv = 255;
+ lv = (sd) ? sd->status.base_level : 255;
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);
+ 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);
- if (!md) continue;
+ if (!md)
+ continue;
- if(class_ == MOBID_EMPERIUM) {
+ if (class_ == MOBID_EMPERIUM)
+ {
struct guild_castle* gc = guild_mapindex2gc(map[m].index);
- struct guild* g = gc?guild_search(gc->guild_id):NULL;
- if(gc) {
+ struct guild* g = (gc) ? guild_search(gc->guild_id) : NULL;
+ if (gc)
+ {
md->guardian_data = (struct guardian_data*)aCalloc(1, sizeof(struct guardian_data));
md->guardian_data->castle = gc;
md->guardian_data->number = MAX_GUARDIANS;
@@ -527,33 +506,35 @@ int mob_once_spawn(struct map_session_data* sd, int m, short x, short y, const c
sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE|MD_CANATTACK|MD_CANMOVE|MD_ANGRY, 0, 60000);
}
- return (md)?md->bl.id : 0; // id of last spawned mob
+ return (md) ? md->bl.id : 0; // id of last spawned mob
}
/*==========================================
* Spawn mobs in the specified area.
*------------------------------------------*/
-int mob_once_spawn_area(struct map_session_data* sd,int m,int x0,int y0,int x1,int y1,const char* mobname,int class_,int amount,const char* event)
+int mob_once_spawn_area(struct map_session_data* sd, int m, int x0, int y0, int x1, int y1, const char* mobname, int class_, int amount, const char* event, unsigned int size, unsigned int ai)
{
- int i,max,id=0;
- int lx=-1,ly=-1;
+ int i, max, id = 0;
+ int lx = -1, ly = -1;
if (m < 0 || amount <= 0)
return 0; // invalid input
// normalize x/y coordinates
- if( x0 > x1 ) swap(x0,x1);
- if( y0 > y1 ) swap(y0,y1);
+ if (x0 > x1)
+ swap(x0, x1);
+ if (y0 > y1)
+ swap(y0, y1);
// choose a suitable max. number of attempts
- max = (y1-y0+1)*(x1-x0+1)*3;
- if( max > 1000 )
+ max = (y1 - y0 + 1)*(x1 - x0 + 1)*3;
+ if (max > 1000)
max = 1000;
// spawn mobs, one by one
- for( i = 0; i < amount; i++)
+ for (i = 0; i < amount; i++)
{
- int x,y;
+ int x, y;
int j = 0;
// find a suitable map cell
@@ -561,11 +542,11 @@ int mob_once_spawn_area(struct map_session_data* sd,int m,int x0,int y0,int x1,i
x = rnd()%(x1-x0+1)+x0;
y = rnd()%(y1-y0+1)+y0;
j++;
- } while( map_getcell(m,x,y,CELL_CHKNOPASS) && j < max );
+ } while (map_getcell(m,x,y,CELL_CHKNOPASS) && j < max);
- if( j == max )
+ if (j == max)
{// attempt to find an available cell failed
- if( lx == -1 && ly == -1 )
+ if (lx == -1 && ly == -1)
return 0; // total failure
// fallback to last good x/y pair
@@ -577,7 +558,7 @@ int mob_once_spawn_area(struct map_session_data* sd,int m,int x0,int y0,int x1,i
lx = x;
ly = y;
- id = mob_once_spawn(sd,m,x,y,mobname,class_,1,event);
+ id = mob_once_spawn(sd, m, x, y, mobname, class_, 1, event, size, ai);
}
return id; // id of last spawned mob
@@ -3508,14 +3489,14 @@ int mob_clone_spawn(struct map_session_data *sd, int m, int x, int y, const char
sd->fd = fd;
//Finally, spawn it.
- md = mob_once_spawn_sub(&sd->bl, m, x, y, "--en--",class_,event);
+ md = mob_once_spawn_sub(&sd->bl, m, x, y, "--en--", class_, event, SZ_SMALL, AI_NONE);
if (!md) return 0; //Failed?
md->special_state.clone = 1;
if (master_id || flag || duration) { //Further manipulate crafted char.
if (flag&1) //Friendly Character
- md->special_state.ai = 1;
+ md->special_state.ai = AI_ATTACK;
if (master_id) //Attach to Master
md->master_id = master_id;
if (duration) //Auto Delete after a while.
diff --git a/src/map/mob.h b/src/map/mob.h
index d45962163..d6d58584e 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -69,6 +69,14 @@ enum size {
SZ_BIG,
};
+enum ai {
+ AI_NONE = 0,
+ AI_ATTACK,
+ AI_SPHERE,
+ AI_FLORA,
+ AI_ZANZOU,
+};
+
struct mob_skill {
enum MobSkillState state;
short skill_id,skill_lv;
@@ -184,7 +192,7 @@ struct mob_data {
enum {
- MST_TARGET = 0,
+ MST_TARGET = 0,
MST_RANDOM, //Random Target!
MST_SELF,
MST_FRIEND,
@@ -197,9 +205,9 @@ enum {
MST_AROUND2,
MST_AROUND3,
MST_AROUND4,
- MST_AROUND = MST_AROUND4,
+ MST_AROUND = MST_AROUND4,
- MSC_ALWAYS = 0x0000,
+ MSC_ALWAYS = 0x0000,
MSC_MYHPLTMAXRATE,
MSC_MYHPINRATE,
MSC_FRIENDHPLTMAXRATE,
@@ -215,7 +223,7 @@ enum {
MSC_CLOSEDATTACKED,
MSC_LONGRANGEATTACKED,
MSC_AFTERSKILL,
- MSC_SKILLUSED ,
+ MSC_SKILLUSED,
MSC_CASTTARGETED,
MSC_RUDEATTACKED,
MSC_MASTERHPLTMAXRATE,
@@ -240,10 +248,15 @@ int mobdb_searchname(const char *str);
int mobdb_searchname_array(struct mob_db** data, int size, const char *str);
int mobdb_checkid(const int id);
struct view_data* mob_get_viewdata(int class_);
+
struct mob_data *mob_once_spawn_sub(struct block_list *bl, int m,
- short x, short y, const char *mobname, int class_, const char *event);
-int mob_once_spawn(struct map_session_data* sd,int m,short x,short y,const char* mobname,int class_,int amount,const char* event);
-int mob_once_spawn_area(struct map_session_data* sd,int m,int x0,int y0,int x1,int y1,const char* mobname,int class_,int amount,const char* event);
+ short x, short y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai);
+
+int mob_once_spawn(struct map_session_data* sd, int m, short x, short y,
+ const char* mobname, int class_, int amount, const char* event, unsigned int size, unsigned int ai);
+
+int mob_once_spawn_area(struct map_session_data* sd, int m,
+ int x0, int y0, int x1, int y1, const char* mobname, int class_, int amount, const char* event, unsigned int size, unsigned int ai);
bool mob_ksprotected (struct block_list *src, struct block_list *target);
diff --git a/src/map/npc.c b/src/map/npc.c
index 65f5ee577..60f8b14ad 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -383,15 +383,6 @@ int npc_event_doall_id(const char* name, int rid)
return c;
}
-
-/// Checks whether or not the event name is used as transport for
-/// special flags.
-bool npc_event_isspecial(const char* eventname)
-{
- return (bool)( eventname && ISDIGIT(eventname[0]) && !strstr(eventname, "::") );
-}
-
-
/*==========================================
* Clock event execution
* OnMinute/OnClock/OnHour/OnDay/OnDDHHMM
diff --git a/src/map/npc.h b/src/map/npc.h
index 7198ad905..29cf39c77 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -145,7 +145,6 @@ int npc_do_ontimer(int npc_id, int option);
int npc_event_do(const char* name);
int npc_event_doall(const char* name);
int npc_event_doall_id(const char* name, int rid);
-bool npc_event_isspecial(const char* eventname);
int npc_timerevent_start(struct npc_data* nd, int rid);
int npc_timerevent_stop(struct npc_data* nd);
diff --git a/src/map/script.c b/src/map/script.c
index eabf5d14c..f0a0b7f86 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -633,15 +633,8 @@ static void check_event(struct script_state *st, const char *evt)
{
if( evt && evt[0] && !stristr(evt, "::On") )
{
- if( npc_event_isspecial(evt) )
- {
- ; // portable small/large monsters or other attributes
- }
- else
- {
- ShowWarning("NPC event parameter deprecated! Please use 'NPCNAME::OnEVENT' instead of '%s'.\n", evt);
- script_reportsrc(st);
- }
+ ShowWarning("NPC event parameter deprecated! Please use 'NPCNAME::OnEVENT' instead of '%s'.\n", evt);
+ script_reportsrc(st);
}
}
@@ -8663,38 +8656,61 @@ BUILDIN_FUNC(guildchangegm)
*------------------------------------------*/
BUILDIN_FUNC(monster)
{
- const char* mapn = script_getstr(st,2);
- int x = script_getnum(st,3);
- int y = script_getnum(st,4);
- const char* str = script_getstr(st,5);
- int class_ = script_getnum(st,6);
- int amount = script_getnum(st,7);
- const char* event = "";
+ const char* mapn = script_getstr(st,2);
+ int x = script_getnum(st,3);
+ int y = script_getnum(st,4);
+ const char* str = script_getstr(st,5);
+ int class_ = script_getnum(st,6);
+ int amount = script_getnum(st,7);
+ const char* event = "";
+ unsigned int size = SZ_SMALL;
+ unsigned int ai = AI_NONE;
struct map_session_data* sd;
int m;
- if( script_hasdata(st,8) )
+ if (script_hasdata(st, 8))
{
- event = script_getstr(st,8);
+ event = script_getstr(st, 8);
check_event(st, event);
}
+
+ if (script_hasdata(st, 9))
+ {
+ size = script_getnum(st, 9);
+ if (size > 3)
+ {
+ ShowWarning("buildin_monster: Attempted to spawn non-existing size %d for monster class %d\n", size, class_);
+ return 1;
+ }
+ }
+
+ if (script_hasdata(st, 10))
+ {
+ ai = script_getnum(st, 10);
+ if (ai > 4)
+ {
+ ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_);
+ return 1;
+ }
+ }
- if (class_ >= 0 && !mobdb_checkid(class_)) {
+ if (class_ >= 0 && !mobdb_checkid(class_))
+ {
ShowWarning("buildin_monster: Attempted to spawn non-existing monster class %d\n", class_);
return 1;
}
sd = map_id2sd(st->rid);
- if( sd && strcmp(mapn,"this") == 0 )
+ if (sd && strcmp(mapn, "this") == 0)
m = sd->bl.m;
else
{
m = map_mapname2mapid(mapn);
- if( map[m].flag.src4instance && st->instance_id )
+ if (map[m].flag.src4instance && st->instance_id)
{ // Try to redirect to the instance map, not the src map
- if( (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
+ if ((m = instance_mapid2imapid(m, st->instance_id)) < 0)
{
ShowError("buildin_monster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
return 1;
@@ -8702,7 +8718,7 @@ BUILDIN_FUNC(monster)
}
}
- mob_once_spawn(sd,m,x,y,str,class_,amount,event);
+ mob_once_spawn(sd, m, x, y, str, class_, amount, event, size, ai);
return 0;
}
/*==========================================
@@ -8745,35 +8761,57 @@ BUILDIN_FUNC(getmobdrops)
*------------------------------------------*/
BUILDIN_FUNC(areamonster)
{
- const char* mapn = script_getstr(st,2);
- int x0 = script_getnum(st,3);
- int y0 = script_getnum(st,4);
- int x1 = script_getnum(st,5);
- int y1 = script_getnum(st,6);
- const char* str = script_getstr(st,7);
- int class_ = script_getnum(st,8);
- int amount = script_getnum(st,9);
- const char* event = "";
+ const char* mapn = script_getstr(st,2);
+ int x0 = script_getnum(st,3);
+ int y0 = script_getnum(st,4);
+ int x1 = script_getnum(st,5);
+ int y1 = script_getnum(st,6);
+ const char* str = script_getstr(st,7);
+ int class_ = script_getnum(st,8);
+ int amount = script_getnum(st,9);
+ const char* event = "";
+ unsigned int size = SZ_SMALL;
+ unsigned int ai = AI_NONE;
struct map_session_data* sd;
int m;
- if( script_hasdata(st,10) )
+ if (script_hasdata(st,10))
{
- event = script_getstr(st,10);
+ event = script_getstr(st, 10);
check_event(st, event);
}
+
+ if (script_hasdata(st, 11))
+ {
+ size = script_getnum(st, 11);
+ if (size > 3)
+ {
+ ShowWarning("buildin_monster: Attempted to spawn non-existing size %d for monster class %d\n", size, class_);
+ return 1;
+ }
+ }
+
+ if (script_hasdata(st, 12))
+ {
+ ai = script_getnum(st, 12);
+ if (ai > 4)
+ {
+ ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_);
+ return 1;
+ }
+ }
sd = map_id2sd(st->rid);
- if( sd && strcmp(mapn,"this") == 0 )
+ if (sd && strcmp(mapn, "this") == 0)
m = sd->bl.m;
else
{
m = map_mapname2mapid(mapn);
- if( map[m].flag.src4instance && st->instance_id )
+ if (map[m].flag.src4instance && st->instance_id)
{ // Try to redirect to the instance map, not the src map
- if( (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
+ if ((m = instance_mapid2imapid(m, st->instance_id)) < 0)
{
ShowError("buildin_areamonster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
return 1;
@@ -8781,7 +8819,7 @@ BUILDIN_FUNC(areamonster)
}
}
- mob_once_spawn_area(sd,m,x0,y0,x1,y1,str,class_,amount,event);
+ mob_once_spawn_area(sd, m, x0, y0, x1, y1, str, class_, amount, event, size, ai);
return 0;
}
/*==========================================
@@ -12983,10 +13021,10 @@ BUILDIN_FUNC(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);
+ md = mob_once_spawn_sub(&sd->bl, sd->bl.m, sd->bl.x, sd->bl.y, str, _class, event, SZ_SMALL, AI_NONE);
if (md) {
md->master_id=sd->bl.id;
- md->special_state.ai=1;
+ md->special_state.ai = AI_ATTACK;
if( md->deletetimer != INVALID_TIMER )
delete_timer(md->deletetimer, mob_timer_delete);
md->deletetimer = add_timer(tick+(timeout>0?timeout*1000:60000),mob_timer_delete,md->bl.id,0);
@@ -17112,9 +17150,9 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(itemskill,"vi"),
BUILDIN_DEF(produce,"i"),
BUILDIN_DEF(cooking,"i"),
- BUILDIN_DEF(monster,"siisii?"),
+ BUILDIN_DEF(monster,"siisii???"),
BUILDIN_DEF(getmobdrops,"i"),
- BUILDIN_DEF(areamonster,"siiiisii?"),
+ BUILDIN_DEF(areamonster,"siiiisii???"),
BUILDIN_DEF(killmonster,"ss?"),
BUILDIN_DEF(killmonsterall,"s?"),
BUILDIN_DEF(clone,"siisi????"),
diff --git a/src/map/skill.c b/src/map/skill.c
index 7dcfa2552..78586e2ef 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -4909,7 +4909,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
case SA_SUMMONMONSTER:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (sd) mob_once_spawn(sd,src->m,src->x,src->y,"--ja--",-1,1,"");
+ if (sd) mob_once_spawn(sd, src->m, src->x, src->y," --ja--", -1, 1, "", SZ_SMALL, AI_NONE);
break;
case SA_LEVELUP:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
@@ -8725,11 +8725,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if(sd){
struct mob_data *md;
- md = mob_once_spawn_sub(src, src->m, src->x, src->y, status_get_name(src), 2308, "");
+ md = mob_once_spawn_sub(src, src->m, src->x, src->y, status_get_name(src), 2308, "", SZ_SMALL, AI_NONE);
if( md )
{
md->master_id = src->id;
- md->special_state.ai = 4;
+ md->special_state.ai = AI_ZANZOU;
if( md->deletetimer != INVALID_TIMER )
delete_timer(md->deletetimer, mob_timer_delete);
md->deletetimer = add_timer (gettick() + skill_get_time(skillid, skilllv), mob_timer_delete, md->bl.id, 0);
@@ -9648,10 +9648,10 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
struct mob_data *md;
// Correct info, don't change any of this! [celest]
- md = mob_once_spawn_sub(src, src->m, x, y, status_get_name(src),class_,"");
+ md = mob_once_spawn_sub(src, src->m, x, y, status_get_name(src), class_, "", SZ_SMALL, AI_NONE);
if (md) {
md->master_id = src->id;
- md->special_state.ai = skillid==AM_SPHEREMINE?2:3;
+ md->special_state.ai = (skillid == AM_SPHEREMINE) ? AI_SPHERE : AI_FLORA;
if( md->deletetimer != INVALID_TIMER )
delete_timer(md->deletetimer, mob_timer_delete);
md->deletetimer = add_timer (gettick() + skill_get_time(skillid,skilllv), mob_timer_delete, md->bl.id, 0);
@@ -9746,7 +9746,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
if (rnd()%100 < 50) {
clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
} else {
- TBL_MOB* md = mob_once_spawn_sub(src, src->m, x, y, "--ja--",(skilllv < 2 ? 1084+rnd()%2 : 1078+rnd()%6),"");
+ TBL_MOB* md = mob_once_spawn_sub(src, src->m, x, y, "--ja--",(skilllv < 2 ? 1084+rnd()%2 : 1078+rnd()%6),"", SZ_SMALL, AI_NONE);
int i;
if (!md) break;
if ((i = skill_get_time(skillid, skilllv)) > 0)
@@ -9886,11 +9886,11 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
int class_ = 2042;
struct mob_data *md;
- md = mob_once_spawn_sub(src, src->m, x, y, status_get_name(src), class_, "");
+ md = mob_once_spawn_sub(src, src->m, x, y, status_get_name(src), class_, "", SZ_SMALL, AI_NONE);
if( md )
{
md->master_id = src->id;
- md->special_state.ai = 3;
+ md->special_state.ai = AI_FLORA;
if( md->deletetimer != INVALID_TIMER )
delete_timer(md->deletetimer, mob_timer_delete);
md->deletetimer = add_timer (gettick() + skill_get_time(skillid, skilllv), mob_timer_delete, md->bl.id, 0);
@@ -16325,10 +16325,10 @@ int skill_magicdecoy(struct map_session_data *sd, int nameid) {
class_ = (nameid == 990 || nameid == 991) ? 2043 + nameid - 990 : (nameid == 992) ? 2046 : 2045;
- md = mob_once_spawn_sub(&sd->bl, sd->bl.m, x, y, sd->status.name, class_, "");
+ md = mob_once_spawn_sub(&sd->bl, sd->bl.m, x, y, sd->status.name, class_, "", SZ_SMALL, AI_NONE);
if( md ) {
md->master_id = sd->bl.id;
- md->special_state.ai = 3;
+ md->special_state.ai = AI_FLORA;
if( md->deletetimer != INVALID_TIMER )
delete_timer(md->deletetimer, mob_timer_delete);
md->deletetimer = add_timer (gettick() + skill_get_time(NC_MAGICDECOY,skill), mob_timer_delete, md->bl.id, 0);