diff options
author | Haru <haru@dotalux.com> | 2019-06-01 14:22:19 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-01 14:22:19 +0200 |
commit | c8202e1cd9eb64d07fa921d117a13eef3938a4db (patch) | |
tree | e57701639ffb1e518431dc0e0a10860aa7c642d6 /src/map | |
parent | d7042459c9f9797a80dadce57297b5d16e8931c4 (diff) | |
parent | a321a26f2f9867c8c0e4b5503e4ad2275801122e (diff) | |
download | hercules-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.c | 10 | ||||
-rw-r--r-- | src/map/instance.c | 9 | ||||
-rw-r--r-- | src/map/map.c | 153 | ||||
-rw-r--r-- | src/map/map.h | 41 | ||||
-rw-r--r-- | src/map/npc.c | 20 | ||||
-rw-r--r-- | src/map/npc.h | 2 | ||||
-rw-r--r-- | src/map/quest.c | 42 | ||||
-rw-r--r-- | src/map/quest.h | 34 | ||||
-rw-r--r-- | src/map/script.c | 12 |
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: { |