questinfo requirement update (#4168)

* The <quest ID> is now removed, all the conditions are handled by a <condition> argument. The <condition> is using the achievement_check_condition (like in achievement_db.yml) so any condition (in theory) can be used to display the icon.
* A new script command has been added to refresh the bubble for the given player anytime.

Thanks to @aleos89 and @secretdataz for the review!
This commit is contained in:
Atemo
2019-10-06 17:15:46 +02:00
committed by GitHub
parent df6385fd4a
commit b412c4fcab
20 changed files with 553 additions and 836 deletions

View File

@@ -3682,15 +3682,10 @@ void map_data_copy(struct map_data *dst_map, struct map_data *src_map) {
dst_map->skill_duration.insert(src_map->skill_duration.begin(), src_map->skill_duration.end());
dst_map->zone = src_map->zone;
dst_map->qi_count = 0;
dst_map->qi_data = NULL;
// Mimic questinfo
if (src_map->qi_count) {
dst_map->qi_count = src_map->qi_count;
CREATE(dst_map->qi_data, struct questinfo, dst_map->qi_count);
memcpy(dst_map->qi_data, src_map->qi_data, dst_map->qi_count * sizeof(struct questinfo));
}
if (!src_map->qi_data.empty())
src_map->qi_data = dst_map->qi_data;
}
/**
@@ -3905,8 +3900,6 @@ int map_readallmaps (void)
memset(&mapdata->save, 0, sizeof(struct point));
mapdata->damage_adjust = {};
mapdata->qi_count = 0;
mapdata->qi_data = NULL;
mapdata->channel = NULL;
}
@@ -4353,110 +4346,31 @@ int log_sql_init(void)
return 0;
}
struct questinfo *map_add_questinfo(int m, struct questinfo *qi) {
unsigned short i;
void map_remove_questinfo(int m, struct npc_data *nd) {
struct map_data *mapdata = map_getmapdata(m);
struct s_questinfo *qi;
/* duplicate, override */
for(i = 0; i < mapdata->qi_count; i++) {
if( &mapdata->qi_data[i] && mapdata->qi_data[i].nd == qi->nd && mapdata->qi_data[i].quest_id == qi->quest_id)
break;
}
nullpo_retv(nd);
nullpo_retv(mapdata);
if( i == mapdata->qi_count )
RECREATE(mapdata->qi_data, struct questinfo, ++mapdata->qi_count);
else { // clear previous criteria on override
if (mapdata->qi_data[i].jobid)
aFree(mapdata->qi_data[i].jobid);
mapdata->qi_data[i].jobid = NULL;
mapdata->qi_data[i].jobid_count = 0;
if (mapdata->qi_data[i].req)
aFree(mapdata->qi_data[i].req);
mapdata->qi_data[i].req = NULL;
mapdata->qi_data[i].req_count = 0;
}
memcpy(&mapdata->qi_data[i], qi, sizeof(struct questinfo));
return &mapdata->qi_data[i];
}
bool map_remove_questinfo(int m, struct npc_data *nd) {
unsigned short i, c;
struct map_data *mapdata = map_getmapdata(m);
for(i = 0; i < mapdata->qi_count; i++) {
struct questinfo *qi = &mapdata->qi_data[i];
if( qi->nd == nd ) {
if (qi->jobid)
aFree(qi->jobid);
qi->jobid = NULL;
qi->jobid_count = 0;
if (qi->req)
aFree(qi->req);
qi->req = NULL;
qi->req_count = 0;
memset(&mapdata->qi_data[i], 0, sizeof(mapdata->qi_data[i]));
for (int i = 0; i < mapdata->qi_data.size(); i++) {
qi = &mapdata->qi_data[i];
if (qi && qi->nd == nd) {
script_free_code(qi->condition);
mapdata->qi_data.erase(mapdata->qi_data.begin() + i);
}
}
// Move next data to empty slot
for(i = 0, c = 0; i < mapdata->qi_count; i++) {
struct questinfo *qi = &mapdata->qi_data[i];
if (!qi || !qi->nd)
continue;
if (i != c) {
mapdata->qi_data[c] = mapdata->qi_data[i];
memset(&mapdata->qi_data[i], 0, sizeof(mapdata->qi_data[i]));
}
c++;
}
if (!(mapdata->qi_count = c)) {
aFree(mapdata->qi_data);
mapdata->qi_data = NULL;
}
else
RECREATE(mapdata->qi_data, struct questinfo, mapdata->qi_count);
return true;
}
static void map_free_questinfo(struct map_data *mapdata) {
unsigned short i;
if (!mapdata)
return;
nullpo_retv(mapdata);
for(i = 0; i < mapdata->qi_count; i++) {
if (mapdata->qi_data[i].jobid)
aFree(mapdata->qi_data[i].jobid);
mapdata->qi_data[i].jobid = NULL;
mapdata->qi_data[i].jobid_count = 0;
if (mapdata->qi_data[i].req)
aFree(mapdata->qi_data[i].req);
mapdata->qi_data[i].req = NULL;
mapdata->qi_data[i].req_count = 0;
}
aFree(mapdata->qi_data);
mapdata->qi_data = NULL;
mapdata->qi_count = 0;
}
struct questinfo *map_has_questinfo(int m, struct npc_data *nd, int quest_id) {
unsigned short i;
struct map_data *mapdata = map_getmapdata(m);
for (i = 0; i < mapdata->qi_count; i++) {
struct questinfo *qi = &mapdata->qi_data[i];
if (qi->nd == nd && qi->quest_id == quest_id) {
return qi;
}
for (const auto &it : mapdata->qi_data) {
if (it.condition)
script_free_code(it.condition);
}
return NULL;
mapdata->qi_data.clear();
}
/**