From 94b7b25456aa8a9de1e0f2a147d58dba6e5976dd Mon Sep 17 00:00:00 2001 From: Kisuka Date: Thu, 24 Oct 2013 07:03:46 -0700 Subject: Quest Bubbles (Actually Works Finally) --- db/const.txt | 10 +++++++ doc/script_commands.txt | 70 ++++++++++++++++++++++++++++++++----------- src/map/clif.c | 27 ++++++++++++++++- src/map/npc.h | 6 ++++ src/map/script.c | 80 ++++++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 166 insertions(+), 27 deletions(-) diff --git a/db/const.txt b/db/const.txt index af3dedbc5..d04b0d8b4 100644 --- a/db/const.txt +++ b/db/const.txt @@ -3218,6 +3218,16 @@ HAVEQUEST 0 PLAYTIME 1 HUNTING 2 +QTYPE_NONE 0x270f +QTYPE_QUEST 0x00 +QTYPE_QUEST2 0x01 +QTYPE_JOB 0x02 +QTYPE_JOB2 0x03 +QTYPE_EVENT 0x04 +QTYPE_EVENT2 0x05 +QTYPE_WARG 0x06 +QTYPE_WARG2 0x08 + FW_DONTCARE 0 FW_THIN 100 FW_EXTRALIGHT 200 diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 9969ff1a8..751db221a 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -7886,10 +7886,48 @@ that fails, the command returns an empty string instead. ========================= --------------------------------------- +*questinfo , {, }; + +This is esentially a combination of checkquest and showevent. Use this only +in an OnInit label. For the Quest ID, specify the quest ID that you want +checked if it has been started yet. + +For Icon, use one of the following: + +No Icon : QTYPE_NONE +! Quest Icon : QTYPE_QUEST +? Quest Icon : QTYPE_QUEST2 +! Job Icon : QTYPE_JOB +? Job Icon : QTYPE_JOB2 +! Event Icon : QTYPE_EVENT +? Event Icon : QTYPE_EVENT2 +Warg : QTYPE_WARG +Warg Face : QTYPE_WARG2 (Only for packetver >= 20120410) + +When a user shows up on a map, each NPC is checked for questinfo that has been set. +If questinfo is present, it will check if the quest has been started, if it has not, the bubble will appear. + +Optionally, you can also specify a Job Class if the quest bubble should only appear for a certain class. + +Example +izlude,100,100,4 script Test 844,{ + mes "[Test]"; + mes "Hello World."; + close; + + OnInit: + questinfo 1001, QTYPE_QUEST, Job_Novice; + end; +} + +--------------------------------------- + *setquest ; Place quest of in the users quest log, the state of which is "active". +If *questinfo is set, and the same ID is specified here, the icon will be cleared when the quest is set. + --------------------------------------- *completequest ; @@ -7937,27 +7975,23 @@ If parameter "HUNTING" is supplied: --------------------------------------- -*showevent , ; +*showevent ; Show a colored mark in the mini-map like "viewpoint" and an emotion on top of a NPC. This is used to indicate that a NPC has a quest or an event to -certain player/s. - -state can be: - 0 = disable ( Used to disable and remove the mark and the emotion from - the NPC. ) - 1 = exclamation emotion ( Used to show an important quest event to - certain player. ) - 2 = interrogation emotion ( Used to show an non-important quest event - to certain player. ) -Other value may cause client crashes. - -color can be: - 0 = yellow "Quest" - 1 = orange "Job" - 2 = green "Event" - 3 = an MVP flag -Other values show a transparent mark in the mini-map. +a certain player. + +Available Icons: + +Remove Icon : QTYPE_NONE +! Quest Icon : QTYPE_QUEST +? Quest Icon : QTYPE_QUEST2 +! Job Icon : QTYPE_JOB +? Job Icon : QTYPE_JOB2 +! Event Icon : QTYPE_EVENT +? Event Icon : QTYPE_EVENT2 +Warg : QTYPE_WARG +Warg Face : QTYPE_WARG2 (Only for packetver >= 20120410) ---------------------------------------- diff --git a/src/map/clif.c b/src/map/clif.c index 9c740d607..3dba530f4 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9316,6 +9316,8 @@ void clif_hercules_chsys_mjoin(struct map_session_data *sd) { /// Notification from the client, that it has finished map loading and is about to display player's character (CZ_NOTIFY_ACTORINIT). /// 007d void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { + int i; + if(sd->bl.prev != NULL) return; @@ -9624,10 +9626,33 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { skill->usave_trigger(sd); } -// Trigger skill effects if you appear standing on them + // Trigger skill effects if you appear standing on them if(!battle_config.pc_invincible_time) skill->unit_move(&sd->bl,timer->gettick(),1); + // NPC Quest / Event Icon Check [Kisuka] + #if PACKETVER >= 20090218 + for(i = 0; i < map->list[sd->bl.m].npc_num; i++) { + TBL_NPC *nd = map->list[sd->bl.m].npc[i]; + + // Make sure NPC exists and is not a warp + if(nd != NULL) + { + // Check if NPC has quest attached to it + if(nd->quest.quest_id > 0) + if(quest->check(sd, nd->quest.quest_id, HAVEQUEST) == -1) // Check if quest is not started + // Check if quest is job-specific, check is user is said job class. + if(nd->quest.hasJob == true) + { + if(sd->class_ == nd->quest.job) + clif->quest_show_event(sd, &nd->bl, nd->quest.icon, 0); + } + else { + clif->quest_show_event(sd, &nd->bl, nd->quest.icon, 0); + } + } + } + #endif } diff --git a/src/map/npc.h b/src/map/npc.h index f809cb19c..c9184b22d 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -48,6 +48,12 @@ struct npc_data { char* path;/* path dir */ enum npc_subtype subtype; int src_id; + struct { + int icon; + int quest_id; + bool hasJob; + int job; + } quest; union { struct { struct script_code *script; diff --git a/src/map/script.c b/src/map/script.c index 3c0742405..cf2ddd812 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -15453,12 +15453,68 @@ BUILDIN(readbook) Questlog script commands *******************/ +BUILDIN(questinfo) +{ + struct npc_data *nd = map->id2nd(st->oid); + int quest, icon, job; + + if( nd == NULL ) + return true; + + quest = script_getnum(st, 2); + icon = script_getnum(st, 3); + + #if PACKETVER >= 20120410 + if(icon < 0 || (icon > 8 && icon != 9999) || icon == 7) + icon = 9999; // Default to nothing if icon id is invalid. + #else + if(icon < 0 || icon > 7) + icon = 0; + else + icon = icon + 1; + #endif + + nd->quest.quest_id = quest; + nd->quest.icon = icon; + nd->quest.hasJob = false; + + if(script_hasdata(st, 4)) + { + job = script_getnum(st, 4); + + if (!pcdb_checkid(job)) + { + ShowError("questinfo: Nonexistant Job Class.\n"); + } + else + { + nd->quest.hasJob = true; + nd->quest.job = job; + } + } + + return true; +} + BUILDIN(setquest) { struct map_session_data *sd = script->rid2sd(st); + struct npc_data *nd = map->id2nd(st->oid); nullpo_retr(false,sd); + if (!nd) + return false; + quest->add(sd, script_getnum(st, 2)); + + // If questinfo is set, remove quest bubble once quest is set. + if(nd->quest.quest_id > 0) + #if PACKETVER >= 20120410 + clif->quest_show_event(sd, &nd->bl, 9999, 0); + #else + clif->quest_show_event(sd, &nd->bl, 0, 0); + #endif + return true; } @@ -15507,17 +15563,24 @@ BUILDIN(checkquest) BUILDIN(showevent) { TBL_PC *sd = script->rid2sd(st); struct npc_data *nd = map->id2nd(st->oid); - int state, color; + int icon; if( sd == NULL || nd == NULL ) return true; - state = script_getnum(st, 2); - color = script_getnum(st, 3); - - if( color < 0 || color > 3 ) - color = 0; // set default color + + icon = script_getnum(st, 2); + + #if PACKETVER >= 20120410 + if(icon < 0 || (icon > 8 && icon != 9999) || icon == 7) + icon = 9999; // Default to nothing if icon id is invalid. + #else + if(icon < 0 || icon > 7) + icon = 0; + else + icon = icon + 1; + #endif - clif->quest_show_event(sd, &nd->bl, state, color); + clif->quest_show_event(sd, &nd->bl, icon, 0); return true; } @@ -18023,12 +18086,13 @@ void script_parse_builtin(void) { BUILDIN_DEF(useatcmd, "s"), //Quest Log System [Inkfish] + BUILDIN_DEF(questinfo, "ii?"), BUILDIN_DEF(setquest, "i"), BUILDIN_DEF(erasequest, "i"), BUILDIN_DEF(completequest, "i"), BUILDIN_DEF(checkquest, "i?"), BUILDIN_DEF(changequest, "ii"), - BUILDIN_DEF(showevent, "ii"), + BUILDIN_DEF(showevent, "i"), /** * hQueue [Ind/Hercules] -- cgit v1.2.3-70-g09d2