Skip to content

Commit

Permalink
Added a new way to show when we have multiple guide quests.
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamKyle committed Aug 23, 2024
1 parent cb8c3e6 commit f7b747f
Show file tree
Hide file tree
Showing 6 changed files with 429 additions and 217 deletions.
33 changes: 3 additions & 30 deletions app/Game/GuideQuests/Controllers/Api/GuideQuestsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public function handInQuest(User $user, GuideQuest $guideQuest): JsonResponse
}

return response()->json([
'message' => 'Oh christ, something is wrong. Quick call The Creator!',
]);
'message' => 'Oh christ, something is wrong. Quick call The Creator! Submit a bug report indicating the guide quest failed to load.',
], 422);
}

/**
Expand All @@ -46,34 +46,7 @@ protected function getNextQuest(Character $character, string $message = ''): Jso
{
$data = $this->guideQuestService->fetchQuestForCharacter($character);

if (! is_null($data)) {

$quest = $data['quest'];

$quest->intro_text = nl2br($quest->intro_text);
$quest->instructions = nl2br($quest->instructions);
$quest->desktop_instructions = nl2br($quest->desktop_instructions);
$quest->mobile_instructions = nl2br($quest->mobile_instructions);

$response = [
'quest' => $quest,
'can_hand_in' => $data['can_hand_in'],
'completed_requirements' => $data['completed_requirements'],
];

if ($message !== '') {
$response['message'] = $message;
}

return response()->json($response);
}

$response = [
'quest' => null,
'can_hand_in' => false,
'completed_requirements' => [],
];

return response()->json($response);
return response()->json([...$data, 'message' => $message]);
}
}
44 changes: 34 additions & 10 deletions app/Game/GuideQuests/Services/GuideQuestService.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,32 @@ public function __construct(GuideQuestRequirementsService $guideQuestRequirement
public function fetchQuestForCharacter(Character $character): ?array
{

$quest = $this->fetchNextGuideQuest($character);
$quests = $this->fetchNextGuideQuest($character);

if (is_null($quest)) {
if (is_null($quests)) {
return null;
}

$canHandIn = $this->canHandInQuest($character, $quest, true);
$canHandIn = [];
$completedAttributes = [];

foreach ($quests as $quest) {
$canHandInQuest = $this->canHandInQuest($character, $quest, true);

$canHandIn[] = [
'quest_id' => $quest->id,
'can_hand_in' => $canHandInQuest,
];

$completedAttributes[] = [
'quest_id' => $quest->id,
'completed_requirements' => $this->completedAttributes,
];
}

return [
'quest' => $quest,
'completed_requirements' => $this->completedAttributes,
'quests' => $quests,
'completed_requirements' => $completedAttributes,
'can_hand_in' => $canHandIn,
];
}
Expand Down Expand Up @@ -182,7 +197,7 @@ public function canHandInQuest(Character $character, GuideQuest $quest, bool $ig
return false;
}

protected function fetchNextGuideQuest(Character $character): ?GuideQuest
protected function fetchNextGuideQuest(Character $character): array
{

$winterEvent = Event::where('type', EventType::WINTER_EVENT)->first();
Expand Down Expand Up @@ -210,19 +225,28 @@ protected function fetchNextGuideQuest(Character $character): ?GuideQuest
}
}

if (! is_null($delusionalEvent) && is_null($nextGuideQuest)) {
if (!is_null($delusionalEvent) && is_null($nextGuideQuest)) {
$delusionalEventQuest = GuideQuest::where('only_during_event', EventType::DELUSIONAL_MEMORIES_EVENT)->whereNull('parent_id')->first();

if (! is_null($delusionalEventQuest)) {
$nextGuideQuest = $this->fetchNextEventQuest($character, $delusionalEventQuest);
}
}

if (! is_null($nextGuideQuest)) {
return $nextGuideQuest;
$regularGuideQuest = $this->fetchNextRegularGuideQuest($character);
$newFeatureGuideQuest = $nextGuideQuest;

$guideQuests = [];

if (!is_null($regularGuideQuest)) {
$guideQuests[] = $regularGuideQuest;
}

if (!is_null($newFeatureGuideQuest)) {
$guideQuests[] = $newFeatureGuideQuest;
}

return $this->fetchNextRegularGuideQuest($character);
return $guideQuests;
}

protected function fetchNextRegularGuideQuest(Character $character): ?GuideQuest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export default class GuideQuestAjax {
) {
let guideQuestId = 0;

if (component.state.quest_data !== null) {
guideQuestId = component.state.quest_data.id;
if (component.state.selected_quest_data_to_show !== null) {
guideQuestId = component.state.selected_quest_data_to_show.id;
}

const route = this.getRoute(
Expand Down Expand Up @@ -60,15 +60,25 @@ export default class GuideQuestAjax {
.doAjaxCall(
action,
(result: AxiosResponse) => {
let selectedGuideQuest = null;

if (result.data.quests.length <= 1) {
selectedGuideQuest = result.data.quests[0];
}

console.log(result.data.quests);

component.setState({
loading: false,
quest_data: result.data.quest,
quest_data: result.data.quests,
can_hand_in: result.data.can_hand_in,
completed_requirements:
result.data.completed_requirements,
selected_quest_data_to_show: selectedGuideQuest,
});
},
(error: AxiosError) => {
console.log(error);
component.setState({
loading: false,
});
Expand Down Expand Up @@ -98,13 +108,20 @@ export default class GuideQuestAjax {
.doAjaxCall(
action,
(result: AxiosResponse) => {
let selectedGuideQuest = null;

if (result.data.quests.length <= 1) {
selectedGuideQuest = result.data.quests[0];
}

component.setState({
is_handing_in: false,
quest_data: result.data.quest,
quest_data: result.data.quests,
can_hand_in: result.data.can_hand_in,
success_message: result.data.message,
completed_requirements:
result.data.completed_requirements,
selected_quest_data_to_show: selectedGuideQuest,
});
},
(error: AxiosError) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
import React from "react";
import InfoAlert from "../../../../game/components/ui/alerts/simple-alerts/info-alert";
import SuccessAlert from "../../../../game/components/ui/alerts/simple-alerts/success-alert";
import DangerAlert from "../../../../game/components/ui/alerts/simple-alerts/danger-alert";
import TabLayout from "../components/tab-labout";
import clsx from "clsx";
import {
buildValueLink,
getRequirementKey,
guideQuestLabelBuilder,
} from "../lib/guide-quest-label-builder";
import RequiredListItem from "../components/required-list-item";
import { questRewardKeys } from "../lib/guide-quests-rewards";
import RewardListItem from "../components/reward-list-item";
import GuideQuest from "../components/definitions/guide-quest";

interface GuideQuestDetailsProps {
guide_quest: GuideQuest;
completed_requirements: string[] | [];
close_message: () => void;
success_message: string | null;
error_message: string | null;
view_port: number;
}

export default class GuideQuestDetails extends React.Component<GuideQuestDetailsProps> {
constructor(props: GuideQuestDetailsProps) {
super(props);
}

fetchRequiredKeys(): string[] {
if (this.props.guide_quest === null) {
return ["UNKNOWN"];
}

return Object.keys(this.props.guide_quest).filter((key: string) => {
if (this.props.guide_quest !== null) {
return (
(key.startsWith("required_") ||
key.startsWith("secondary_")) &&
this.props.guide_quest[key] !== null
);
}
});
}

buildRequirementsList(): JSX.Element[] | [] {
const requirementsList: JSX.Element[] = [];

this.fetchRequiredKeys().forEach((key: string) => {
if (this.props.guide_quest === null) {
return [];
}

let label = guideQuestLabelBuilder(key, this.props.guide_quest);

if (label !== null) {
const requiredKey = getRequirementKey(key);
const value = this.props.guide_quest[requiredKey];

const matchingCompletedRequirements: any = this.props.completed_requirements.filter((completedRequirements: any) => {
return completedRequirements.quest_id === this.props.guide_quest.id
});

let completedRequirements: string[] = [];

if (matchingCompletedRequirements.length > 0) {
completedRequirements = matchingCompletedRequirements[0].completed_requirements;
}

const isFinished =
completedRequirements.includes(key) ||
completedRequirements.includes(requiredKey);

requirementsList.push(
<RequiredListItem
key={key}
label={label}
isFinished={isFinished}
requirement={buildValueLink(
value,
key,
this.props.guide_quest,
)}
/>,
);
}
});

return requirementsList;
}

buildRewardsItems(): JSX.Element[] | [] {
const items: JSX.Element[] = [];

questRewardKeys().forEach((key: string) => {
if (this.props.guide_quest === null) {
return [];
}

if (this.props.guide_quest[key] !== null) {
const label = key
.split("_")
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ");

items.push(
<RewardListItem
label={label}
value={this.props.guide_quest[key]}
/>,
);
}
});

return items;
}

render() {

return (
<>
<InfoAlert
additional_css={clsx("my-4", {
hidden:
this.props.guide_quest.only_during_event === null &&
this.props.guide_quest.unlock_at_level === null,
})}
>
<p>
These types of Guide Quests only pop up during special
events or when new features are unlocked at specific
levels. You can continue your regular guide quests once
you finish this one and any "child" quests that might
folow after it.
</p>
</InfoAlert>
{this.props.success_message !== null ? (
<SuccessAlert close_alert={this.props.close_message}>
{this.props.success_message}
</SuccessAlert>
) : null}

{this.props.error_message !== null ? (
<DangerAlert close_alert={this.props.close_message}>
{this.props.error_message}
</DangerAlert>
) : null}

<div className={"mt-2"}>
<div className="grid md:grid-cols-2 gap-2">
<div>
<h3 className="mb-2">Required to complete</h3>
<ul className="my-4 list-disc ml-[18px]">
{this.buildRequirementsList()}
</ul>
</div>
<div className="block md:hidden border-b-2 border-b-gray-300 dark:border-b-gray-600 my-3"></div>
<div>
<h3 className="mb-2">Rewards</h3>
<ul className="list-disc ml-[18px]">
{this.buildRewardsItems()}
</ul>
</div>
</div>
</div>

<div className="border-b-2 border-b-gray-300 dark:border-b-gray-600 my-3"></div>

{this.props.guide_quest.faction_points_per_kill !== null ? (
<p className="text-blue-700 dark:text-blue-400">
You have been given an additional{" "}
{this.props.guide_quest.faction_points_per_kill} Faction
Points per kill for this quest.
</p>
) : null}

<TabLayout
intro_text={this.props.guide_quest.intro_text}
instructions={this.props.guide_quest.instructions}
desktop_instructions={
this.props.guide_quest.desktop_instructions
}
mobile_instructions={
this.props.guide_quest.mobile_instructions
}
is_small={this.props.view_port < 1600}
/>

<p className={"mt-4 mb-4"}>
The Hand in button will become available when you meet the
requirements. Unless exploration is running.
</p>

<p className={"mt-4 mb-4"}>
You can click the top right button in the header called
Guide Quests to re-open this modal. You can also see
previous Guide Quests by opening the top left menu,
selecting Quest Log and then selecting Completed Guide
Quests.
</p>
</>
);
}
}
Loading

0 comments on commit f7b747f

Please sign in to comment.