summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/map/init.c4
-rw-r--r--src/map/parse.c56
-rw-r--r--src/map/quest.c156
-rw-r--r--src/map/quest.h2
4 files changed, 114 insertions, 104 deletions
diff --git a/src/map/init.c b/src/map/init.c
index 90ecffb..3e92ce9 100644
--- a/src/map/init.c
+++ b/src/map/init.c
@@ -10,6 +10,7 @@
#include "../../../common/mmo.h"
#include "../../../common/socket.h"
#include "../../../common/strlib.h"
+#include "../../../map/channel.h"
#include "../../../map/chat.h"
#include "../../../map/chrif.h"
#include "../../../map/clif.h"
@@ -182,10 +183,11 @@ HPExport void server_preinit (void)
libpcre = GET_SYMBOL("libpcre");
mapit = GET_SYMBOL("mapit");
mapindex = GET_SYMBOL("mapindex");
+ channel = GET_SYMBOL("channel");
setDefaultMap();
- addHookPre("quest->read_db", equest_read_db);
+ addHookPre("quest->read_db_sub", equest_read_db_sub);
addGroupPermission("send_gm_flag", permission_send_gm_flag);
}
diff --git a/src/map/parse.c b/src/map/parse.c
index a2155b1..2e145dc 100644
--- a/src/map/parse.c
+++ b/src/map/parse.c
@@ -10,6 +10,7 @@
#include "../../../common/mmo.h"
#include "../../../common/socket.h"
#include "../../../common/strlib.h"
+#include "../../../map/channel.h"
#include "../../../map/clif.h"
#include "../../../map/pc.h"
@@ -28,7 +29,6 @@ void map_parse_join_channel(int fd)
{
char name[24];
char *p;
- struct hChSysCh *channel = NULL;
struct map_session_data* sd = (struct map_session_data*)session[fd]->session_data;
int res = 0;
if (!sd)
@@ -40,52 +40,16 @@ void map_parse_join_channel(int fd)
else
p = name;
- if (clif->hChSys->local && strcmpi(p, clif->hChSys->local_name) == 0)
- {
- if (!map->list[sd->bl.m].channel)
- clif->chsys_mjoin(sd);
- channel = map->list[sd->bl.m].channel;
- res = 1;
- }
- else if (clif->hChSys->ally && sd->status.guild_id && strcmpi(p, clif->hChSys->ally_name) == 0)
- {
- struct guild *g = sd->guild;
- if (g)
- channel = g->channel;
- }
- if (!res && (channel || (channel = strdb_get(clif->channel_db,p ))))
+ struct channel_data *chan = channel->search(p, sd);
+
+ if (chan)
{
int k;
- for (k = 0; k < sd->channel_count; k++)
- {
- if (sd->channels[k] == channel)
- break;
- }
- if (k < sd->channel_count)
- {
- res = 2;
- }
- else if (channel->pass[0] == '\0' && !(channel->banned && idb_exists(channel->banned, sd->status.account_id)))
- {
- if (channel->type == hChSys_ALLY)
- {
- struct guild *g = sd->guild, *sg = NULL;
- for (k = 0; k < MAX_GUILDALLIANCE; k++)
- {
- if (g->alliance[k].opposition == 0 && g->alliance[k].guild_id && (sg = guild->search(g->alliance[k].guild_id)))
- {
- if (!(sg->channel->banned && idb_exists(sg->channel->banned, sd->status.account_id)))
- clif->chsys_join(sg->channel, sd);
- }
- }
- }
- clif->chsys_join(channel, sd);
+ ARR_FIND(0, sd->channel_count, k, sd->channels[k] == chan);
+ if (k < sd->channel_count || channel->join(chan, sd, NULL, true) == HCS_STATUS_OK)
res = 1;
- }
else
- {
res = 0;
- }
}
send_join_ack(fd, name, res);
@@ -112,15 +76,15 @@ void map_parse_part_channel(int fd)
break;
}
- if (sd->channels[k]->type == hChSys_ALLY)
+ if (sd->channels[k]->type == HCS_TYPE_ALLY)
{
do
{
for (k = 0; k < sd->channel_count; k++)
{
- if (sd->channels[k]->type == hChSys_ALLY)
+ if (sd->channels[k]->type == HCS_TYPE_ALLY)
{
- clif->chsys_left(sd->channels[k],sd);
+ channel->leave(sd->channels[k], sd);
break;
}
}
@@ -129,6 +93,6 @@ void map_parse_part_channel(int fd)
}
else
{
- clif->chsys_left(sd->channels[k],sd);
+ channel->leave(sd->channels[k], sd);
}
}
diff --git a/src/map/quest.c b/src/map/quest.c
index a65e08a..aef112a 100644
--- a/src/map/quest.c
+++ b/src/map/quest.c
@@ -10,75 +10,119 @@
#include "../../../common/mmo.h"
#include "../../../common/socket.h"
#include "../../../common/strlib.h"
+#include "../../../map/itemdb.h"
#include "../../../map/quest.h"
#include "map/quest.h"
-int equest_read_db(void)
+/**
+ * Reads and parses an entry from the quest_db.
+ *
+ * @param cs The config setting containing the entry.
+ * @param n The sequential index of the current config setting.
+ * @param source The source configuration file.
+ * @return The parsed quest entry.
+ * @retval NULL in case of errors.
+ */
+struct quest_db *equest_read_db_sub(config_setting_t *cs, int *nPtr, const char *source)
{
- FILE *fp;
- char line[1024];
- int i, count = 0;
- char *str[20], *p, *np;
- struct quest_db entry;
+ struct quest_db *entry = NULL;
+ config_setting_t *t = NULL;
+ int i32 = 0, quest_id;
+ const char *str = NULL;
+ const int n = *nPtr;
- sprintf(line, "%s/quest_db.txt", map->db_path);
- if ((fp = fopen(line, "r")) == NULL)
- {
- ShowError("can't read %s\n", line);
- hookStop();
- return -1;
- }
+ /*
+ * Id: Quest ID [int]
+ * Name: Quest Name [string]
+ * TimeLimit: Time Limit (seconds) [int, optional]
+ * Targets: ( [array, optional]
+ * {
+ * MobId: Mob ID [int]
+ * Count: [int]
+ * },
+ * ... (can repeated up to MAX_QUEST_OBJECTIVES times)
+ * )
+ * Drops: (
+ * {
+ * ItemId: Item ID to drop [int]
+ * Rate: Drop rate [int]
+ * MobId: Mob ID to match [int, optional]
+ * },
+ * ... (can be repeated)
+ * )
+ */
- while (fgets(line, sizeof(line), fp))
- {
- if (line[0]=='/' && line[1]=='/')
- continue;
- memset(str,0,sizeof(str));
+ if (!libconfig->setting_lookup_int(cs, "Id", &quest_id)) {
+ ShowWarning("quest_read_db: Missing id in \"%s\", entry #%d, skipping.\n", source, n);
+ return NULL;
+ }
+ if (quest_id < 0 || quest_id >= MAX_QUEST_DB) {
+ ShowWarning("quest_read_db: Invalid quest ID '%d' in \"%s\", entry #%d (min: 0, max: %d), skipping.\n", quest_id, source, n, MAX_QUEST_DB);
+ return NULL;
+ }
- for (i = 0, p = line; i < 8; i++) {
- if (( np = strchr(p,',') ) != NULL) {
- str[i] = p;
- *np = 0;
- p = np + 1;
- } else if (str[0] == NULL) {
- break;
- } else {
- ShowError("quest_read_db: insufficient columns in line %s\n", line);
- continue;
- }
- }
- if (str[0] == NULL)
- continue;
+ if (!libconfig->setting_lookup_string(cs, "Name", &str) || !*str) {
+ ShowWarning("quest_read_db_sub: Missing Name in quest %d of \"%s\", skipping.\n", quest_id, source);
+ return NULL;
+ }
- memset(&entry, 0, sizeof(entry));
+ CREATE(entry, struct quest_db, 1);
+ entry->id = quest_id;
+ //safestrncpy(entry->name, str, sizeof(entry->name));
- entry.id = atoi(str[0]);
+ if (libconfig->setting_lookup_int(cs, "TimeLimit", &i32)) // This is an unsigned value, do not check for >= 0
+ entry->time = (unsigned int)i32;
- if (entry.id < 0 || entry.id >= MAX_QUEST_DB) {
- ShowError("quest_read_db: Invalid quest ID '%d' in line '%s' (min: 0, max: %d.)\n", entry.id, line, MAX_QUEST_DB);
- continue;
+ if ((t=libconfig->setting_get_member(cs, "Targets")) && config_setting_is_list(t)) {
+/*
+ int i, len = libconfig->setting_length(t);
+ for (i = 0; i < len && entry->objectives_count < MAX_QUEST_OBJECTIVES; i++) {
+ // Note: We ensure that objectives_count < MAX_QUEST_OBJECTIVES because
+ // quest_log (as well as the client) expect this maximum size.
+ config_setting_t *tt = libconfig->setting_get_elem(t, i);
+ int mob_id = 0, count = 0;
+ if (!tt)
+ break;
+ if (!config_setting_is_group(tt))
+ continue;
+ if (!libconfig->setting_lookup_int(tt, "MobId", &mob_id) || mob_id <= 0)
+ continue;
+ if (!libconfig->setting_lookup_int(tt, "Count", &count) || count <= 0)
+ continue;
+ RECREATE(entry->objectives, struct quest_objective, ++entry->objectives_count);
+ entry->objectives[entry->objectives_count-1].mob = mob_id;
+ entry->objectives[entry->objectives_count-1].count = count;
}
+*/
+ entry->objectives_count = 1;
+ RECREATE(entry->objectives, struct quest_objective, 1);
+ entry->objectives[0].mob = 1;
+ entry->objectives[0].count = 0;
+ }
- entry.time = atoi(str[1]);
-
-// for (i = 0; i < MAX_QUEST_OBJECTIVES; i++) {
- for (i = 0; i < 1; i++) {
-// entry.mob[i] = atoi(str[2*i+2]);
- entry.mob[i] = 1;
- entry.count[i] = atoi(str[2*i+3]);
+ if ((t=libconfig->setting_get_member(cs, "Drops")) && config_setting_is_list(t)) {
+ int i, len = libconfig->setting_length(t);
+ for (i = 0; i < len; i++) {
+ config_setting_t *tt = libconfig->setting_get_elem(t, i);
+ int mob_id = 0, nameid = 0, rate = 0;
+ if (!tt)
+ break;
+ if (!config_setting_is_group(tt))
+ continue;
+ if (!libconfig->setting_lookup_int(tt, "MobId", &mob_id))
+ mob_id = 0; // Zero = any monster
+ if (mob_id < 0)
+ continue;
+ if (!libconfig->setting_lookup_int(tt, "ItemId", &nameid) || !itemdb->exists(nameid))
+ continue;
+ if (!libconfig->setting_lookup_int(tt, "Rate", &rate) || rate <= 0)
+ continue;
+ RECREATE(entry->dropitem, struct quest_dropitem, ++entry->dropitem_count);
+ entry->dropitem[entry->dropitem_count-1].mob_id = mob_id;
+ entry->dropitem[entry->dropitem_count-1].nameid = nameid;
+ entry->dropitem[entry->dropitem_count-1].rate = rate;
}
-
- entry.num_objectives = i;
-
- if (quest->db_data[entry.id] == NULL)
- quest->db_data[entry.id] = aMalloc(sizeof(struct quest_db));
-
- memcpy(quest->db_data[entry.id], &entry, sizeof(struct quest_db));
- count++;
}
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, "quest_db.txt");
- hookStop();
- return 0;
+ return entry;
}
diff --git a/src/map/quest.h b/src/map/quest.h
index 07b5db7..c947bcc 100644
--- a/src/map/quest.h
+++ b/src/map/quest.h
@@ -4,6 +4,6 @@
#ifndef EVOL_MAP_QUEST
#define EVOL_MAP_QUEST
-int equest_read_db(void);
+struct quest_db *equest_read_db_sub(config_setting_t *cs, int *nPtr, const char *source);
#endif // EVOL_MAP_QUEST