Skip to content

Commit

Permalink
feat(settings): new settings and custom settings feature
Browse files Browse the repository at this point in the history
  • Loading branch information
liana-p committed Jun 17, 2023
1 parent f30bd06 commit 8864665
Show file tree
Hide file tree
Showing 21 changed files with 428 additions and 19 deletions.
7 changes: 7 additions & 0 deletions packages/narrat/examples/games/default/data/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ dialogPanel:
bottomOffset: 50
width: 475
height: 680
settings:
customSettings:
playerName:
name: Player Name
type: string
defaultValue: Someone
description: The name of the player.
layout:
backgrounds:
# Default was 880 x 720
Expand Down
3 changes: 3 additions & 0 deletions packages/narrat/src/components/MainMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@
Main Menu
</button>
<button class="button title quit-button" @click="quit">Exit</button>
<SettingsMenu />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import VolumeControls from './volume-controls.vue';
import SettingsMenu from './settings/settings-menu.vue';
import { getPlayTime, toHHMMSS } from '@/utils/time-helpers';
import { useMain } from '@/stores/main-store';
export default defineComponent({
components: {
VolumeControls,
SettingsMenu,
},
data() {
return {};
Expand Down
6 changes: 0 additions & 6 deletions packages/narrat/src/components/game-dialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,6 @@ watch(dialog.value, (newValue) => {
display: none; /* webkit */
}
.dialog-box {
/* background-color: rgba(0, 0, 0, 0.8); */
/* border-top: 1px dashed rgba(255, 255, 255, 0.2);
border-bottom: 1px dashed rgba(255, 255, 255, 0.2); */
}
.dialog * {
overflow-anchor: none;
}
Expand Down
5 changes: 2 additions & 3 deletions packages/narrat/src/components/inventory/item-details.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@
</div>
</template>
<script lang="ts" setup>
import { getAssetUrl, getConfig, getItemConfig } from '@/config';
import { useDialogStore } from '@/stores/dialog-store';
import { getAssetUrl, getItemConfig } from '@/config';
import { ItemState, useInventory } from '@/stores/inventory-store';
import { computed } from 'vue';
const props = defineProps<{
item: ItemState;
}>();
const emit = defineEmits(['close', 'use']);
defineEmits(['close', 'use']);
const itemData = computed(() => {
return getItemConfig(props.item.id);
Expand Down
1 change: 0 additions & 1 deletion packages/narrat/src/components/menu-buttons.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
</template>
<script setup lang="ts">
import { useMain } from '../stores/main-store';
import { computed, onMounted, onUnmounted, ref } from 'vue';
import { vm } from '../vm/vm';
import { useMenu } from '@/stores/menu-store';
Expand Down
116 changes: 116 additions & 0 deletions packages/narrat/src/components/settings/setting-widget.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<template>
<div class="settings-widget-container">
<label
:for="settingId"
class="setting-label"
:id="`setting-label-${settingId}`"
>
{{ schema.name }}
</label>
<input
v-if="isSettingNumber(schema) || isSettingInteger(schema)"
ref="slider"
class="number-slider setting-slider"
type="range"
:id="`setting-slider-${settingId}`"
:name="settingId"
:min="schema.minValue"
:max="schema.maxValue"
:step="schema.step"
v-model="settingValue"
/>
<input
v-else-if="isSettingBoolean(schema)"
type="checkbox"
class="setting-checkbox"
:id="`setting-checkbox-${settingId}`"
:name="settingId"
v-model="settingValue"
/>
<input
v-else-if="isSettingString(schema)"
type="text"
class="setting-text"
:id="`setting-text-${settingId}`"
:name="settingId"
v-model="settingValue"
/>
<span class="mx-8">{{ settingValue }}</span>
</div>
<p class="text-left setting-description">{{ schema.description }}</p>
<hr
class="h-px my-8 bg-gray-200 border-0 dark:bg-gray-700 setting-separator"
/>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { useSettings } from '../../stores/settings-store';
import {
isSettingNumber,
isSettingBoolean,
isSettingInteger,
isSettingString,
} from '../../config/settings-config';
export interface SettingWidgetProps {
settingId: string;
}
const props = defineProps<SettingWidgetProps>();
const settings = useSettings();
const startValue = computed(() => {
return settings.getSetting(props.settingId);
});
const settingValue = ref(startValue.value);
const schema = computed(() => {
return settings.getSettingSchema(props.settingId)!;
});
function valueChanged(newValue: number) {
let value = newValue;
if (isSettingInteger(schema.value)) {
value = Math.round(value);
}
settings.setSetting(props.settingId, value);
}
watch(settingValue, (newValue: any) => {
valueChanged(newValue);
});
</script>
<style>
.setting-label {
/* margin: 5px 20px; */
margin-right: 10px;
font-size: 1.25rem;
font-weight: 700;
/* width: 180px; */
text-align: left;
margin-right: 20px;
}
.setting-slider {
flex-grow: 2;
background-color: blue;
}
.settings-widget-container {
width: 100%;
font-size: 1.5rem;
display: flex;
align-items: center;
justify-content: flex-start;
}
.setting-description {
margin-left: 2rem;
}
.setting-separator {
background-color: var(--separator-bg-color);
width: var(--separator-width);
height: var(--separator-height);
margin-top: 0.5rem;
margin-bottom: 0.5rem;
text-align: center;
margin-left: auto;
margin-right: auto;
}
</style>
41 changes: 41 additions & 0 deletions packages/narrat/src/components/settings/settings-menu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<template>
<div class="container mx-auto settings-menu-container">
<h2 class="settings-menu-title subtitle text-center">Settings</h2>
<SettingWidget
v-for="(schema, id) in schemas"
:settingId="(id as string)"
:key="id"
/>
</div>
</template>

<script setup lang="ts">
import { computed } from 'vue';
import { useSettings } from '../../stores/settings-store';
import SettingWidget from './setting-widget.vue';
const settings = useSettings();
const schemas = computed(() => {
return settings.getAllSettingSchemas();
});
</script>

<style>
.settings-menu-title {
margin-top: 1rem;
margin-bottom: 1rem;
}
.settings-menu-container {
position: relative;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
background: var(--light-background);
border: 1px dashed white;
padding: 20px;
margin: 20px 0;
}
</style>
1 change: 1 addition & 0 deletions packages/narrat/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ const baseConfigKeys = [
'saveFileName',
'images',
'layout',
'settings',
'gameFlow',
'dialogPanel',
'splashScreens',
Expand Down
2 changes: 2 additions & 0 deletions packages/narrat/src/config/config-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { ScreensInputConfigSchema } from './screens-config';
import { SkillsInputConfigSchema } from './skills-config';
import { SkillChecksInputConfigSchema } from './skillchecks-config';
import { TooltipsConfigSchema } from './tooltips-config';
import { SettingsConfigSchema } from './settings-config';

export const ConfigInputSchema = Type.Object({
baseAssetsPath: Type.Optional(Type.String()),
Expand All @@ -29,6 +30,7 @@ export const ConfigInputSchema = Type.Object({
saveFileName: Type.String(),
images: Type.Optional(Type.Record(Type.String(), Type.String())),
layout: LayoutConfigSchema,
settings: Type.Optional(SettingsConfigSchema),
gameFlow: Type.Optional(
Type.Object({
labelToJumpOnScriptEnd: Type.Optional(Type.String()),
Expand Down
3 changes: 3 additions & 0 deletions packages/narrat/src/config/config-output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
SkillChecksConfig,
defaultSkillChecksConfig,
} from './skillchecks-config';
import { SettingsConfig } from './settings-config';

export interface Config {
baseAssetsPath: string;
Expand All @@ -40,6 +41,7 @@ export interface Config {
[key: string]: string;
};
layout: LayoutConfig;
settings: SettingsConfig;
gameFlow: {
labelToJumpOnScriptEnd?: string;
};
Expand Down Expand Up @@ -72,6 +74,7 @@ export const defaultConfig = {
saveFileName: 'narrat save',
images: {},
layout: defaultLayoutConfig,
settings: {},
gameFlow: {},
dialogPanel: {
overlayMode: true,
Expand Down
2 changes: 2 additions & 0 deletions packages/narrat/src/config/layout-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const LayoutConfigSchema = Type.Object({
dialogBottomPadding: Type.Union([Type.Number(), Type.String()]),
minTextWidth: Type.Optional(Type.Number()),
verticalLayoutThreshold: Type.Number(),
defaultFontSize: Type.Optional(Type.Number()),
portraits: Type.Object({
width: Type.Number(),
height: Type.Number(),
Expand Down Expand Up @@ -38,6 +39,7 @@ export const defaultLayoutConfig: LayoutConfig = {
},
dialogBottomPadding: 70,
verticalLayoutThreshold: 600,
defaultFontSize: 16,
portraits: {
width: 100,
height: 100,
Expand Down
82 changes: 82 additions & 0 deletions packages/narrat/src/config/settings-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { Type, Static } from '@sinclair/typebox';

export const CustomSettingGenericSchema = Type.Object({
name: Type.String(),
description: Type.Optional(Type.String()),
});

export const CustomSettingsNumberSchema = Type.Intersect([
CustomSettingGenericSchema,
Type.Object({
type: Type.Literal('number'),
defaultValue: Type.Number(),
step: Type.Number(),
minValue: Type.Number(),
maxValue: Type.Number(),
}),
]);
export type CustomSettingsNumber = Static<typeof CustomSettingsNumberSchema>;

export const CustomSettingsIntegerSchema = Type.Intersect([
CustomSettingGenericSchema,
Type.Object({
type: Type.Literal('integer'),
defaultValue: Type.Number(),
step: Type.Number(),
minValue: Type.Number(),
maxValue: Type.Number(),
}),
]);
export type CustomSettingsInteger = Static<typeof CustomSettingsIntegerSchema>;

export const CustomSettingsBooleanSchema = Type.Intersect([
CustomSettingGenericSchema,
Type.Object({
type: Type.Literal('boolean'),
defaultValue: Type.Boolean(),
}),
]);
export type CustomSettingsBoolean = Static<typeof CustomSettingsBooleanSchema>;

export const CustomSettingsStringSchema = Type.Intersect([
CustomSettingGenericSchema,
Type.Object({
type: Type.Literal('string'),
defaultValue: Type.String(),
}),
]);
export type CustomSettingsString = Static<typeof CustomSettingsStringSchema>;

export const CustomSettingSchema = Type.Union([
CustomSettingsNumberSchema,
CustomSettingsIntegerSchema,
CustomSettingsBooleanSchema,
CustomSettingsStringSchema,
]);
export type CustomSetting = Static<typeof CustomSettingSchema>;
export function isSettingNumber(
setting: CustomSetting,
): setting is CustomSettingsNumber {
return setting.type === 'number';
}
export function isSettingInteger(
setting: CustomSetting,
): setting is CustomSettingsInteger {
return setting.type === 'integer';
}
export function isSettingBoolean(
setting: CustomSetting,
): setting is CustomSettingsBoolean {
return setting.type === 'boolean';
}
export function isSettingString(
setting: CustomSetting,
): setting is CustomSettingsString {
return setting.type === 'string';
}
export const SettingsConfigSchema = Type.Object({
customSettings: Type.Optional(
Type.Record(Type.String(), CustomSettingSchema),
),
});
export type SettingsConfig = Static<typeof SettingsConfigSchema>;
4 changes: 4 additions & 0 deletions packages/narrat/src/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@
--achievement-tile-background: var(--tile-background);
--achievement-tile-border-color: var(--tile-border-color);
--achievement-description-color: rgb(170, 170, 170);

--separator-bg-color: rgba(250, 250, 250, 0.8);
--separator-height: 1px;
--separator-width: 100%;
}
body {
font-family: var(--font-family);
Expand Down
2 changes: 2 additions & 0 deletions packages/narrat/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'es6-promise/auto';
import 'virtual:windi.css';
import 'virtual:windi-devtools';

import './css/main.css';

import { Vue3Mq } from 'vue3-mq';
Expand Down
Loading

0 comments on commit 8864665

Please sign in to comment.