add reroll and remove option to all rollers

This commit is contained in:
RussellChamp committed 2021-08-23 14:26:25 -04:00
1 parent 9e8a22cd62
commit 5a3bdb423d
19 files changed
+528 -130

No files matched your search

+2 -4
View File
@@ -1,6 +1,4 @@
Add Steadings tables
Change steadings and mounts to not show English names by default Change steadings and mounts to not show English names by default
Make everything look nicer Make everything look more nicer
Maybe put roller button in a left nav bar and the results in the middle? get the roll sound working on all reroll events
Add a copy-to-clipboard option
Add a 3d dice rolling visualizer Add a 3d dice rolling visualizer
+7 -1
View File
@@ -17,6 +17,7 @@
import Footer from "./components/Footer.svelte"; import Footer from "./components/Footer.svelte";
import MultiCard from "./components/MultiCard.svelte"; import MultiCard from "./components/MultiCard.svelte";
import { RollCard } from "./types/RollCard"; import { RollCard } from "./types/RollCard";
import type { RerolledEvent } from "./types/RerolledEvent";
let rollThemBones = new Audio("https://soundbible.com/mp3/Shake And Roll Dice-SoundBible.com-591494296.mp3"); let rollThemBones = new Audio("https://soundbible.com/mp3/Shake And Roll Dice-SoundBible.com-591494296.mp3");
let playSounds = localStorage?.getItem("playSounds") != "false"; let playSounds = localStorage?.getItem("playSounds") != "false";
@@ -52,6 +53,11 @@
} }
} }
function rerolled(event: CustomEvent<RerolledEvent>) {
// console.log("rerolled card value", event.detail);
playAudio();
}
function remove(event: CustomEvent<RollCard>) { function remove(event: CustomEvent<RollCard>) {
cards = cards.filter((c) => c.timestamp != event.detail.timestamp); cards = cards.filter((c) => c.timestamp != event.detail.timestamp);
} }
@@ -94,7 +100,7 @@
<Col sm="9"> <Col sm="9">
<h3>Results:</h3> <h3>Results:</h3>
{#each cards as card} {#each cards as card}
<MultiCard {card} on:remove={remove} /> <MultiCard {card} on:rerolled={rerolled} on:remove={remove} />
{/each} {/each}
</Col> </Col>
</Row> </Row>
+67
View File
@@ -0,0 +1,67 @@
<script lang="ts">
import { createEventDispatcher } from "svelte";
import { Button, Icon, Tooltip } from "sveltestrap";
import { sample } from "lodash";
import ClipboardHelper from "./ClipboardHelper.svelte";
const dispatch = createEventDispatcher();
export let showCopy: boolean = true;
export let showReroll: boolean = true;
export let showRemove: boolean = true;
export let data: any;
export let dataType: string;
let rerollIcon = getIcon();
function getIcon() {
return "dice-" + sample([1, 2, 3, 4, 5, 6]);
}
function reroll() {
rerollIcon = getIcon();
dispatch("reroll");
}
function remove() {
dispatch("remove");
}
</script>
<main>
<div class="buttons">
{#if showCopy}
<div class="clipboard">
<ClipboardHelper {data} {dataType} />
</div>
{/if}
{#if showReroll}
<div class="reroll">
<Button id="reroll" outline color="dark" on:click={reroll}>
<Icon name={rerollIcon} />
</Button>
<Tooltip target="reroll" placement="top">Reroll Item</Tooltip>
</div>
{/if}
{#if showRemove}
<Button id="remove" outline color="danger" on:click={remove}>
<Icon name="x" />
</Button>
<Tooltip target="remove" placement="top">Remove Item</Tooltip>
{/if}
</div>
</main>
<style>
.buttons {
display: flex;
}
.clipboard {
padding-right: 5px;
}
.reroll {
padding-right: 5px;
}
</style>
+24 -32
View File
@@ -1,30 +1,24 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
import { capitalize } from "lodash"; import { capitalize } from "lodash";
import { import { Card, CardHeader, CardTitle, CardBody, CardText, CardFooter, Container, Row } from "sveltestrap";
Card,
CardHeader,
CardTitle,
CardBody,
CardSubtitle,
CardText,
CardFooter,
Container,
Row,
Button,
Icon,
Tooltip,
} from "sveltestrap";
import ClipboardHelper from "./ClipboardHelper.svelte";
import NpcCard from "./NpcCard.svelte"; import NpcCard from "./NpcCard.svelte";
import DieIcon from "./DieIcon.svelte"; import DieIcon from "./DieIcon.svelte";
import type { Creature } from "../rollers/creatures"; import CardButtons from "./CardTitleButtons.svelte";
import { Creature, rollCreature } from "../rollers/creatures";
import { RerolledEvent } from "../types/RerolledEvent";
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
export let creature: Creature; export let creature: Creature;
export let timestamp: string; export let timestamp: string = "";
export let showRemove: boolean = true;
function reroll() {
creature = rollCreature();
dispatch("rerolled", new RerolledEvent("creature", creature));
}
function remove() { function remove() {
dispatch("remove"); dispatch("remove");
@@ -36,25 +30,24 @@
<CardHeader> <CardHeader>
<CardTitle> <CardTitle>
<div class="title"> <div class="title">
<div class="description"> <div class="type">
Creature:
{capitalize(creature.type)}<DieIcon value={creature.roll} /> {capitalize(creature.type)}<DieIcon value={creature.roll} />
{#if creature.subtype !== ""}({creature.subtype})<DieIcon value={creature.subroll} />{/if}: {capitalize(
creature.description
)}<DieIcon value={creature.specificroll} />
</div>
<div class="buttons">
<ClipboardHelper data={creature} dataType="creature" />
<Button id="remove" outline color="danger" on:click={remove}>
<Icon name="x" />
</Button>
<Tooltip target="remove" placement="top">Remove Item</Tooltip>
</div> </div>
<CardButtons data={creature} dataType="creature" showReroll={true} on:reroll={reroll} {showRemove} on:remove={remove} />
</div> </div>
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
<CardBody> <CardBody>
<CardText> <CardText>
<Container> <Container>
<Row>
<strong>Description:</strong>
<ul>
{#if creature.subtype !== ""}<li>{capitalize(creature.subtype)}<DieIcon value={creature.subroll} /></li>{/if}
<li>{capitalize(creature.description)}<DieIcon value={creature.specificroll} /></li>
</ul>
</Row>
<Row> <Row>
<strong>Details:</strong> <strong>Details:</strong>
<ul> <ul>
@@ -81,7 +74,7 @@
{#if creature.feature}<li>Feature: {creature.feature.description}<DieIcon value={creature.feature.roll} /></li>{/if} {#if creature.feature}<li>Feature: {creature.feature.description}<DieIcon value={creature.feature.roll} /></li>{/if}
{#if creature.npc}<li> {#if creature.npc}<li>
NPC Stats: NPC Stats:
<NpcCard npc={creature.npc} {timestamp} /> <NpcCard npc={creature.npc} showRemove={false} />
</li>{/if} </li>{/if}
{#if creature.numAppearing}<li> {#if creature.numAppearing}<li>
Number Appearing: {creature.numAppearing.description} Number Appearing: {creature.numAppearing.description}
@@ -96,7 +89,9 @@
</Container> </Container>
</CardText> </CardText>
</CardBody> </CardBody>
{#if timestamp}
<CardFooter>{timestamp}</CardFooter> <CardFooter>{timestamp}</CardFooter>
{/if}
</Card> </Card>
</main> </main>
@@ -108,9 +103,6 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
} }
.title .buttons {
display: flex;
}
ul { ul {
margin-left: 2em; margin-left: 2em;
} }
+39 -2
View File
@@ -1,12 +1,32 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from "svelte";
import { capitalize } from "lodash"; import { capitalize } from "lodash";
import { Card, CardHeader, CardTitle, CardBody, CardText, CardFooter, Icon } from "sveltestrap"; import { Card, CardHeader, CardTitle, CardBody, CardText, CardFooter, Icon } from "sveltestrap";
import type { Danger } from "../rollers/dangers";
import DieIcon from "./DieIcon.svelte";
import { Danger, rollDanger } from "../rollers/dangers";
import CreatureCard from "./CreatureCard.svelte";
import DieIcon from "./DieIcon.svelte";
import CardButtons from "./CardTitleButtons.svelte";
import { RerolledEvent } from "../types/RerolledEvent";
const dispatch = createEventDispatcher();
export let danger: Danger; export let danger: Danger;
export let timestamp: string; export let timestamp: string;
function reroll() {
danger = rollDanger();
dispatch("rerolled", new RerolledEvent("danger", danger));
}
function remove() {
dispatch("remove");
}
function rerolledCreature(event: CustomEvent<RerolledEvent>) {
danger.creature = event.detail.value;
dispatch("rerolled", new RerolledEvent("danger", danger));
}
let icon = ""; let icon = "";
$: icon = $: icon =
danger.category == "unnatural entity" danger.category == "unnatural entity"
@@ -22,20 +42,37 @@
<Card class="mb-3"> <Card class="mb-3">
<CardHeader> <CardHeader>
<CardTitle> <CardTitle>
<div class="title">
<div class="description">
{capitalize(danger.category)}<DieIcon value={danger.roll} /> {capitalize(danger.category)}<DieIcon value={danger.roll} />
{#if danger.subcategory !== ""}({danger.subcategory})<DieIcon value={danger.subroll} />{/if}: {capitalize( {#if danger.subcategory !== ""}({danger.subcategory})<DieIcon value={danger.subroll} />{/if}: {capitalize(
danger.description danger.description
)}<DieIcon value={danger.specificroll} /> )}<DieIcon value={danger.specificroll} />
</div>
<CardButtons data={danger} dataType="danger" on:reroll={reroll} on:remove={remove} />
</div>
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
<CardBody> <CardBody>
<CardText> <CardText>
<Icon name={icon} />: {danger.description} <Icon name={icon} />: {danger.description}
{#if danger.creature}
<CreatureCard creature={danger.creature} on:rerolled={rerolledCreature} showRemove={false} />
{/if}
</CardText> </CardText>
</CardBody> </CardBody>
{#if timestamp}
<CardFooter>{timestamp}</CardFooter> <CardFooter>{timestamp}</CardFooter>
{/if}
</Card> </Card>
</main> </main>
<style> <style>
main {
text-align: left;
}
.title {
display: flex;
justify-content: space-between;
}
</style> </style>
+30 -3
View File
@@ -1,28 +1,55 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from "svelte";
import { capitalize } from "lodash"; import { capitalize } from "lodash";
import { Card, CardHeader, CardTitle, CardBody, CardText, CardFooter } from "sveltestrap"; import { Card, CardHeader, CardTitle, CardBody, CardText, CardFooter } from "sveltestrap";
import type { Detail } from "../rollers/details"; import { Detail, rollDetail } from "../rollers/details";
import DieIcon from "./DieIcon.svelte"; import DieIcon from "./DieIcon.svelte";
import CardButtons from "./CardTitleButtons.svelte";
import { RerolledEvent } from "../types/RerolledEvent";
const dispatch = createEventDispatcher();
export let detail: Detail; export let detail: Detail;
export let timestamp: string; export let timestamp: string;
function reroll() {
detail = rollDetail(detail.type);
dispatch("rerolled", new RerolledEvent("detail-" + detail.type, detail));
}
function remove() {
dispatch("remove");
}
</script> </script>
<main> <main>
<Card class="mb-3"> <Card class="mb-3">
<CardHeader> <CardHeader>
<CardTitle> <CardTitle>
{capitalize(detail.type)} <div class="title">
</CardTitle> <div class="description">
Detail: {capitalize(detail.type)}
</div>
<CardButtons data={detail} dataType={"detail-" + detail.type} on:reroll={reroll} on:remove={remove} />
</div></CardTitle
>
</CardHeader> </CardHeader>
<CardBody> <CardBody>
<CardText> <CardText>
{detail.description}<DieIcon value={detail.roll} /> {detail.description}<DieIcon value={detail.roll} />
</CardText> </CardText>
</CardBody> </CardBody>
{#if timestamp}
<CardFooter>{timestamp}</CardFooter> <CardFooter>{timestamp}</CardFooter>
{/if}
</Card> </Card>
</main> </main>
<style> <style>
main {
text-align: left;
}
.title {
display: flex;
justify-content: space-between;
}
</style> </style>
+53 -10
View File
@@ -1,39 +1,76 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from "svelte";
import { Button, Card, CardHeader, CardTitle, CardBody, CardSubtitle, CardText, CardFooter, Container, Row, Icon } from "sveltestrap"; import { Button, Card, CardHeader, CardTitle, CardBody, CardSubtitle, CardText, CardFooter, Container, Row, Icon } from "sveltestrap";
import { capitalize } from "lodash"; import { capitalize } from "lodash";
import DieIcon from "./DieIcon.svelte"; import DieIcon from "./DieIcon.svelte";
import CreatureCard from "./CreatureCard.svelte"; import CreatureCard from "./CreatureCard.svelte";
import SteadingCard from "./SteadingCard.svelte"; import SteadingCard from "./SteadingCard.svelte";
import type { Discovery } from "../rollers/discoveries"; import CardButtons from "./CardTitleButtons.svelte";
import { Discovery, rollDiscovery } from "../rollers/discoveries";
import { RerolledEvent } from "../types/RerolledEvent";
const dispatch = createEventDispatcher();
export let discovery: Discovery; export let discovery: Discovery;
export let timestamp: string; export let timestamp: string;
let hasDetails = false;
$: hasDetails = !!(
discovery.age ||
discovery.alignment ||
discovery.aspect ||
discovery.creature ||
discovery.element ||
discovery.magicType ||
discovery.ruination ||
discovery.size ||
discovery.steading ||
discovery.visibility
);
function reroll() {
discovery = rollDiscovery();
dispatch("rerolled", new RerolledEvent("discovery", discovery));
}
function remove() {
dispatch("remove");
}
</script> </script>
<main> <main>
<Card class="mb-3"> <Card class="mb-3">
<CardHeader> <CardHeader>
<CardTitle> <CardTitle>
<div class="title">
<div class="description">
Discovery:
{capitalize(discovery.category)} {capitalize(discovery.category)}
<DieIcon value={discovery.roll} /> <DieIcon value={discovery.roll} />
{#if discovery.subcategory !== ""} </div>
({discovery.subcategory}<DieIcon value={discovery.subroll} />){/if}: {capitalize(discovery.description)} <CardButtons data={discovery} dataType="discovery" on:reroll={reroll} on:remove={remove} />
<DieIcon value={discovery.specificroll} /> </div></CardTitle
</CardTitle> >
</CardHeader> </CardHeader>
<CardBody> <CardBody>
<CardText> <CardText>
<Container> <Container>
<h4>
Type{#if discovery.subcategory !== ""}&nbsp;{capitalize(discovery.subcategory)}<DieIcon value={discovery.subroll} />{/if}: {capitalize(
discovery.description
)}
<DieIcon value={discovery.specificroll} />
</h4>
{#if discovery.category == "creature"} {#if discovery.category == "creature"}
<Row> <Row>
<CreatureCard creature={discovery.creature} {timestamp} /> <CreatureCard creature={discovery.creature} showRemove={false} />
</Row> </Row>
{:else if discovery.category == "steading"} {:else if discovery.category == "structure" && discovery.steading}
<Row> <Row>
<SteadingCard steading={discovery.steading} {timestamp} /> <SteadingCard steading={discovery.steading} showRemove={false} />
</Row> </Row>
{:else} {:else if hasDetails}
<Row> <Row>
<strong>Details:</strong> <strong>Details:</strong>
<ul> <ul>
@@ -44,7 +81,7 @@
{#if discovery.aspect}<li>Aspect: {discovery.aspect.description}<DieIcon value={discovery.aspect.roll} /></li>{/if} {#if discovery.aspect}<li>Aspect: {discovery.aspect.description}<DieIcon value={discovery.aspect.roll} /></li>{/if}
{#if discovery.creature}<li> {#if discovery.creature}<li>
Produced/Inhabited By: {discovery.creature.description}<DieIcon value={discovery.creature.roll} /> Produced/Inhabited By: {discovery.creature.description}<DieIcon value={discovery.creature.roll} />
<CreatureCard creature={discovery.creature} {timestamp} /> <CreatureCard creature={discovery.creature} {timestamp} showRemove={false} />
</li>{/if} </li>{/if}
{#if discovery.element}<li>Element: {discovery.element.description}<DieIcon value={discovery.element.roll} /></li>{/if} {#if discovery.element}<li>Element: {discovery.element.description}<DieIcon value={discovery.element.roll} /></li>{/if}
{#if discovery.magicType}<li> {#if discovery.magicType}<li>
@@ -64,7 +101,9 @@
</Container> </Container>
</CardText> </CardText>
</CardBody> </CardBody>
{#if timestamp}
<CardFooter>{timestamp}</CardFooter> <CardFooter>{timestamp}</CardFooter>
{/if}
</Card> </Card>
</main> </main>
@@ -72,6 +111,10 @@
main { main {
text-align: left; text-align: left;
} }
.title {
display: flex;
justify-content: space-between;
}
ul { ul {
margin-left: 2em; margin-left: 2em;
} }
+30 -2
View File
@@ -1,12 +1,25 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from "svelte";
import { Card, CardHeader, CardTitle, CardBody, CardSubtitle, CardText, CardFooter, Container, Row, Icon } from "sveltestrap"; import { Card, CardHeader, CardTitle, CardBody, CardSubtitle, CardText, CardFooter, Container, Row, Icon } from "sveltestrap";
import { capitalize } from "lodash"; import { capitalize } from "lodash";
import type { Dungeon } from "../rollers/dungeons"; import { Dungeon, rollDungeon } from "../rollers/dungeons";
import CardButtons from "./CardTitleButtons.svelte";
import { RerolledEvent } from "../types/RerolledEvent";
const dispatch = createEventDispatcher();
export let dungeon: Dungeon; export let dungeon: Dungeon;
export let timestamp; export let timestamp;
function reroll() {
dungeon = rollDungeon();
dispatch("rerolled", new RerolledEvent("dungeon", dungeon));
}
function remove() {
dispatch("remove");
}
function getIcon(t: string, c: string): string { function getIcon(t: string, c: string): string {
return t == "discovery" return t == "discovery"
? "eye-fill" ? "eye-fill"
@@ -25,7 +38,16 @@
<main> <main>
<Card class="mb-3"> <Card class="mb-3">
<CardHeader> <CardHeader>
<CardTitle>{capitalize(dungeon.size.description)} {dungeon.function.description} built by {dungeon.builder.description}</CardTitle> <CardTitle>
<div class="title">
<div class="description">
Dungeon:
{capitalize(dungeon.size.description)}
{dungeon.function.description} built by {dungeon.builder.description}
</div>
<CardButtons data={dungeon} dataType="dungeon" on:reroll={reroll} on:remove={remove} />
</div>
</CardTitle>
</CardHeader> </CardHeader>
<CardBody> <CardBody>
<CardSubtitle> <CardSubtitle>
@@ -68,7 +90,9 @@
</Container> </Container>
</CardText> </CardText>
</CardBody> </CardBody>
{#if timestamp}
<CardFooter>{timestamp}</CardFooter> <CardFooter>{timestamp}</CardFooter>
{/if}
</Card> </Card>
</main> </main>
@@ -76,6 +100,10 @@
main { main {
text-align: left; text-align: left;
} }
.title {
display: flex;
justify-content: space-between;
}
ul { ul {
margin-left: 2em; margin-left: 2em;
} }
+30 -3
View File
@@ -1,15 +1,36 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from "svelte";
import { Card, CardHeader, CardTitle, CardBody, CardSubtitle, CardText, CardFooter, Container, Col, Row } from "sveltestrap"; import { Card, CardHeader, CardTitle, CardBody, CardSubtitle, CardText, CardFooter, Container, Col, Row } from "sveltestrap";
import type { Follower } from "../rollers/followers"; import { Follower, rollFollower } from "../rollers/followers";
import { RerolledEvent } from "../types/RerolledEvent";
import CardButtons from "./CardTitleButtons.svelte";
const dispatch = createEventDispatcher();
export let follower: Follower; export let follower: Follower;
export let timestamp: string; export let timestamp: string = "";
export let showRemove: boolean = true;
function reroll() {
follower = rollFollower();
dispatch("rerolled", new RerolledEvent("follower", follower));
}
function remove() {
dispatch("remove");
}
</script> </script>
<main> <main>
<Card class="mb-3"> <Card class="mb-3">
<CardHeader> <CardHeader>
<CardTitle>{follower.name} ({follower.gender})</CardTitle> <CardTitle>
<div class="title">
<div class="description">
Follower: {follower.name} ({follower.gender})
</div>
<CardButtons data={follower} dataType="follower" on:reroll={reroll} {showRemove} on:remove={remove} />
</div>
</CardTitle>
</CardHeader> </CardHeader>
<CardBody> <CardBody>
<CardSubtitle> <CardSubtitle>
@@ -88,7 +109,9 @@
</Container> </Container>
</CardText> </CardText>
</CardBody> </CardBody>
{#if timestamp}
<CardFooter>{timestamp}</CardFooter> <CardFooter>{timestamp}</CardFooter>
{/if}
</Card> </Card>
</main> </main>
@@ -96,6 +119,10 @@
main { main {
text-align: left; text-align: left;
} }
.title {
display: flex;
justify-content: space-between;
}
p { p {
margin-left: 1em; margin-left: 1em;
} }
+30 -3
View File
@@ -1,12 +1,25 @@
<script lang="ts"> <script lang="ts">
import { capitalize } from "lodash"; import { createEventDispatcher } from "svelte";
import { capitalize, sample } from "lodash";
import { Card, CardHeader, CardTitle, CardBody, CardText, CardFooter, Icon } from "sveltestrap"; import { Card, CardHeader, CardTitle, CardBody, CardText, CardFooter, Icon } from "sveltestrap";
import type { Kingdom, KingdomItem } from "../rollers/kingdoms"; import type { KingdomItem } from "../rollers/kingdoms";
import CardButtons from "./CardTitleButtons.svelte";
import { RerolledEvent } from "../types/RerolledEvent";
const dispatch = createEventDispatcher();
export let item: KingdomItem; export let item: KingdomItem;
export let timestamp: string; export let timestamp: string;
let icon = ""; let icon = "";
function reroll() {
item.description = sample(item.kingdom[item.category]);
dispatch("rerolled", new RerolledEvent("kingdomItem-" + item.category, item.description));
}
function remove() {
dispatch("remove");
}
$: icon = String({ male: "person-fill", female: "person", steading: "house-door-fill", mount: "bicycle" }[item?.category] || ""); $: icon = String({ male: "person-fill", female: "person", steading: "house-door-fill", mount: "bicycle" }[item?.category] || "");
</script> </script>
@@ -14,18 +27,32 @@
<Card class="mb-3"> <Card class="mb-3">
<CardHeader> <CardHeader>
<CardTitle> <CardTitle>
<div class="title">
<div class="description">
{capitalize(item.category)} from {item.kingdom.description} {capitalize(item.category)} from {item.kingdom.description}
</div>
<CardButtons data={item.description} dataType={"kingdomItem." + item?.category} on:reroll={reroll} on:remove={remove} />
</div>
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
<CardBody> <CardBody>
<CardText> <CardText>
<Icon name={icon} /> Name: <Icon name={icon} />
{item.description} {item.description}
</CardText> </CardText>
</CardBody> </CardBody>
{#if timestamp}
<CardFooter>{timestamp}</CardFooter> <CardFooter>{timestamp}</CardFooter>
{/if}
</Card> </Card>
</main> </main>
<style> <style>
main {
text-align: left;
}
.title {
display: flex;
justify-content: space-between;
}
</style> </style>
+16 -11
View File
@@ -14,10 +14,15 @@
import SteadingCard from "./SteadingCard.svelte"; import SteadingCard from "./SteadingCard.svelte";
import type { RollCard } from "../types/RollCard"; import type { RollCard } from "../types/RollCard";
import type { RerolledEvent } from "../types/RerolledEvent";
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
export let card: RollCard; export let card: RollCard;
function rerolled(event: CustomEvent<RerolledEvent>) {
// pass along the event
dispatch("rerolled", event.detail);
}
function remove() { function remove() {
dispatch("remove", card); dispatch("remove", card);
} }
@@ -25,27 +30,27 @@
<main> <main>
{#if card.type == "creature"} {#if card.type == "creature"}
<CreatureCard creature={card.value} timestamp={card.timestamp} on:remove={remove} /> <CreatureCard creature={card.value} timestamp={card.timestamp} on:rerolled={rerolled} on:remove={remove} />
{:else if card.type == "danger"} {:else if card.type == "danger"}
<DangerCard danger={card.value} timestamp={card.timestamp} /> <DangerCard danger={card.value} timestamp={card.timestamp} on:rerolled={rerolled} on:remove={remove} />
{:else if card.type == "detail"} {:else if card.type == "detail"}
<DetailsCard detail={card.value} timestamp={card.timestamp} /> <DetailsCard detail={card.value} timestamp={card.timestamp} on:rerolled={rerolled} on:remove={remove} />
{:else if card.type == "discovery"} {:else if card.type == "discovery"}
<DiscoveryCard discovery={card.value} timestamp={card.timestamp} /> <DiscoveryCard discovery={card.value} timestamp={card.timestamp} on:rerolled={rerolled} on:remove={remove} />
{:else if card.type == "dungeon"} {:else if card.type == "dungeon"}
<DungeonCard dungeon={card.value} timestamp={card.timestamp} /> <DungeonCard dungeon={card.value} timestamp={card.timestamp} on:rerolled={rerolled} on:remove={remove} />
{:else if card.type == "follower"} {:else if card.type == "follower"}
<FollowerCard follower={card.value} timestamp={card.timestamp} /> <FollowerCard follower={card.value} timestamp={card.timestamp} on:rerolled={rerolled} on:remove={remove} />
{:else if card.type == "kingdom"} {:else if card.type == "kingdom"}
<KingdomCard item={card.value} timestamp={card.timestamp} /> <KingdomCard item={card.value} timestamp={card.timestamp} on:rerolled={rerolled} on:remove={remove} />
{:else if card.type == "npc"} {:else if card.type == "npc"}
<NpcCard npc={card.value} timestamp={card.timestamp} /> <NpcCard npc={card.value} timestamp={card.timestamp} on:rerolled={rerolled} on:remove={remove} />
{:else if card.type == "place"} {:else if card.type == "place"}
<PlaceCard place={card.value} timestamp={card.timestamp} /> <PlaceCard place={card.value} timestamp={card.timestamp} on:rerolled={rerolled} on:remove={remove} />
{:else if card.type == "region"} {:else if card.type == "region"}
<RegionCard region={card.value} timestamp={card.timestamp} /> <RegionCard region={card.value} timestamp={card.timestamp} on:rerolled={rerolled} on:remove={remove} />
{:else if card.type == "steading"} {:else if card.type == "steading"}
<SteadingCard steading={card.value} timestamp={card.timestamp} /> <SteadingCard steading={card.value} timestamp={card.timestamp} on:rerolled={rerolled} on:remove={remove} />
{:else} {:else}
<h3>Card type not supported: {card.type}</h3> <h3>Card type not supported: {card.type}</h3>
{/if} {/if}
+54 -11
View File
@@ -1,15 +1,51 @@
<script lang="ts"> <script lang="ts">
import { Card, CardHeader, CardTitle, CardBody, CardSubtitle, CardText, CardFooter, Container, Col, Row, Icon } from "sveltestrap"; import { createEventDispatcher } from "svelte";
import type { Npc } from "../rollers/npcs"; import {
Accordion,
AccordionItem,
Card,
CardHeader,
CardTitle,
CardBody,
CardSubtitle,
CardText,
CardFooter,
Container,
Col,
Row,
Icon,
} from "sveltestrap";
import { Npc, rollNpc } from "../rollers/npcs";
import FollowerCard from "./FollowerCard.svelte";
import CardButtons from "./CardTitleButtons.svelte";
import { RerolledEvent } from "../types/RerolledEvent";
const dispatch = createEventDispatcher();
export let npc: Npc; export let npc: Npc;
export let timestamp: string; export let timestamp: string = "";
export let showRemove: boolean = true;
function reroll() {
npc = rollNpc();
dispatch("rerolled", new RerolledEvent("npc", npc));
}
function remove() {
dispatch("remove");
}
</script> </script>
<main> <main>
<Card class="mb-3"> <Card class="mb-3">
<CardHeader> <CardHeader>
<CardTitle>{npc.getDescription()}</CardTitle> <CardTitle>
<div class="title">
<div class="description">
NPC: {npc.getDescription()}
</div>
<CardButtons data={npc} dataType="npc" on:reroll={reroll} {showRemove} on:remove={remove} />
</div></CardTitle
>
</CardHeader> </CardHeader>
<CardBody> <CardBody>
<CardSubtitle> <CardSubtitle>
@@ -22,21 +58,24 @@
<ul> <ul>
<li> <li>
They are a(n) <em>{npc.context.alignment.description}</em> <em>{npc.context.description}</em> with They are a(n) <em>{npc.context.alignment.description}</em> <em>{npc.context.description}</em> with
<em>{npc.trait.category} ({npc.context.trait.description})</em> <em>{npc.traits[0]?.category} ({npc.context.trait.description})</em>
encountered in a(n) <em>{npc.context.category}</em> setting while they are <em>{npc.context.activity.description}</em> encountered in a(n) <em>{npc.context.category}</em> setting while they are <em>{npc.context.activity.description}</em>
</li> </li>
</ul> </ul>
</Row> </Row>
<Row> <!-- <Row>
<strong>Follower Stats:</strong> <Accordion>
<ul> <AccordionItem header="Follower Stats">
<li>{npc.follower.name}</li> <FollowerCard follower={npc.follower} showRemove={false} />
</ul> </AccordionItem>
</Row> </Accordion>
</Row> -->
</Container> </Container>
</CardText> </CardText>
</CardBody> </CardBody>
{#if timestamp}
<CardFooter>{timestamp}</CardFooter> <CardFooter>{timestamp}</CardFooter>
{/if}
</Card> </Card>
</main> </main>
@@ -44,6 +83,10 @@
main { main {
text-align: left; text-align: left;
} }
.title {
display: flex;
justify-content: space-between;
}
ul { ul {
margin-left: 2em; margin-left: 2em;
} }
+30 -2
View File
@@ -1,24 +1,52 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from "svelte";
import { Card, CardHeader, CardTitle, CardBody, CardText, CardFooter } from "sveltestrap"; import { Card, CardHeader, CardTitle, CardBody, CardText, CardFooter } from "sveltestrap";
import type { Place } from "../rollers/places"; import type { Place } from "../rollers/places";
import { rollPlace } from "../rollers/places";
import { RerolledEvent } from "../types/RerolledEvent";
import CardButtons from "./CardTitleButtons.svelte";
const dispatch = createEventDispatcher();
export let place: Place; export let place: Place;
export let timestamp: string; export let timestamp: string;
function reroll() {
place = rollPlace();
dispatch("rerolled", new RerolledEvent("place", place));
}
function remove() {
dispatch("remove");
}
</script> </script>
<main> <main>
<Card class="mb-3"> <Card class="mb-3">
<CardHeader> <CardHeader>
<CardTitle>Place</CardTitle> <CardTitle>
<div class="title">
<div class="description">Place</div>
<CardButtons data={place} dataType="place" on:reroll={reroll} on:remove={remove} />
</div>
</CardTitle>
</CardHeader> </CardHeader>
<CardBody> <CardBody>
<CardText> <CardText>
{place} Name: {place}
</CardText> </CardText>
</CardBody> </CardBody>
{#if timestamp}
<CardFooter>{timestamp}</CardFooter> <CardFooter>{timestamp}</CardFooter>
{/if}
</Card> </Card>
</main> </main>
<style> <style>
main {
text-align: left;
}
.title {
display: flex;
justify-content: space-between;
}
</style> </style>
+30 -2
View File
@@ -1,24 +1,52 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from "svelte";
import { Card, CardHeader, CardTitle, CardBody, CardText, CardFooter } from "sveltestrap"; import { Card, CardHeader, CardTitle, CardBody, CardText, CardFooter } from "sveltestrap";
import type { Region } from "../rollers/regions"; import type { Region } from "../rollers/regions";
import { rollRegion } from "../rollers/regions";
import { RerolledEvent } from "../types/RerolledEvent";
import CardButtons from "./CardTitleButtons.svelte";
const dispatch = createEventDispatcher();
export let region: Region; export let region: Region;
export let timestamp: string; export let timestamp: string;
function reroll() {
region = rollRegion();
dispatch("rerolled", new RerolledEvent("region", region));
}
function remove() {
dispatch("remove");
}
</script> </script>
<main> <main>
<Card class="mb-3"> <Card class="mb-3">
<CardHeader> <CardHeader>
<CardTitle>Region</CardTitle> <CardTitle>
<div class="title">
<div class="description">Region</div>
<CardButtons data={region} dataType="region" on:reroll={reroll} on:remove={remove} />
</div>
</CardTitle>
</CardHeader> </CardHeader>
<CardBody> <CardBody>
<CardText> <CardText>
{region} Name: {region}
</CardText> </CardText>
</CardBody> </CardBody>
{#if timestamp}
<CardFooter>{timestamp}</CardFooter> <CardFooter>{timestamp}</CardFooter>
{/if}
</Card> </Card>
</main> </main>
<style> <style>
main {
text-align: left;
}
.title {
display: flex;
justify-content: space-between;
}
</style> </style>
+31 -9
View File
@@ -1,32 +1,48 @@
<script lang="ts"> <script lang="ts">
import { Button, Card, CardHeader, CardTitle, CardBody, CardSubtitle, CardText, CardFooter, Container, Row, Icon } from "sveltestrap"; import { createEventDispatcher } from "svelte";
import { Card, CardHeader, CardTitle, CardBody, CardSubtitle, CardText, CardFooter, Container, Row } from "sveltestrap";
import { capitalize } from "lodash"; import { capitalize } from "lodash";
import DieIcon from "./DieIcon.svelte"; import DieIcon from "./DieIcon.svelte";
import CreatureCard from "./CreatureCard.svelte"; import CreatureCard from "./CreatureCard.svelte";
import type { Steading } from "../rollers/steadings"; import { rollSteading, Steading } from "../rollers/steadings";
import CardButtons from "./CardTitleButtons.svelte";
import { RerolledEvent } from "../types/RerolledEvent";
const dispatch = createEventDispatcher();
export let steading: Steading; export let steading: Steading;
export let timestamp: string; export let timestamp: string = "";
export let showRemove: boolean = true;
function reroll() {
steading = rollSteading();
dispatch("rerolled", new RerolledEvent("steading", steading));
}
function remove() {
dispatch("remove");
}
</script> </script>
<main> <main>
<Card class="mb-3"> <Card class="mb-3">
<CardHeader> <CardHeader>
<CardTitle> <CardTitle>
{capitalize(steading.category)} <div class="title">
<DieIcon value={steading.roll} /> <div class="description">Steading: {capitalize(steading.category)}<DieIcon value={steading.roll} /></div>
<CardButtons data={steading} dataType="steading" on:reroll={reroll} {showRemove} on:remove={remove} />
</div>
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
<CardBody> <CardBody>
<CardText> <CardText>
<Container> <Container>
<Row> <Row>
<h3>Built by:</h3> <h4>Built by:</h4>
<CreatureCard creature={steading.builtBy} {timestamp} /> <CreatureCard creature={steading.builtBy} showRemove={false} />
</Row> </Row>
<Row> <Row>
<h3>Tags</h3> <h4>Tags</h4>
<ul> <ul>
{#each steading.tags as tag} {#each steading.tags as tag}
<li>{tag}</li> <li>{tag}</li>
@@ -34,7 +50,7 @@
</ul> </ul>
</Row> </Row>
<Row> <Row>
<h3>{capitalize(steading.condition)}:</h3> <h4>{capitalize(steading.condition)}:</h4>
</Row> </Row>
<Row> <Row>
<h4>{capitalize(steading.benefit.description)} <DieIcon value={steading.benefitRoll} />:</h4> <h4>{capitalize(steading.benefit.description)} <DieIcon value={steading.benefitRoll} />:</h4>
@@ -55,7 +71,9 @@
</Container> </Container>
</CardText> </CardText>
</CardBody> </CardBody>
{#if timestamp}
<CardFooter>{timestamp}</CardFooter> <CardFooter>{timestamp}</CardFooter>
{/if}
</Card> </Card>
</main> </main>
@@ -63,6 +81,10 @@
main { main {
text-align: left; text-align: left;
} }
.title {
display: flex;
justify-content: space-between;
}
ul { ul {
margin-left: 2em; margin-left: 2em;
} }
+2 -13
View File
@@ -1,29 +1,18 @@
<script lang="ts"> <script lang="ts">
import { format as formatDate } from "date-fns";
import { createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
import { Button } from "sveltestrap"; import { Button } from "sveltestrap";
import SteadingCard from "./SteadingCard.svelte"; import { rollSteading } from "../rollers/steadings";
import { rollSteading, Steading } from "../rollers/steadings";
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
export let rollResults: { steading: Steading; timestamp: string }[] = [];
function roll(event: Event) { function roll(event: Event) {
let steading = rollSteading(); let steading = rollSteading();
rollResults = [{ steading, timestamp: formatDate(new Date(), "P kk:mm:ss") }, ...rollResults]; dispatch("roll", { type: "steading", value: steading });
dispatch("roll");
} }
</script> </script>
<main> <main>
<span class="btn">
<Button color="primary" on:click={roll}>Roll Steading</Button> <Button color="primary" on:click={roll}>Roll Steading</Button>
</span>
{#each rollResults as { steading, timestamp }}
<SteadingCard {steading} {timestamp} />
{/each}
</main> </main>
<style> <style>
+48 -20
View File
@@ -1,13 +1,41 @@
import { random, replace, sample, sampleSize } from "lodash"; import { random, replace, sample, sampleSize } from "lodash";
export type DetailType = "ability" | "activity" | "adjective" | "age" | "alignment" | "aspect" | "condition" | "disposition" | "element" |
"feature" | "magic type" | "num appearing" | "oddity" | "orientation" | "ruination" | "size" | "tag" | "terrain" | "visibility";
// This is the general implemenetation of details. // This is the general implemenetation of details.
// We are not doing strict class inheritance because that way leads to pain // We are not doing strict class inheritance because that way leads to pain
export class Detail { export class Detail {
constructor(public type: string, public roll: number, public description: string) { } constructor(public type: DetailType, public roll: number, public description: string) { }
}
export function rollDetail(type: DetailType): { type: DetailType, roll: number, description: string } {
switch (type) {
case "ability": return rollAbility();
case "activity": return rollActivity();
case "adjective": return rollAdjective();
case "age": return rollAge();
case "alignment": return rollAlignment();
case "aspect": return rollAspect();
case "condition": return rollCondition();
case "disposition": return rollDisposition();
case "element": return rollElement();
case "feature": return rollFeature();
case "magic type": return rollMagicType();
case "num appearing": return rollNumAppearing();
case "oddity": return rollOddity();
case "orientation": return rollOrientation();
case "ruination": return rollRuination();
case "size": return rollSize();
case "tag": return rollTag();
case "terrain": return rollTerrain();
case "visibility": return rollVisibility();
default: return { type: type, roll: 0, description: "invalid type" };
}
} }
export class Ability { export class Ability {
type: string = "ability"; type: DetailType = "ability";
constructor(public roll: number = 0, public description = "") { }; constructor(public roll: number = 0, public description = "") { };
} }
@@ -33,7 +61,7 @@ export function rollAbility(roll: number = random(1, 12)): Ability {
} }
export class Activity { export class Activity {
type: string = "activity"; type: DetailType = "activity";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -58,7 +86,7 @@ export function rollActivity(roll: number = random(1, 12)): Activity {
} }
export class Adjective { export class Adjective {
type: string = "adjective"; type: DetailType = "adjective";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -83,7 +111,7 @@ export function rollAdjective(roll: number = random(1, 12)): Adjective {
} }
export class Age { export class Age {
type: string = "age"; type: DetailType = "age";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -108,7 +136,7 @@ export function rollAge(roll: number = random(1, 12)): Age {
} }
export class Alignment { export class Alignment {
type: string = "alignment"; type: DetailType = "alignment";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -131,7 +159,7 @@ export function rollAlignment(roll: number = random(1, 12)): Alignment {
} }
export class Aspect { export class Aspect {
type: string = "aspect"; type: DetailType = "aspect";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -157,7 +185,7 @@ export function rollAspect(roll: number = random(1, 12)): Aspect {
} }
export class Condition { export class Condition {
type: string = "condition"; type: DetailType = "condition";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -184,7 +212,7 @@ export function rollCondition(roll: number = random(1, 12)): Condition {
} }
export class Disposition { export class Disposition {
type: string = "disposition"; type: DetailType = "disposition";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -211,7 +239,7 @@ export function rollDisposition(roll: number = random(1, 12)): Disposition {
} }
export class Element { export class Element {
type: string = "element"; type: DetailType = "element";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -236,7 +264,7 @@ export function rollElement(roll: number = random(1, 12)): Element {
} }
export class Feature { export class Feature {
type: string = "feature"; type: DetailType = "feature";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -271,7 +299,7 @@ export function rollFeature(roll: number = random(1, 12)): Feature {
} }
export class MagicType { export class MagicType {
type: string = "magic type"; type: DetailType = "magic type";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -295,7 +323,7 @@ export function rollMagicType(roll: number = random(1, 12)): MagicType {
} }
export class NumAppearing { export class NumAppearing {
type: string = "num appearing"; type: DetailType = "num appearing";
constructor(public roll: number = 0, public description: string = "", public count: string = "") { }; constructor(public roll: number = 0, public description: string = "", public count: string = "") { };
} }
@@ -316,7 +344,7 @@ export function rollNumAppearing(roll: number = random(1, 12)): NumAppearing {
} }
export class Oddity { export class Oddity {
type: string = "oddity"; type: DetailType = "oddity";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -342,7 +370,7 @@ export function rollOddity(roll: number = random(1, 12)): Oddity {
} }
export class Orientation { export class Orientation {
type: string = "orientation"; type: DetailType = "orientation";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -375,7 +403,7 @@ export function rollOrientation(roll: number = random(1, 12)): Orientation {
} }
export class Ruination { export class Ruination {
type: string = "ruination"; type: DetailType = "ruination";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -404,7 +432,7 @@ export function rollRuination(roll: number = random(1, 12)): Ruination {
} }
export class Size { export class Size {
type: string = "size"; type: DetailType = "size";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -427,7 +455,7 @@ export function rollSize(roll: number = random(1, 12)): Size {
} }
export class Tag { export class Tag {
type: string = "tag"; type: DetailType = "tag";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -461,7 +489,7 @@ export function rollTag(roll: number = random(1, 12)) {
} }
export class Terrain { export class Terrain {
type: string = "terrain"; type: DetailType = "terrain";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
@@ -488,7 +516,7 @@ export function rollTerrain(roll: number = random(1, 12)): Terrain {
} }
export class Visibility { export class Visibility {
type: string = "visibility"; type: DetailType = "visibility";
constructor(public roll: number = 0, public description: string = "") { }; constructor(public roll: number = 0, public description: string = "") { };
} }
+2 -2
View File
@@ -10,7 +10,7 @@ export class Npc {
hometown: string; hometown: string;
context: Context; context: Context;
occupation: Occupation occupation: Occupation
trait: Trait; traits: Trait[];
follower: Follower; follower: Follower;
getDescription(fullDesc: boolean = false) { getDescription(fullDesc: boolean = false) {
@@ -32,7 +32,7 @@ export function rollNpc(): Npc {
npc.context = rollContext(); npc.context = rollContext();
npc.occupation = rollOccupation(); npc.occupation = rollOccupation();
npc.trait = rollTrait(); npc.traits.push(rollTrait());
npc.follower = rollFollower(); npc.follower = rollFollower();
return npc; return npc;
+3
View File
@@ -0,0 +1,3 @@
export class RerolledEvent {
constructor(public type: string, public value: any) { };
}