summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/battle/feature.conf4
-rw-r--r--conf/msg_athena.conf2
-rw-r--r--src/map/atcommand.c80
-rw-r--r--src/map/battle.c1
-rw-r--r--src/map/battle.h2
-rw-r--r--src/map/config/core.h5
6 files changed, 93 insertions, 1 deletions
diff --git a/conf/battle/feature.conf b/conf/battle/feature.conf
index 0dd3af0cf..efb58722a 100644
--- a/conf/battle/feature.conf
+++ b/conf/battle/feature.conf
@@ -14,3 +14,7 @@ feature.buying_store: on
// Search stores (Note 1)
// Requires: 2010-08-03aRagexeRE or later
feature.search_stores: on
+
+// Atcommand suggestions (Note 1)
+// If one type incomplete atcommand, it will suggest the complete ones.
+feature.atcommand_suggestions = off \ No newline at end of file
diff --git a/conf/msg_athena.conf b/conf/msg_athena.conf
index 90cce6c42..2e4fe62ff 100644
--- a/conf/msg_athena.conf
+++ b/conf/msg_athena.conf
@@ -218,7 +218,7 @@
202: This player has forgotten the skill.
203: This player doesn't have this quest skill.
204: You can't open a shop on this cell.
-//205: FREE
+205: Maybe you meant:
206: '%s' skill points reset.
207: '%s' stats points reset.
208: '%s' skill and stat points have been reset.
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index e9b6732c8..741513ca2 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -52,6 +52,7 @@
#define ACMD_FUNC(x) static int atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message)
#define MAX_MSG 1000
+
typedef struct AtCommandInfo AtCommandInfo;
typedef struct AliasInfo AliasInfo;
@@ -79,6 +80,7 @@ static char atcmd_player_name[NAME_LENGTH];
static AtCommandInfo* get_atcommandinfo_byname(const char *name); // @help
static const char* atcommand_checkalias(const char *aliasname); // @help
+static void atcommand_get_suggestions(struct map_session_data* sd, const char *name, bool atcommand); // @help
//-----------------------------------------------------------
// Return the message string of the specified number by [Yor]
@@ -1657,11 +1659,13 @@ ACMD_FUNC(help)
if (!pc_can_use_command(sd, command_name, COMMAND_ATCOMMAND)) {
sprintf(atcmd_output, msg_txt(153), message); // "%s is Unknown Command"
clif_displaymessage(fd, atcmd_output);
+ atcommand_get_suggestions(sd, command_name, true);
return -1;
}
if (!config_setting_lookup_string(help, command_name, &text)) {
clif_displaymessage(fd, "There is no help for this command_name.");
+ atcommand_get_suggestions(sd, command_name, true);
return -1;
}
@@ -8757,6 +8761,81 @@ static const char* atcommand_checkalias(const char *aliasname)
return aliasname;
}
+/// AtCommand suggestion
+static void atcommand_get_suggestions(struct map_session_data* sd, const char *name, bool atcommand)
+{
+ DBIterator* atcommand_iter = db_iterator(atcommand_db);
+ DBIterator* alias_iter = db_iterator(atcommand_alias_db);
+ AtCommandInfo* command_info = NULL;
+ AliasInfo* alias_info = NULL;
+ AtCommandType type;
+ char* suggestions[MAX_SUGGESTIONS];
+ int count = 0;
+
+ if (!battle_config.atcommand_suggestions_enabled)
+ return;
+
+ if (atcommand)
+ type = COMMAND_ATCOMMAND;
+ else
+ type = COMMAND_CHARCOMMAND;
+
+
+ // First match the beginnings of the commands
+ for (command_info = dbi_first(atcommand_iter); dbi_exists(atcommand_iter) && count < MAX_SUGGESTIONS; command_info = dbi_next(atcommand_iter)) {
+ if ( strstr(command_info->command, name) == command_info->command && pc_can_use_command(sd, command_info->command, type) )
+ {
+ suggestions[count] = command_info->command;
+ ++count;
+ }
+ }
+
+ for (alias_info = dbi_first(alias_iter); dbi_exists(alias_iter) && count < MAX_SUGGESTIONS; alias_info = dbi_next(alias_iter)) {
+ if ( strstr(alias_info->alias, name) == alias_info->alias && pc_can_use_command(sd, alias_info->command->command, type) )
+ {
+ suggestions[count] = alias_info->alias;
+ ++count;
+ }
+ }
+
+ // Fill up the space left, with full matches
+ for (command_info = dbi_first(atcommand_iter); dbi_exists(atcommand_iter) && count < MAX_SUGGESTIONS; command_info = dbi_next(atcommand_iter)) {
+ if ( strstr(command_info->command, name) != NULL && pc_can_use_command(sd, command_info->command, type) )
+ {
+ suggestions[count] = command_info->command;
+ ++count;
+ }
+ }
+
+ for (alias_info = dbi_first(alias_iter); dbi_exists(alias_iter) && count < MAX_SUGGESTIONS; alias_info = dbi_next(alias_iter)) {
+ if ( strstr(alias_info->alias, name) != NULL && pc_can_use_command(sd, alias_info->command->command, type) )
+ {
+ suggestions[count] = alias_info->alias;
+ ++count;
+ }
+ }
+
+ if (count > 0)
+ {
+ char buffer[512];
+ int i;
+
+ strcpy(buffer, msg_txt(205));
+ strcat(buffer,"\n");
+
+ for(i=0; i < count; ++i)
+ {
+ strcat(buffer,suggestions[i]);
+ strcat(buffer," ");
+ }
+
+ clif_displaymessage(sd->fd, buffer);
+ }
+
+ dbi_destroy(atcommand_iter);
+ dbi_destroy(alias_iter);
+}
+
/// Executes an at-command.
bool is_atcommand(const int fd, struct map_session_data* sd, const char* message, int type)
{
@@ -8855,6 +8934,7 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message
if( pc_get_group_level(sd) ) { // TODO: remove or replace with proper permission
sprintf(output, msg_txt(153), command); // "%s is Unknown Command."
clif_displaymessage(fd, output);
+ atcommand_get_suggestions(sd, command + 1, *message == atcommand_symbol);
return true;
} else
return false;
diff --git a/src/map/battle.c b/src/map/battle.c
index b14bb6f33..5f327803c 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -5269,6 +5269,7 @@ static const struct _battle_data {
{ "atcommand_max_stat_bypass", &battle_config.atcommand_max_stat_bypass, 0, 0, 100, },
{ "skill_amotion_leniency", &battle_config.skill_amotion_leniency, 90, 0, 100 },
{ "mvp_tomb_enabled", &battle_config.mvp_tomb_enabled, 1, 0, 1 },
+ { "feature.atcommand_suggestions", &battle_config.atcommand_suggestions_enabled, 0, 0, 1 },
};
diff --git a/src/map/battle.h b/src/map/battle.h
index 3b42c52b7..bf381927d 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -471,6 +471,8 @@ extern struct Battle_Config
int atcommand_max_stat_bypass;
int mvp_tomb_enabled;
+
+ int atcommand_suggestions_enabled;
} battle_config;
void do_init_battle(void);
diff --git a/src/map/config/core.h b/src/map/config/core.h
index 519df60e7..9963d38b9 100644
--- a/src/map/config/core.h
+++ b/src/map/config/core.h
@@ -13,6 +13,11 @@
**/
#define AUTOLOOTITEM_SIZE 10
+/**
+ * The maximum number of atcommand suggestions
+ **/
+#define MAX_SUGGESTIONS 10
+
/// leave this line uncommented to enable callfunc checks when processing scripts.
/// while allowed, the script engine will attempt to match user-defined functions
/// in scripts allowing direct function callback (without the use of callfunc.)