summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2019-06-01 14:22:19 +0200
committerGitHub <noreply@github.com>2019-06-01 14:22:19 +0200
commitc8202e1cd9eb64d07fa921d117a13eef3938a4db (patch)
treee57701639ffb1e518431dc0e0a10860aa7c642d6 /src/map
parentd7042459c9f9797a80dadce57297b5d16e8931c4 (diff)
parenta321a26f2f9867c8c0e4b5503e4ad2275801122e (diff)
downloadhercules-c8202e1cd9eb64d07fa921d117a13eef3938a4db.tar.gz
hercules-c8202e1cd9eb64d07fa921d117a13eef3938a4db.tar.bz2
hercules-c8202e1cd9eb64d07fa921d117a13eef3938a4db.tar.xz
hercules-c8202e1cd9eb64d07fa921d117a13eef3938a4db.zip
Merge pull request #2433 from Asheraf/questinfomemfix
Move questinfo data from map to npc_data
Diffstat (limited to 'src/map')
-rw-r--r--src/map/clif.c10
-rw-r--r--src/map/instance.c9
-rw-r--r--src/map/map.c153
-rw-r--r--src/map/map.h41
-rw-r--r--src/map/npc.c20
-rw-r--r--src/map/npc.h2
-rw-r--r--src/map/quest.c42
-rw-r--r--src/map/quest.h34
-rw-r--r--src/map/script.c12
9 files changed, 127 insertions, 196 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 5228f06a3..721d2f5b5 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -10790,15 +10790,7 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
// NPC Quest / Event Icon Check [Kisuka]
#if PACKETVER >= 20090218
- {
- int i;
- for (i = 0; i < VECTOR_LENGTH(map->list[sd->bl.m].qi_data); i++) {
- struct questinfo *qi = &VECTOR_INDEX(map->list[sd->bl.m].qi_data, i);
-
- if (quest->questinfo_validate(sd, qi))
- clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
- }
- }
+ quest->questinfo_refresh(sd);
#endif
}
diff --git a/src/map/instance.c b/src/map/instance.c
index 1e83b0b76..e87cc03bb 100644
--- a/src/map/instance.c
+++ b/src/map/instance.c
@@ -295,13 +295,6 @@ static int instance_add_map(const char *name, int instance_id, bool usebasename,
}
}
- //Mimic questinfo
- VECTOR_INIT(map->list[im].qi_data);
- VECTOR_ENSURE(map->list[im].qi_data, VECTOR_LENGTH(map->list[m].qi_data), 1);
- for (i = 0; i < VECTOR_LENGTH(map->list[m].qi_data); i++) {
- VECTOR_PUSH(map->list[im].qi_data, VECTOR_INDEX(map->list[m].qi_data, i));
- }
-
map->list[im].m = im;
map->list[im].instance_id = instance_id;
map->list[im].instance_src_map = m;
@@ -518,7 +511,7 @@ static void instance_del_map(int16 m)
aFree(map->list[m].zone_mf);
}
- quest->questinfo_vector_clear(m);
+ VECTOR_CLEAR(map->list[m].qi_list);
// Remove from instance
for( i = 0; i < instance->list[map->list[m].instance_id].num_map; i++ ) {
diff --git a/src/map/map.c b/src/map/map.c
index 2b95ec27a..71eab9286 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -3586,23 +3586,27 @@ static void map_zone_db_clear(void)
}
static void map_clean(int i)
{
- int v;
Assert_retv(i >= 0 && i < map->count);
- if(map->list[i].cell && map->list[i].cell != (struct mapcell *)0xdeadbeaf) aFree(map->list[i].cell);
- if(map->list[i].block) aFree(map->list[i].block);
- if(map->list[i].block_mob) aFree(map->list[i].block_mob);
- if(battle_config.dynamic_mobs) { //Dynamic mobs flag by [random]
- int j;
- if(map->list[i].mob_delete_timer != INVALID_TIMER)
+ if (map->list[i].cell && map->list[i].cell != (struct mapcell *)0xdeadbeaf)
+ aFree(map->list[i].cell);
+ if (map->list[i].block)
+ aFree(map->list[i].block);
+ if (map->list[i].block_mob)
+ aFree(map->list[i].block_mob);
+
+ if (battle_config.dynamic_mobs != 0) { //Dynamic mobs flag by [random]
+ if (map->list[i].mob_delete_timer != INVALID_TIMER)
timer->delete(map->list[i].mob_delete_timer, map->removemobs_timer);
- for (j=0; j<MAX_MOB_LIST_PER_MAP; j++)
- if (map->list[i].moblist[j]) aFree(map->list[i].moblist[j]);
+ for (int j = 0; j < MAX_MOB_LIST_PER_MAP; j++) {
+ if (map->list[i].moblist[j] != NULL)
+ aFree(map->list[i].moblist[j]);
+ }
}
- if( map->list[i].unit_count ) {
- if( map->list[i].units ) {
- for(v = 0; v < map->list[i].unit_count; v++) {
+ if (map->list[i].unit_count != 0) {
+ if (map->list[i].units != NULL) {
+ for (int v = 0; v < map->list[i].unit_count; v++) {
aFree(map->list[i].units[v]);
}
aFree(map->list[i].units);
@@ -3611,98 +3615,44 @@ static void map_clean(int i)
map->list[i].unit_count = 0;
}
- if( map->list[i].skill_count ) {
- if( map->list[i].skills ) {
- for(v = 0; v < map->list[i].skill_count; v++) {
- aFree(map->list[i].skills[v]);
- }
+ if (map->list[i].skill_count != 0) {
+ if (map->list[i].skills != NULL) {
+ for (int v = 0; v < map->list[i].skill_count; v++) {
+ aFree(map->list[i].skills[v]);
+ }
aFree(map->list[i].skills);
map->list[i].skills = NULL;
}
map->list[i].skill_count = 0;
}
- if( map->list[i].zone_mf_count ) {
- if( map->list[i].zone_mf ) {
- for(v = 0; v < map->list[i].zone_mf_count; v++) {
- aFree(map->list[i].zone_mf[v]);
- }
+ if (map->list[i].zone_mf_count != 0) {
+ if (map->list[i].zone_mf != NULL) {
+ for (int v = 0; v < map->list[i].zone_mf_count; v++) {
+ aFree(map->list[i].zone_mf[v]);
+ }
aFree(map->list[i].zone_mf);
map->list[i].zone_mf = NULL;
}
map->list[i].zone_mf_count = 0;
}
- if( map->list[i].channel )
+ if (map->list[i].drop_list_count != 0)
+ map->list[i].drop_list_count = 0;
+ if (map->list[i].drop_list != NULL)
+ aFree(map->list[i].drop_list);
+
+ if (map->list[i].channel != NULL)
channel->delete(map->list[i].channel);
+
+ VECTOR_CLEAR(map->list[i].qi_list);
+ HPM->data_store_destroy(&map->list[i].hdata);
}
static void do_final_maps(void)
{
- int i, v = 0;
-
- for( i = 0; i < map->count; i++ ) {
-
- if(map->list[i].cell && map->list[i].cell != (struct mapcell *)0xdeadbeaf ) aFree(map->list[i].cell);
- if(map->list[i].block) aFree(map->list[i].block);
- if(map->list[i].block_mob) aFree(map->list[i].block_mob);
-
- if(battle_config.dynamic_mobs) { //Dynamic mobs flag by [random]
- int j;
- if(map->list[i].mob_delete_timer != INVALID_TIMER)
- timer->delete(map->list[i].mob_delete_timer, map->removemobs_timer);
- for (j=0; j<MAX_MOB_LIST_PER_MAP; j++)
- if (map->list[i].moblist[j]) aFree(map->list[i].moblist[j]);
- }
-
- if( map->list[i].unit_count ) {
- if( map->list[i].units ) {
- for(v = 0; v < map->list[i].unit_count; v++) {
- aFree(map->list[i].units[v]);
- }
- aFree(map->list[i].units);
- map->list[i].units = NULL;
- }
- map->list[i].unit_count = 0;
- }
-
- if( map->list[i].skill_count ) {
- if( map->list[i].skills ) {
- for(v = 0; v < map->list[i].skill_count; v++) {
- aFree(map->list[i].skills[v]);
- }
- aFree(map->list[i].skills);
- map->list[i].skills = NULL;
- }
- map->list[i].skill_count = 0;
- }
-
- if( map->list[i].zone_mf_count ) {
- if( map->list[i].zone_mf ) {
- for(v = 0; v < map->list[i].zone_mf_count; v++) {
- aFree(map->list[i].zone_mf[v]);
- }
- aFree(map->list[i].zone_mf);
- map->list[i].zone_mf = NULL;
- }
- map->list[i].zone_mf_count = 0;
- }
-
- if( map->list[i].drop_list_count ) {
- map->list[i].drop_list_count = 0;
- }
- if( map->list[i].drop_list != NULL )
- aFree(map->list[i].drop_list);
-
- if( map->list[i].channel )
- channel->delete(map->list[i].channel);
-
- quest->questinfo_vector_clear(i);
-
- HPM->data_store_destroy(&map->list[i].hdata);
- }
-
+ for (int i = 0; i < map->count; i++)
+ map->clean(i);
map->zone_db_clear();
-
}
static void map_zonedb_reload(void)
@@ -3793,7 +3743,8 @@ static void map_flags_init(void)
map->list[i].short_damage_rate = 100;
map->list[i].long_damage_rate = 100;
- VECTOR_INIT(map->list[i].qi_data);
+ VECTOR_CLEAR(map->list[i].qi_list);
+ VECTOR_INIT(map->list[i].qi_list);
}
}
@@ -6029,28 +5980,30 @@ static int map_get_new_bonus_id(void)
return map->bonus_id++;
}
-static void map_add_questinfo(int m, struct questinfo *qi)
+static bool map_add_questinfo(int m, struct npc_data *nd)
{
- nullpo_retv(qi);
- Assert_retv(m >= 0 && m < map->count);
+ nullpo_retr(false, nd);
+ Assert_retr(false, m >= 0 && m < map->count);
- VECTOR_ENSURE(map->list[m].qi_data, 1, 1);
- VECTOR_PUSH(map->list[m].qi_data, *qi);
+ if (&VECTOR_LAST(map->list[m].qi_list) == nd)
+ return false;
+
+ VECTOR_ENSURE(map->list[m].qi_list, 1, 1);
+ VECTOR_PUSH(map->list[m].qi_list, *nd);
+ return true;
}
static bool map_remove_questinfo(int m, struct npc_data *nd)
{
- unsigned short i;
nullpo_retr(false, nd);
Assert_retr(false, m >= 0 && m < map->count);
- for (i = 0; i < VECTOR_LENGTH(map->list[m].qi_data); i++) {
- struct questinfo *qi_data = &VECTOR_INDEX(map->list[m].qi_data, i);
- if (qi_data->nd == nd) {
- VECTOR_ERASE(map->list[m].qi_data, i);
- return true;
- }
+ int i;
+ ARR_FIND(0, VECTOR_LENGTH(map->list[m].qi_list), i, &VECTOR_INDEX(map->list[m].qi_list, i) == nd);
+ if (i != VECTOR_LENGTH(map->list[m].qi_list)) {
+ VECTOR_ERASE(map->list[m].qi_list, i);
+ return true;
}
return false;
}
diff --git a/src/map/map.h b/src/map/map.h
index 1f70680e8..0330eccc4 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -705,41 +705,6 @@ struct map_drop_list {
int drop_per;
};
-struct questinfo_qreq {
- int id;
- int state;
-};
-
-struct questinfo_itemreq {
- int nameid;
- int min;
- int max;
-};
-
-struct questinfo {
- struct npc_data *nd;
- unsigned short icon;
- unsigned char color;
- bool hasJob;
- unsigned int job;/* perhaps a mapid mask would be most flexible? */
- bool sex_enabled;
- int sex;
- struct {
- int min;
- int max;
- } base_level;
- struct {
- int min;
- int max;
- } job_level;
- VECTOR_DECL(struct questinfo_itemreq) items;
- struct s_homunculus homunculus;
- int homunculus_type;
- VECTOR_DECL(struct questinfo_qreq) quest_requirement;
- int mercenary_class;
-};
-
-
struct map_data {
char name[MAP_NAME_LENGTH];
uint16 index; // The map index used by the mapindex* functions.
@@ -877,8 +842,8 @@ struct map_data {
int len;
} cell_buf;
- /* ShowEvent Data Cache */
- VECTOR_DECL(struct questinfo) qi_data;
+ /* questinfo entries list */
+ VECTOR_DECL(struct npc_data) qi_list;
/* speeds up clif_updatestatus processing by causing hpmeter to run only when someone with the permission can view it */
unsigned short hpmeter_visible;
@@ -1312,7 +1277,7 @@ END_ZEROED_BLOCK;
int (*abort_sub) (struct map_session_data *sd, va_list ap);
void (*update_cell_bl) (struct block_list *bl, bool increase);
int (*get_new_bonus_id) (void);
- void (*add_questinfo) (int m, struct questinfo *qi);
+ bool (*add_questinfo) (int m, struct npc_data *nd);
bool (*remove_questinfo) (int m, struct npc_data *nd);
struct map_zone_data *(*merge_zone) (struct map_zone_data *main, struct map_zone_data *other);
void (*zone_clear_single) (struct map_zone_data *zone);
diff --git a/src/map/npc.c b/src/map/npc.c
index 4b79a9fed..77087d6cb 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -36,6 +36,7 @@
#include "map/mob.h"
#include "map/pc.h"
#include "map/pet.h"
+#include "map/quest.h"
#include "map/script.h"
#include "map/skill.h"
#include "map/status.h"
@@ -2638,8 +2639,9 @@ static int npc_unload(struct npc_data *nd, bool single)
nd->path = NULL;
}
- if( single && nd->bl.m != -1 )
- map->remove_questinfo(nd->bl.m,nd);
+ if (single && nd->bl.m != -1)
+ map->remove_questinfo(nd->bl.m, nd);
+ npc->questinfo_clear(nd);
if (nd->src_id == 0 && ( nd->subtype == SHOP || nd->subtype == CASHSHOP)) {
//src check for duplicate shops [Orcao]
@@ -2978,6 +2980,7 @@ static struct npc_data *npc_create_npc(enum npc_subtype subtype, int m, int x, i
nd->class_ = class_;
nd->speed = 200;
nd->vd = npc_viewdb[0]; // Copy INVISIBLE_CLASS view data. Actual view data is set by npc->add_to_location() later.
+ VECTOR_INIT(nd->qi_data);
return nd;
}
@@ -5331,6 +5334,18 @@ static void npc_debug_warps(void)
npc->debug_warps_sub(map->list[m].npc[i]);
}
+static void npc_questinfo_clear(struct npc_data *nd)
+{
+ nullpo_retv(nd);
+
+ for (int i = 0; i < VECTOR_LENGTH(nd->qi_data); i++) {
+ struct questinfo *qi = &VECTOR_INDEX(nd->qi_data, i);
+ VECTOR_CLEAR(qi->items);
+ VECTOR_CLEAR(qi->quest_requirement);
+ }
+ VECTOR_CLEAR(nd->qi_data);
+}
+
/*==========================================
* npc initialization
*------------------------------------------*/
@@ -5551,4 +5566,5 @@ void npc_defaults(void)
npc->barter_delfromsql_sub = npc_barter_delfromsql_sub;
npc->db_checkid = npc_db_checkid;
npc->refresh = npc_refresh;
+ npc->questinfo_clear = npc_questinfo_clear;
}
diff --git a/src/map/npc.h b/src/map/npc.h
index 0eb8befd1..2819cbd87 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -129,6 +129,7 @@ struct npc_data {
int spawn_timer;
} tomb;
} u;
+ VECTOR_DECL(struct questinfo) qi_data;
struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
};
@@ -322,6 +323,7 @@ struct npc_interface {
void (*barter_delfromsql_sub) (const char *npcname, int itemId, int itemId2, int amount2);
bool (*db_checkid) (const int id);
void (*refresh) (struct npc_data* nd);
+ void (*questinfo_clear) (struct npc_data *nd);
/**
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
**/
diff --git a/src/map/quest.c b/src/map/quest.c
index 7a216095e..9540b411d 100644
--- a/src/map/quest.c
+++ b/src/map/quest.c
@@ -672,21 +672,22 @@ static int quest_questinfo_validate_icon(int icon)
*/
static void quest_questinfo_refresh(struct map_session_data *sd)
{
- int i;
-
nullpo_retv(sd);
- for (i = 0; i < VECTOR_LENGTH(map->list[sd->bl.m].qi_data); i++) {
- struct questinfo *qi = &VECTOR_INDEX(map->list[sd->bl.m].qi_data, i);
- // Remove the bubbles if one of the conditions is no longer valid.
- if (quest->questinfo_validate(sd, qi) == false) {
+ for (int i = 0; i < VECTOR_LENGTH(map->list[sd->bl.m].qi_list); i++) {
+ struct npc_data *nd = &VECTOR_INDEX(map->list[sd->bl.m].qi_list, i);
+
+ int j;
+ ARR_FIND(0, VECTOR_LENGTH(nd->qi_data), j, quest->questinfo_validate(sd, &VECTOR_INDEX(nd->qi_data, j)) == true);
+ if (j != VECTOR_LENGTH(nd->qi_data)) {
+ struct questinfo *qi = &VECTOR_INDEX(nd->qi_data, j);
+ clif->quest_show_event(sd, &nd->bl, qi->icon, qi->color);
+ } else {
#if PACKETVER >= 20120410
- clif->quest_show_event(sd, &qi->nd->bl, 9999, 0);
+ clif->quest_show_event(sd, &nd->bl, 9999, 0);
#else
- clif->quest_show_event(sd, &qi->nd->bl, 0, 0);
+ clif->quest_show_event(sd, &nd->bl, 0, 0);
#endif
- } else {
- clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
}
}
}
@@ -927,26 +928,6 @@ static bool quest_questinfo_validate_mercenary_class(struct map_session_data *sd
}
/**
- * Clears the questinfo data vector
- *
- * @param m mapindex.
- *
- */
-static void quest_questinfo_vector_clear(int m)
-{
- int i;
-
- Assert_retv(m >= 0 && m < map->count);
-
- for (i = 0; i < VECTOR_LENGTH(map->list[m].qi_data); i++) {
- struct questinfo *qi_data = &VECTOR_INDEX(map->list[m].qi_data, i);
- VECTOR_CLEAR(qi_data->items);
- VECTOR_CLEAR(qi_data->quest_requirement);
- }
- VECTOR_CLEAR(map->list[m].qi_data);
-}
-
-/**
* Initializes the quest interface.
*
* @param minimal Run in minimal mode (skips most of the loading)
@@ -1020,5 +1001,4 @@ void quest_defaults(void)
quest->questinfo_validate_homunculus_type = quest_questinfo_validate_homunculus_type;
quest->questinfo_validate_quests = quest_questinfo_validate_quests;
quest->questinfo_validate_mercenary_class = quest_questinfo_validate_mercenary_class;
- quest->questinfo_vector_clear = quest_questinfo_vector_clear;
}
diff --git a/src/map/quest.h b/src/map/quest.h
index 206a7902f..d60b9b33c 100644
--- a/src/map/quest.h
+++ b/src/map/quest.h
@@ -60,6 +60,39 @@ enum quest_check_type {
HUNTING, ///< Check if the given hunting quest's requirements have been met
};
+struct questinfo_qreq {
+ int id;
+ int state;
+};
+
+struct questinfo_itemreq {
+ int nameid;
+ int min;
+ int max;
+};
+
+struct questinfo {
+ unsigned short icon;
+ unsigned char color;
+ bool hasJob;
+ unsigned int job;/* perhaps a mapid mask would be most flexible? */
+ bool sex_enabled;
+ int sex;
+ struct {
+ int min;
+ int max;
+ } base_level;
+ struct {
+ int min;
+ int max;
+ } job_level;
+ VECTOR_DECL(struct questinfo_itemreq) items;
+ struct s_homunculus homunculus;
+ int homunculus_type;
+ VECTOR_DECL(struct questinfo_qreq) quest_requirement;
+ int mercenary_class;
+};
+
struct quest_interface {
struct quest_db **db_data; ///< Quest database
struct quest_db dummy; ///< Dummy entry for invalid quest lookups
@@ -93,7 +126,6 @@ struct quest_interface {
bool (*questinfo_validate_homunculus_type) (struct map_session_data *sd, struct questinfo *qi);
bool (*questinfo_validate_quests) (struct map_session_data *sd, struct questinfo *qi);
bool (*questinfo_validate_mercenary_class) (struct map_session_data *sd, struct questinfo *qi);
- void (*questinfo_vector_clear) (int m);
};
#ifdef HERCULES_CORE
diff --git a/src/map/script.c b/src/map/script.c
index 5843ac292..8d001f3fe 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -21256,7 +21256,6 @@ static BUILDIN(questinfo)
return false;
}
- qi.nd = nd;
qi.icon = quest->questinfo_validate_icon(icon);
if (script_hasdata(st, 3)) {
int color = script_getnum(st, 3);
@@ -21268,7 +21267,9 @@ static BUILDIN(questinfo)
qi.color = (unsigned char)color;
}
- map->add_questinfo(nd->bl.m, &qi);
+ VECTOR_ENSURE(nd->qi_data, 1, 1);
+ VECTOR_PUSH(nd->qi_data, qi);
+ map->add_questinfo(nd->bl.m, nd);
return true;
}
@@ -21286,15 +21287,12 @@ static BUILDIN(setquestinfo)
return false;
}
- qi = &VECTOR_LAST(map->list[nd->bl.m].qi_data);
+ qi = &VECTOR_LAST(nd->qi_data);
if (qi == NULL) {
ShowWarning("buildin_setquestinfo: no valide questinfo data has been found for this npc.\n");
return false;
}
- if (qi->nd != nd) {
- ShowWarning("buildin_setquestinfo: invalid usage, setquestinfo must be used only after questinfo.\n");
- return false;
- }
+
switch (type) {
case QINFO_JOB:
{