summaryrefslogtreecommitdiff
path: root/src/map/atcommand.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/atcommand.c')
-rw-r--r--src/map/atcommand.c193
1 files changed, 132 insertions, 61 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 5d95e2c14..c9191d27d 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -4483,59 +4483,90 @@ ACMD(loadnpc)
return true;
}
+/**
+ * Unloads a specific NPC.
+ *
+ * @code{.herc}
+ * @unloadnpc <NPC_name> {<flag>}
+ * @endcode
+ *
+ **/
ACMD(unloadnpc)
{
- struct npc_data *nd;
- char NPCname[NAME_LENGTH+1];
-
- memset(NPCname, '\0', sizeof(NPCname));
+ char npc_name[NAME_LENGTH + 1] = {'\0'};
+ int flag = 1;
- 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 == '\0' || sscanf(message, "%24s %1d", npc_name, &flag) < 1) {
+ clif->message(fd, msg_fd(fd, 1133)); /// Please enter a NPC name (Usage: @unloadnpc <NPC_name> {<flag>}).
return false;
}
-
- if ((nd = npc->name2id(NPCname)) == NULL) {
- clif->message(fd, msg_fd(fd,111)); // This NPC doesn't exist.
+
+ struct npc_data *nd = npc->name2id(npc_name);
+
+ if (nd == NULL) {
+ clif->message(fd, msg_fd(fd, 111)); /// This NPC doesn't exist.
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.
+ 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
+/**
+ * Unloads a script file and reloads it.
+ * Note: Be aware that some changes made by NPC are not reverted on unload. See doc/atcommands.txt for details.
+ *
+ * @code{.herc}
+ * @reloadnpc <path> {<flag>}
+ * @endcode
+ *
+ **/
ACMD(reloadnpc)
{
- if (!*message) {
- clif->message(fd, msg_fd(fd, 1385)); // Usage: @unloadnpcfile <file name>
+ char format[20];
+
+ snprintf(format, sizeof(format), "%%%ds %%1d", MAX_DIR_PATH);
+
+ char file_path[MAX_DIR_PATH + 1] = {'\0'};
+ int flag = 1;
+
+ if (*message == '\0' || (sscanf(message, format, 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.
+ }
- FILE *fp = fopen(message, "r");
- // check if script file exists
- if (fp == NULL) {
- clif->message(fd, msg_fd(fd, 261));
- return false;
- }
- fclose(fp);
+ if (!exists(file_path)) {
+ clif->message(fd, msg_fd(fd, 1387)); /// File not found.
+ return false;
+ }
+
+ if (!is_file(file_path)) {
+ clif->message(fd, msg_fd(fd, 1518)); /// Not a file.
+ return false;
+ }
- // add to list of script sources and run it
- npc->addsrcfile(message);
- npc->parsesrcfile(message, true);
- npc->read_event_script();
+ FILE *fp = fopen(file_path, "r");
- clif->message(fd, msg_fd(fd, 262));
- } else {
- clif->message(fd, msg_fd(fd, 1387)); // File not found.
+ if (fp == NULL) {
+ clif->message(fd, msg_fd(fd, 1519)); /// Can't open file.
return false;
}
+ fclose(fp);
+
+ if (!npc->unloadfile(file_path, (flag != 0))) {
+ clif->message(fd, msg_fd(fd, 1517)); /// Script could not be unloaded.
+ return false;
+ }
+
+ clif->message(fd, msg_fd(fd, 1386)); /// File unloaded. Be aware that...
+ npc->addsrcfile(file_path);
+ npc->parsesrcfile(file_path, true);
+ npc->read_event_script();
+ clif->message(fd, msg_fd(fd, 262)); /// Script loaded.
return true;
}
@@ -6576,47 +6607,52 @@ ACMD(reset)
/*==========================================
*
*------------------------------------------*/
+
+/**
+ * Spawns mobs which treats the invoking as its master.
+ *
+ * @code{.herc}
+ * @summon <monster name/ID> {<duration>}
+ * @endcode
+ *
+ **/
ACMD(summon)
{
- char name[NAME_LENGTH];
- int mob_id = 0;
+ char name[NAME_LENGTH + 1] = {'\0'};
int duration = 0;
- struct mob_data *md;
- int64 tick=timer->gettick();
- if (!*message || sscanf(message, "%23s %12d", name, &duration) < 1)
- {
- clif->message(fd, msg_fd(fd,1225)); // Please enter a monster name (usage: @summon <monster name> {duration}).
+ if (*message == '\0' || sscanf(message, "%24s %12d", name, &duration) < 1) {
+ clif->message(fd, msg_fd(fd, 1225)); /// Please enter a monster name (usage: @summon <monster name> {duration}).
return false;
}
- if (duration < 1)
- duration =1;
- else if (duration > 60)
- duration =60;
+ int mob_id = atoi(name);
- if ((mob_id = atoi(name)) == 0)
+ if (mob_id == 0)
mob_id = mob->db_searchname(name);
- if(mob_id == 0 || mob->db_checkid(mob_id) == 0)
- {
- clif->message(fd, msg_fd(fd,40)); // Invalid monster ID or name.
+
+ if (mob_id == 0 || mob->db_checkid(mob_id) == 0) {
+ clif->message(fd, msg_fd(fd, 40)); /// Invalid monster ID or name.
return false;
}
- md = mob->once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, DEFAULT_MOB_JNAME, mob_id, "", SZ_SMALL, AI_NONE);
+ struct mob_data *md = mob->once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, DEFAULT_MOB_JNAME, mob_id, "",
+ SZ_SMALL, AI_NONE, 0);
- if(!md)
+ if (md == NULL)
return false;
md->master_id = sd->bl.id;
md->special_state.ai = AI_ATTACK;
- md->deletetimer = timer->add(tick+(duration*60000),mob->timer_delete,md->bl.id,0);
- clif->specialeffect(&md->bl,344,AREA);
- mob->spawn(md);
- sc_start4(NULL,&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000);
- clif->skill_poseffect(&sd->bl,AM_CALLHOMUN,1,md->bl.x,md->bl.y,tick);
- clif->message(fd, msg_fd(fd,39)); // All monster summoned!
+ const int64 tick = timer->gettick();
+
+ md->deletetimer = timer->add(tick + (int64)cap_value(duration, 1, 60) * 60000, mob->timer_delete, md->bl.id, 0);
+ clif->specialeffect(&md->bl, 344, AREA);
+ mob->spawn(md);
+ sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000);
+ clif->skill_poseffect(&sd->bl, AM_CALLHOMUN, 1, md->bl.x, md->bl.y, tick);
+ clif->message(fd, msg_fd(fd, 39)); /// All monster summoned!
return true;
}
@@ -9009,19 +9045,54 @@ ACMD(addperm)
return true;
}
+/**
+ * Unloads a script file.
+ * Note: Be aware that some changes made by NPC are not reverted on unload. See doc/atcommands.txt for details.
+ *
+ * @code{.herc}
+ * @unloadnpcfile <path> {<flag>}
+ * @endcode
+ *
+ **/
ACMD(unloadnpcfile)
{
- if (!*message) {
- clif->message(fd, msg_fd(fd,1385)); // Usage: @unloadnpcfile <file name>
+ char format[20];
+
+ snprintf(format, sizeof(format), "%%%ds %%1d", MAX_DIR_PATH);
+
+ char file_path[MAX_DIR_PATH + 1] = {'\0'};
+ int flag = 1;
+
+ if (*message == '\0' || (sscanf(message, format, 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.
- } else {
- clif->message(fd, msg_fd(fd,1387)); // File not found.
+ if (!exists(file_path)) {
+ clif->message(fd, msg_fd(fd, 1387)); /// File not found.
return false;
}
+
+ if (!is_file(file_path)) {
+ clif->message(fd, msg_fd(fd, 1518)); /// Not a file.
+ return false;
+ }
+
+ FILE *fp = fopen(file_path, "r");
+
+ if (fp == NULL) {
+ clif->message(fd, msg_fd(fd, 1519)); /// Can't open file.
+ return false;
+ }
+
+ fclose(fp);
+
+ if (!npc->unloadfile(file_path, (flag != 0))) {
+ clif->message(fd, msg_fd(fd, 1517)); /// Script could not be unloaded.
+ return false;
+ }
+
+ clif->message(fd, msg_fd(fd, 1386)); /// File unloaded. Be aware that...
return true;
}