Add quest widgets

This commit is contained in:
KingRainbow44 2023-05-18 22:11:30 -04:00
parent b6b9d3d744
commit 900d7fa200
No known key found for this signature in database
GPG Key ID: FC2CB64B00D257BE
6 changed files with 254 additions and 0 deletions

View File

@ -16,6 +16,9 @@
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.8.0",
"react-d3-tree": "^3.6.1",
"react-collapsible": "^2.10.0",
"react-virtualized": "^9.22.3",
"events": "^3.3.0"

View File

@ -6,6 +6,8 @@ import scenes from "@data/scenes.csv";
import quests from "@data/quests.csv";
import items from "@data/items.csv";
import type { RawNodeDatum } from "react-d3-tree";
import { Quality, ItemType, ItemCategory, SceneType } from "@backend/types";
import type { MainQuest, Command, Avatar, Item, Scene, Entity, Quest } from "@backend/types";
@ -209,3 +211,41 @@ export function listMainQuests(): MainQuestDump[] {
export function getMainQuestFor(quest: Quest): MainQuest {
return allMainQuests[quest.mainId];
}
/**
* Fetches all quests for a main quest.
*
* @param mainQuest The main quest to fetch quests for.
*/
export function listSubQuestsFor(mainQuest: MainQuest): Quest[] {
return listQuests()
.filter((quest) => quest.mainId == mainQuest.id);
}
/*
* Tree conversion methods.
*/
/**
* Converts a quest to a tree.
*
* @param mainQuest The main quest to convert.
*/
export function questToTree(mainQuest: MainQuest): RawNodeDatum {
return {
name: mainQuest.title,
attributes: {
id: mainQuest.id
},
children: listSubQuestsFor(mainQuest)
.map((quest) => {
return {
name: quest.id.toString(),
attributes: {
description: quest.description
},
children: []
} as RawNodeDatum;
})
};
}

View File

@ -0,0 +1,54 @@
.NormalQuest {
display: flex;
align-items: center;
justify-content: space-between;
width: 431px;
height: 100%;
min-width: 100px;
min-height: 25px;
max-height: 53px;
background-color: var(--quest-unselected);
padding: 11px 20px 11px 20px;
box-sizing: border-box;
p {
user-select: none;
cursor: pointer;
}
}
.NormalQuest[datatype="right"] {
margin-left: auto;
margin-right: 0;
}
.NormalQuest:hover {
background-color: var(--quest-selected);
p {
color: var(--qt-selected);
}
}
.NormalQuest_Info {
display: flex;
flex-direction: column;
:nth-child(1) {
font-size: 16px;
color: var(--qt-unselected);
}
:nth-child(2) {
font-size: 13px;
color: var(--qt2-unselected);
}
}
.NormalQuest_Icon {
font-size: 16px;
color: var(--quest-accent);
}

View File

@ -0,0 +1,65 @@
.PrimaryQuest {
display: flex;
flex-direction: column;
height: min-content;
}
.PrimaryQuest_List {
display: flex;
flex-direction: column;
width: 97%;
margin-left: auto;
margin-right: 5px;
gap: 8px;
padding: 8px 8px 8px 8px;
background-color: var(--primary-color);
}
/* Trigger related CSS. */
.Trigger {
display: flex;
flex-direction: row;
gap: 10px;
padding: 10px 10px 10px 10px;
box-sizing: border-box;
width: 461px;
height: 100%;
min-width: 100px;
min-height: 25px;
max-height: 60px;
background-color: var(--pq-bg);
p {
user-select: none;
cursor: pointer;
}
}
.Trigger_Icon {
font-size: 20px;
padding-top: 5px;
color: var(--pq-text);
}
.Trigger_Info {
display: flex;
flex-direction: column;
:nth-child(1) {
font-size: 16px;
color: var(--pq-text);
}
:nth-child(2) {
font-size: 14px;
color: var(--pq-text2);
}
}

View File

@ -0,0 +1,38 @@
import React from "react";
import { IoLocationSharp } from "react-icons/io5"
import type { Quest } from "@backend/types";
import "@css/widgets/quest/NormalQuest.scss";
interface IProps {
quest: Quest;
right?: boolean;
}
class NormalQuest extends React.PureComponent<IProps> {
constructor(props: IProps) {
super(props);
}
render() {
const { quest } = this.props;
return (
<div
className={"NormalQuest"}
datatype={this.props.right ? "right" : "left"}
>
<div className={"NormalQuest_Info"}>
<p className={"font-bold"}>{quest.description}</p>
<p>ID: {quest.id} | Main: {quest.mainId}</p>
</div>
<IoLocationSharp className={"NormalQuest_Icon"} />
</div>
);
}
}
export default NormalQuest;

View File

@ -0,0 +1,54 @@
import React from "react";
import { GiSupersonicArrow } from "react-icons/gi";
import Collapsible from "react-collapsible";
import NormalQuest from "@widgets/quest/NormalQuest";
import type { MainQuest } from "@backend/types";
import { listSubQuestsFor } from "@backend/data";
import "@css/widgets/quest/PrimaryQuest.scss";
interface IProps {
quest: MainQuest;
}
function Trigger(props: IProps): React.ReactElement {
return (
<div className={"Trigger"}>
<GiSupersonicArrow className={"Trigger_Icon"} />
<div className={"Trigger_Info"}>
<p className={"font-bold"}>{props.quest.title}</p>
<p>ID: {props.quest.id}</p>
</div>
</div>
);
}
class PrimaryQuest extends React.PureComponent<IProps> {
constructor(props: IProps) {
super(props);
}
render() {
return (
<Collapsible
className={"PrimaryQuest"}
openedClassName={"PrimaryQuest"}
trigger={<Trigger quest={this.props.quest} />}
transitionTime={50}
>
<div className={"PrimaryQuest_List"}>
{
listSubQuestsFor(this.props.quest)
.map((quest) => <NormalQuest
key={quest.id} quest={quest} right />)
}
</div>
</Collapsible>
);
}
}
export default PrimaryQuest;