summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.c50
-rw-r--r--src/map/atcommand.h1
-rw-r--r--src/map/mob.c8
-rw-r--r--src/map/mob.h7
-rw-r--r--src/map/npc.c31
-rw-r--r--src/map/pc.c4
-rw-r--r--src/map/script.c9
7 files changed, 105 insertions, 5 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index d0bed703b..11d10534f 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -231,6 +231,7 @@ ACMD_FUNC(mutearea); // by MouseJstr
ACMD_FUNC(rates); // by MouseJstr
ACMD_FUNC(iteminfo); // Lupus
ACMD_FUNC(whodrops); //Skotlex
+ACMD_FUNC(whereis); //Skotlex
ACMD_FUNC(mapflag); // Lupus
ACMD_FUNC(me); //added by massdriller, code by lordalfa
ACMD_FUNC(monsterignore); // [Valaris]
@@ -527,6 +528,7 @@ static AtCommandInfo atcommand_info[] = {
{ AtCommand_ItemInfo, "@iteminfo", 1, atcommand_iteminfo }, // [Lupus]
{ AtCommand_ItemInfo, "@ii", 1, atcommand_iteminfo }, // [Lupus]
{ AtCommand_WhoDrops, "@whodrops", 1, atcommand_whodrops }, // [Skotlex]
+ { AtCommand_WhereIs, "@whereis", 10, atcommand_whereis }, // [Skotlex]
{ AtCommand_MapFlag, "@mapflag", 99, atcommand_mapflag }, // [Lupus]
{ AtCommand_Me, "@me", 20, atcommand_me }, //added by massdriller, code by lordalfa
{ AtCommand_MonsterIgnore, "@monsterignore", 99, atcommand_monsterignore }, // [Valaris]
@@ -8699,6 +8701,54 @@ int atcommand_whodrops(const int fd, struct map_session_data* sd, const char* co
return 0;
}
+int atcommand_whereis(const int fd, struct map_session_data* sd, const char* command, const char* message)
+{
+ struct mob_db *mob, *mob_array[MAX_SEARCH];
+ int count;
+ int i, j, k;
+
+ if (!message || !*message) {
+ clif_displaymessage(fd, "Please, enter a Monster/ID (usage: @whereis<monster_name_or_monster_ID>).");
+ return -1;
+ }
+
+ // If monster identifier/name argument is a name
+ if ((i = mobdb_checkid(atoi(message))))
+ {
+ mob_array[0] = mob_db(i);
+ count = 1;
+ } else
+ count = mobdb_searchname_array(mob_array, MAX_SEARCH, message);
+
+ if (!count) {
+ clif_displaymessage(fd, msg_txt(40)); // Invalid monster ID or name.
+ return -1;
+ }
+
+ if (count > MAX_SEARCH) {
+ sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, count);
+ clif_displaymessage(fd, atcmd_output);
+ count = MAX_SEARCH;
+ }
+ for (k = 0; k < count; k++) {
+ mob = mob_array[k];
+ snprintf(atcmd_output, sizeof atcmd_output, "%s spawns in:", mob->jname);
+ clif_displaymessage(fd, atcmd_output);
+
+ for (i = 0; i < ARRAYLENGTH(mob->spawn) && mob->spawn[i].qty; i++)
+ {
+ j = map_mapindex2mapid(mob->spawn[i].mapindex);
+ if (j < 0) continue;
+ snprintf(atcmd_output, sizeof atcmd_output, "%s (%d)", map[j].name, mob->spawn[i].qty);
+ clif_displaymessage(fd, atcmd_output);
+ }
+ if (i == 0)
+ clif_displaymessage(fd, "This monster does not spawn normally.");
+ }
+
+ return 0;
+}
+
/*==========================================
* @adopt by [Veider]
* adopt a novice
diff --git a/src/map/atcommand.h b/src/map/atcommand.h
index e5b00046c..9b775a00c 100644
--- a/src/map/atcommand.h
+++ b/src/map/atcommand.h
@@ -217,6 +217,7 @@ enum AtCommandType {
AtCommand_Rates, // MouseJstr
AtCommand_ItemInfo, // Lupus
AtCommand_WhoDrops, // Skotlex
+ AtCommand_WhereIs, // Skotlex
AtCommand_MapFlag, // Lupus
AtCommand_MonsterIgnore, // [Valaris]
AtCommand_FakeName, // [Valaris]
diff --git a/src/map/mob.c b/src/map/mob.c
index f3cec671a..01679708b 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -3991,6 +3991,14 @@ void mob_reload(void)
mob_readdb_race();
}
+void mob_clear_spawninfo()
+{ //Clears spawn related information for a script reload.
+ int i;
+ for (i = 0; i < MAX_MOB_DB; i++)
+ if (mob_db_data[i])
+ memset(&mob_db_data[i]->spawn,0,sizeof(mob_db_data[i]->spawn));
+}
+
/*==========================================
* Circumference initialization of mob
*------------------------------------------*/
diff --git a/src/map/mob.h b/src/map/mob.h
index 944ab84ac..e75de3912 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -56,6 +56,11 @@ struct mob_skill {
short emotion;
};
+struct spawn_info {
+ unsigned short mapindex;
+ unsigned short qty;
+};
+
struct mob_db {
char sprite[NAME_LENGTH],name[NAME_LENGTH],jname[NAME_LENGTH];
unsigned int base_exp,job_exp;
@@ -71,6 +76,7 @@ struct mob_db {
int summonper[MAX_RANDOMMONSTER];
int maxskill;
struct mob_skill skill[MAX_MOBSKILL];
+ struct spawn_info spawn[10];
};
enum {
@@ -173,6 +179,7 @@ void mob_heal(struct mob_data *md,unsigned int heal);
#define mob_stop_walking(md, type) { if (md->ud.walktimer != -1) unit_stop_walking(&md->bl, type); }
#define mob_stop_attack(md) { if (md->ud.attacktimer != -1) unit_stop_attack(&md->bl); }
+void mob_clear_spawninfo();
int do_init_mob(void);
int do_final_mob(void);
diff --git a/src/map/npc.c b/src/map/npc.c
index 40df4b678..c2ab39446 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -2341,6 +2341,7 @@ int npc_parse_mob(char* w1, char* w2, char* w3, char* w4)
char mapname[MAP_NAME_LENGTH_EXT];
char mobname[NAME_LENGTH];
struct spawn_data mob, *data;
+ struct mob_db* db;
memset(&mob, 0, sizeof(struct spawn_data));
@@ -2397,8 +2398,9 @@ int npc_parse_mob(char* w1, char* w2, char* w3, char* w4)
mob.xs = mob.ys = -1;
}
+ db = mob_db(class_);
//Apply the spawn delay fix [Skotlex]
- mode = mob_db(class_)->status.mode;
+ mode = db->status.mode;
if (mode & MD_BOSS) { //Bosses
if (battle_config.boss_spawn_delay != 100)
{ // Divide by 100 first to prevent overflows
@@ -2438,6 +2440,32 @@ int npc_parse_mob(char* w1, char* w2, char* w3, char* w4)
if (!mob_parse_dataset(&mob)) //Verify dataset.
return 1;
+ for(x=0; x < ARRAYLENGTH(db->spawn); x++)
+ {
+ if (map[mob.m].index == db->spawn[x].mapindex)
+ { //Update total
+ db->spawn[x].qty += mob.num;
+ //Re-sort list
+ for (y = x; y>0 && db->spawn[y-1].qty < db->spawn[x].qty; y--);
+ if (y != x)
+ {
+ xs = db->spawn[x].mapindex;
+ ys = db->spawn[x].qty;
+ memmove(&db->spawn[y+1], &db->spawn[y], (x-y)*sizeof(db->spawn[0]));
+ db->spawn[y].mapindex = xs;
+ db->spawn[y].qty = ys;
+ }
+ break;
+ }
+ if (mob.num > db->spawn[x].qty)
+ { //Insert into list
+ memmove(&db->spawn[x+1], &db->spawn[x], sizeof(db->spawn) -(x+1)*sizeof(db->spawn[0]));
+ db->spawn[x].mapindex = map[mob.m].index;
+ db->spawn[x].qty = mob.num;
+ break;
+ }
+ }
+
//Now that all has been validated. We allocate the actual memory
//that the re-spawn data will use.
data = aMalloc(sizeof(struct spawn_data));
@@ -2940,6 +2968,7 @@ int npc_reload(void)
if (map[m].npc_num > 0 && battle_config.error_log)
ShowWarning("npc_reload: %d npcs weren't removed at map %s!\n", map[m].npc_num, map[m].name);
}
+ mob_clear_spawninfo();
// anything else we should cleanup?
// Reloading npc's now
diff --git a/src/map/pc.c b/src/map/pc.c
index e564c3554..30d012b5e 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -2365,11 +2365,11 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
break;
case SP_AUTOSPELL:
if(sd->state.lr_flag != 2)
- pc_bonus_autospell(sd->autospell, MAX_PC_BONUS, type2, type3, val, 0, current_equip_card_id);
+ pc_bonus_autospell(sd->autospell, MAX_PC_BONUS, skill_get_inf(type2)&INF_SELF_SKILL?-type2:type2, type3, val, 0, current_equip_card_id);
break;
case SP_AUTOSPELL_WHENHIT:
if(sd->state.lr_flag != 2)
- pc_bonus_autospell(sd->autospell2, MAX_PC_BONUS, type2, type3, val, 0, current_equip_card_id);
+ pc_bonus_autospell(sd->autospell2, MAX_PC_BONUS, skill_get_inf(type2)&INF_SELF_SKILL?-type2:type2, type3, val, 0, current_equip_card_id);
break;
case SP_HP_LOSS_RATE:
if(sd->state.lr_flag != 2) {
diff --git a/src/map/script.c b/src/map/script.c
index d115e6df3..a98dffe5c 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -8737,8 +8737,13 @@ BUILDIN_FUNC(homunculus_evolution)
{
TBL_PC *sd;
sd=script_rid2sd(st);
- if(merc_is_hom_active(sd->hd) && sd->hd->homunculus.intimacy > 91000)
- merc_hom_evolution(sd->hd);
+ if(merc_is_hom_active(sd->hd))
+ {
+ if (sd->hd->homunculus.intimacy > 91000)
+ merc_hom_evolution(sd->hd);
+ else
+ clif_emotion(&sd->hd->bl, 4) ; //swt
+ }
return 0;
}