diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/clif.c | 25 | ||||
-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/pc.h | 3 | ||||
-rw-r--r-- | src/map/quest.c | 42 | ||||
-rw-r--r-- | src/map/quest.h | 34 | ||||
-rw-r--r-- | src/map/refine.c | 2 | ||||
-rw-r--r-- | src/map/script.c | 66 |
11 files changed, 171 insertions, 226 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index 5228f06a3..b93274d3d 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 } @@ -12851,10 +12843,19 @@ static void clif_parse_NpcAmountInput(int fd, struct map_session_data *sd) int npcid = RFIFOL(fd,2); int amount = RFIFOL(fd,6); - if (amount >= 0) + if (amount < sd->npc_amount_min) { + sd->npc_amount = sd->npc_amount_min; + sd->npc_input_capped_range = -1; + } + else if (amount > sd->npc_amount_max) { + sd->npc_amount = sd->npc_amount_max; + sd->npc_input_capped_range = 1; + } + else { sd->npc_amount = amount; - else - sd->npc_amount = 0; + sd->npc_input_capped_range = 0; + } + npc->scriptcont(sd, npcid, false); } 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/pc.h b/src/map/pc.h index 42c9d204e..7c89f7f32 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -274,6 +274,9 @@ struct map_session_data { int npc_item_flag; //Marks the npc_id with which you can change equipments during interactions with said npc (see script command enable_itemuse) int npc_menu; // internal variable, used in npc menu handling int npc_amount; + int npc_amount_min; + int npc_amount_max; + int npc_input_capped_range; struct script_state *st; char npc_str[CHATBOX_SIZE]; // for passing npc input box text to script engine int npc_timer_id; //For player attached npc timers. [Skotlex] 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/refine.c b/src/map/refine.c index 1ff893c56..4fe6e73c4 100644 --- a/src/map/refine.c +++ b/src/map/refine.c @@ -528,7 +528,7 @@ static int refine_readdb_refine_libconfig_sub(struct config_setting_t *r, const chance[i][j] = 100; // default value for all rates. struct config_setting_t *t = NULL; - for (int i = 0; (t = libconfig->setting_get_elem(rate, i++)) != NULL && config_setting_is_group(t); ++i) { + for (int i = 0; (t = libconfig->setting_get_elem(rate, i)) != NULL && config_setting_is_group(t); ++i) { int level = 0, i32; char *rlvl = config_setting_name(t); memset(&lv, 0, sizeof(lv)); diff --git a/src/map/script.c b/src/map/script.c index fb50a4ba3..478cc8e1d 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -6948,59 +6948,60 @@ static BUILDIN(jobname) return true; } -/// Get input from the player. -/// For numeric inputs the value is capped to the range [min,max]. Returns 1 if -/// the value was higher than 'max', -1 if lower than 'min' and 0 otherwise. -/// For string inputs it returns 1 if the string was longer than 'max', -1 is -/// shorter than 'min' and 0 otherwise. -/// -/// input(<var>{,<min>{,<max>}}) -> <int> +/* + * Get input from the player. + * For numeric inputs the value is capped to the range [min,max]. Returns 1 if + * the value was higher than 'max', -1 if lower than 'min' and 0 otherwise. + * For string inputs it returns 1 if the string was longer than 'max', -1 is + * shorter than 'min' and 0 otherwise. + * + * input(<var>{,<min>{,<max>}}) -> <int> + */ static BUILDIN(input) { - struct script_data* data; - int64 uid; - const char* name; - int min; - int max; struct map_session_data *sd = script->rid2sd(st); if (sd == NULL) return true; - data = script_getdata(st,2); - if( !data_isreference(data) ) { + struct script_data *data = script_getdata(st, 2); + if (!data_isreference(data)) { ShowError("script:input: not a variable\n"); script->reportdata(data); st->state = END; return false; } - uid = reference_getuid(data); - name = reference_getname(data); - min = (script_hasdata(st,3) ? script_getnum(st,3) : script->config.input_min_value); - max = (script_hasdata(st,4) ? script_getnum(st,4) : script->config.input_max_value); + + int64 uid = reference_getuid(data); + const char *name = reference_getname(data); + int min = (script_hasdata(st, 3) ? script_getnum(st, 3) : script->config.input_min_value); + int max = (script_hasdata(st, 4) ? script_getnum(st, 4) : script->config.input_max_value); #ifdef SECURE_NPCTIMEOUT sd->npc_idle_type = NPCT_WAIT; #endif - if( !sd->state.menu_or_input ) { + if (!sd->state.menu_or_input) { // first invocation, display npc input box sd->state.menu_or_input = 1; st->state = RERUNLINE; - if( is_string_variable(name) ) - clif->scriptinputstr(sd,st->oid); - else - clif->scriptinput(sd,st->oid); + if (is_string_variable(name)) { + clif->scriptinputstr(sd, st->oid); + } else { + sd->npc_amount_min = min; + sd->npc_amount_max = max; + clif->scriptinput(sd, st->oid); + } } else { // take received text/value and store it in the designated variable sd->state.menu_or_input = 0; if (is_string_variable(name)) { int len = (int)strlen(sd->npc_str); - script->set_reg(st, sd, uid, name, sd->npc_str, script_getref(st,2)); + script->set_reg(st, sd, uid, name, sd->npc_str, script_getref(st, 2)); script_pushint(st, (len > max ? 1 : len < min ? -1 : 0)); } else { int amount = sd->npc_amount; script->set_reg(st, sd, uid, name, (const void *)h64BPTRSIZE(cap_value(amount,min,max)), script_getref(st,2)); - script_pushint(st, (amount > max ? 1 : amount < min ? -1 : 0)); + script_pushint(st, sd->npc_input_capped_range); } st->state = RUN; } @@ -13919,7 +13920,8 @@ static BUILDIN(failedremovecards) if (sd->status.inventory[i].card[c] > 0 && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD) { cardflag = 1; - sd->status.inventory[i].card[c] = 0; + if (typefail == 1) + sd->status.inventory[i].card[c] = 0; if (typefail == 2) { // add cards to inventory, clear int flag; @@ -21260,7 +21262,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); @@ -21272,7 +21273,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; } @@ -21290,15 +21293,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: { |