Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion agent_docs/quests.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ itself ("Etc item inventory is full."). `startscript`/
`endscript` are allowed only for scripts the server implements
(`game_data::quests::SCRIPTS`: `q1021s`, `q1021e`, Bartos's secret
`q4647e`, Garnox's pet evolutions `q8185e`, `q8189e` and `q4659e` (see
[Pets](./pets.md)), Meren's Maker lessons, Dyle's informants, the baby dragon and Captain Al's family lessons below); those steps go through
[Pets](./pets.md)), Meren's Maker lessons, Dyle's informants, Reef, the baby dragon and Captain Al's family lessons below); those steps go through
QUEST_ACTION 4/5 and the server drives the dialogue (see
[NPC dialogue](./npc-dialogue.md)). `money` pays (or, if negative, takes)
mesos on completion; a quest that takes mesos needs them held, or the
Expand Down Expand Up @@ -260,6 +260,12 @@ list. `game_data::quests::FINISHED_BY_START_SCRIPT` lets these four through
without a completion NPC. The can's and the informants' lines are
unsourced and stay placeholder (`dyle.*`).

"Reef's Gratitude" (2228) works the same way: once Faust is beaten (2227),
Reef (1032108, in 910100001) thanks the player through a start script
(`q2228s`) that completes the quest at once and gives the data's 8 fame
(`Act/1 pop`, through `Effect::GainFame`, since `FinishQuest` gives no
`Act/1` rewards). Its line is a placeholder (`reef.thanks`).

"The Remnants of Horned Tail" (3714) works the same way. Nine Spirit's Baby
Dragon (2081011), in the nest past Leafre's `dragonNest` portal (240040612,
open once 3706 is done), has a start script (`q3714s`) and no end. It
Expand Down
1 change: 1 addition & 0 deletions game-data/placeholder_text.toml
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,7 @@
"nine_spirit.baby.hatched" = "[placeholder] The egg hatches on the nest. The baby dragon coughs up a Dragon Stone and asks you to take it away."
"nine_spirit.baby.stone_held" = "[placeholder] The Dragon Stone in your bag glows brighter here, and the baby dragon glares at it."
"nine_spirit.baby.full" = "[placeholder] You need a free USE slot for the Dragon Stone."
"reef.thanks" = "[placeholder] Reef thanks you for beating Faust. His spirit can rest at last."
"family.captain_al.junior.done" = "[placeholder] Captain Al is pleased you have taken a Junior, and teaches you how a Senior earns Rep."
"family.captain_al.junior.not_yet" = "[placeholder] Captain Al says you have no Junior yet. Add one from the Family window."
"family.captain_al.rep.done" = "[placeholder] Captain Al sees you have earned 1,000 Rep, and praises how you look after your Juniors."
Expand Down
1 change: 1 addition & 0 deletions game-data/server_content.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1444,6 +1444,7 @@ unsourced = [
"nine_spirit.baby.hatched",
"nine_spirit.baby.stone_held",
"nine_spirit.baby.full",
"reef.thanks",
"family.captain_al.junior.done",
"family.captain_al.junior.not_yet",
"family.captain_al.rep.done",
Expand Down
13 changes: 7 additions & 6 deletions game-data/src/quests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,16 @@ pub const INERT_END_REQUIREMENTS: &[&str] = &["start", "end"];
/// Quest scripts (`startscript`/`endscript`) the server implements. A quest
/// naming any other script is unsupported.
pub const SCRIPTS: &[&str] = &[
"q1021s", "q1021e", "q2214e", "q2215e", "q2232e", "q2233e", "q2234e", "q2216s", "q2217s",
"q2218s", "q2219s", "q3714s", "q4647e", "q4659e", "q6030e", "q6031e", "q6032e", "q6033e",
"q6036e", "q8185e", "q8189e",
"q1021s", "q1021e", "q2214e", "q2215e", "q2228s", "q2232e", "q2233e", "q2234e", "q2216s",
"q2217s", "q2218s", "q2219s", "q3714s", "q4647e", "q4659e", "q6030e", "q6031e", "q6032e",
"q6033e", "q6036e", "q8185e", "q8189e",
];
/// Quests with nothing to complete them by (an empty `Check/1`) whose start
/// script completes them as it starts them (`Effect::FinishQuest`): JM's
/// informants (2216-2219), each heard from once, and the Remnants of Horned
/// Tail (3714), once for each Nine Spirit's Egg.
pub const FINISHED_BY_START_SCRIPT: &[i16] = &[2216, 2217, 2218, 2219, 3714];
/// informants (2216-2219), each heard from once, Reef's thanks for Faust
/// (2228), and the Remnants of Horned Tail (3714), once for each Nine
/// Spirit's Egg.
pub const FINISHED_BY_START_SCRIPT: &[i16] = &[2216, 2217, 2218, 2219, 2228, 3714];
/// Meren's Maker classes (quests 6030-6032) and the quest they make up
/// (6029) share 6029's quest-info string, one digit per class: `Act/0 info`
/// starts it at "000", a class starts only while its own digit is 0
Expand Down
5 changes: 5 additions & 0 deletions game-data/src/server_content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,10 @@ pub mod keys {
pub const NINE_SPIRIT_STONE_HELD: &str = "nine_spirit.baby.stone_held";
pub const NINE_SPIRIT_FULL: &str = "nine_spirit.baby.full";

/// Reef's Gratitude (quest 2228, `q2228s`): Reef (NPC 1032108) thanks
/// the player for beating Faust. No licensed script has the text.
pub const REEF_THANKS: &str = "reef.thanks";

/// Captain Al's lessons in leading a family (quests 2232-2234), each
/// ended by his script (NPC 1002103, `q2232e`-`q2234e`): done, then not
/// yet, for a junior taken, 1,000 Rep earned, and 2,000 earned with the
Expand Down Expand Up @@ -3004,6 +3008,7 @@ mod tests {
.chain(&keys::CAPTAIN_AL_REP)
.chain(&keys::CAPTAIN_AL_ENTITLEMENT)
.chain(&[
keys::REEF_THANKS,
keys::NINE_SPIRIT_HATCHED,
keys::NINE_SPIRIT_STONE_HELD,
keys::NINE_SPIRIT_FULL,
Expand Down
1 change: 1 addition & 0 deletions game-data/supported_quests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@
2225
2226
2227
2228
2229
2231
2232
Expand Down
48 changes: 48 additions & 0 deletions integration-harness/tests/reef_gratitude.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//! Reef's Gratitude (2228): once Faust is beaten (2227), Reef's start script
//! thanks the player, which completes the quest at once, with the data's 8
//! fame.

use integration_harness::database::{set_job, set_quest};
use integration_harness::hunting::walk_to;
use integration_harness::preconditions::load_harness_config_or_fail;
use integration_harness::quests::{answer, build_quest_action, SCRIPT_START};
use integration_harness::trace::{step, warp, Trace};
use integration_harness::{login_to_world_session, relogin};
use std::time::Duration;

const QUEST: i16 = 2228;
const REEF: i32 = 1_032_108;
const REEFS_MAP: i32 = 910_100_001;

#[tokio::test]
async fn reef_thanks_the_player_with_eight_fame() {
let config = load_harness_config_or_fail().await;
let m = config.character_name.clone();
let id = login_to_world_session(&config)
.await
.expect("first login failed")
.character_id;
tokio::time::sleep(Duration::from_millis(500)).await;
set_job(id, 200, 45, 100)
.await
.expect("a level 45 magician");
set_quest(id, 2227, 2, "").await.expect("Faust beaten");

let mut session = relogin(&config).await;
let c = &mut session.connection;
let mut trace = Trace::default();
assert_eq!(warp(c, REEFS_MAP, "", &mut trace).await, REEFS_MAP);
step(c, &m, walk_to(33, 209)).await;
let t = step(c, &m, build_quest_action(SCRIPT_START, QUEST, REEF)).await;
assert_eq!(t.prompts, [(REEF, 0)], "Reef speaks");
let t = step(c, &m, answer(0, 1, None)).await;
assert_eq!(t.progress, [(QUEST, 2)], "done at once");
assert_eq!(t.fame_gains, [8]);
// Once.
let t = step(c, &m, build_quest_action(SCRIPT_START, QUEST, REEF)).await;
assert!(t.prompts.is_empty() && t.progress.is_empty());
drop(session);

let restored = relogin(&config).await;
assert_eq!(restored.quests.get(&QUEST), Some(&2));
}
21 changes: 21 additions & 0 deletions net/src/npc_scripts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2341,6 +2341,7 @@ impl NpcScript {
"q2217s" => informant(player, 1),
"q2218s" => informant(player, 2),
"q2219s" => informant(player, 3),
"q2228s" => Some(reef()),
"q3714s" => Some(baby_dragon(player)),
"q6030e" => Some(maker_class(CARSON, keys::MAKER_ALCHEMY, 6030)),
"q6031e" => Some(maker_class(HUGHES, keys::MAKER_SCIENCE, 6031)),
Expand Down Expand Up @@ -2788,6 +2789,17 @@ fn trash_can(player: &Player, lost: bool, hour: u8) -> NpcScript {
script
}

/// `q2228s`, Reef's Gratitude: Reef's spirit, at rest once Faust is beaten
/// (2227), thanks the player, which completes the quest as it starts, with
/// the data's 8 fame (`Act/1 pop`, which a start does not give).
fn reef() -> NpcScript {
let mut script = NpcScript::new(REEF, vec![Page::Say(text(keys::REEF_THANKS))]);
script.on_end = vec![Effect::FinishQuest(2228), Effect::GainFame(8)];
script
}

/// Reef, in 910100001.
const REEF: i32 = 1032108;
/// Captain Al, in Lith Harbor (104000000) and Orbis Park (200000200).
const CAPTAIN_AL: i32 = 1002103;
/// Captain Al's end scripts ([`NpcScript::for_family_quest`]).
Expand Down Expand Up @@ -9995,6 +10007,15 @@ mod tests {
assert_eq!(read_through(early), (1052006, heard(2219)));
}

#[test]
fn reef_thanks_the_player_with_eight_fame() {
let script = NpcScript::for_quest("q2228s", &with_quests(&[(2227, true)])).unwrap();
assert_eq!(
read_through(script),
(REEF, vec![Effect::FinishQuest(2228), Effect::GainFame(8)])
);
}

#[test]
fn the_baby_dragon_trades_each_egg_for_a_dragon_stone() {
let mut player = with_quests(&[(3706, true)]);
Expand Down
2 changes: 2 additions & 0 deletions net/src/scripts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,8 @@ pub enum Effect {
/// Up to the most a player may hold.
GainMeso(i32),
GainExp(i32),
/// Fame, shown in the chat log as a quest's is.
GainFame(i16),
StartQuest(i16),
CompleteQuest(i16),
/// Start a quest not yet started and complete it at once: a start script
Expand Down
9 changes: 9 additions & 0 deletions runtime/src/actor/client/npc_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,15 @@ impl ClientActor {
gain_exp(&mut next, *amount, &mut packets)?;
changed = true;
}
Effect::GainFame(amount) => {
next.stats.fame = next.stats.fame.saturating_add(*amount);
changed = true;
packets.push(stat::build_stat_update(
false,
&[StatUpdate::Fame(next.stats.fame)],
)?);
packets.push(quest::build_fame_gain_in_chat(*amount)?);
}
Effect::TakeFirstJob(job)
| Effect::TakeSecondJob(job)
| Effect::TakeThirdJob(job)
Expand Down
Loading