Ready to implement 'concepts'!

This commit is contained in:
BinarySandia04 2024-09-11 20:03:09 +02:00
parent e347409e89
commit 22d093febc
16 changed files with 402 additions and 40 deletions

View File

@ -198,3 +198,9 @@ button:active {
font-weight: normal; font-weight: normal;
font-size: 32px; font-size: 32px;
} }
.text-icon {
height: 18px;
width: 18px;
margin-right: 5px;
}

View File

@ -23,7 +23,7 @@ function AddTooltip(element, val, data = {}){
function UpdateVisibilityThread(){ function UpdateVisibilityThread(){
let tooltip = document.getElementById('mouse-tooltip'); let tooltip = document.getElementById('mouse-tooltip');
let element = document.elementFromPoint(cursorX, cursorY); let element = document.elementFromPoint(cursorX, cursorY);
if(element._dr_tooltip){ if(element) if(element._dr_tooltip){
ShowTooltip(); ShowTooltip();
content.value = element._dr_tooltip.value; content.value = element._dr_tooltip.value;
if(element._dr_tooltip.max_width) tooltip.style.maxWidth = element._dr_tooltip.max_width + "px"; if(element._dr_tooltip.max_width) tooltip.style.maxWidth = element._dr_tooltip.max_width + "px";

View File

@ -22,7 +22,7 @@ const defValues = {
id: 'main_menu', id: 'main_menu',
title: "DragonRoll", title: "DragonRoll",
create: () => { create: () => {
CreateChildWindow('main_menu', 'welcome'); // CreateChildWindow('main_menu', 'welcome');
} }
}, },
'welcome': { 'welcome': {
@ -123,7 +123,15 @@ const defValues = {
id: 'character_sheet', id: 'character_sheet',
title: 'Character Sheet', title: 'Character Sheet',
close: "true" close: "true"
},
'book_anvil_window': {
id: 'book_anvil_window',
title: "Book Anvil",
back: () => {
ClearWindow('book_anvil_window');
CreateWindow('main_menu');
} }
},
} }
const reload = ref(0); const reload = ref(0);

View File

@ -25,9 +25,10 @@ import MapWindow from '../windows/dm/MapWindow.vue'
import CombatWindow from '../windows/game/CombatWindow.vue' import CombatWindow from '../windows/game/CombatWindow.vue'
import EntityWindow from '../windows/dm/EntityWindow.vue' import EntityWindow from '../windows/dm/EntityWindow.vue'
import CharactersWindow from '../windows/game/CharactersWindow.vue' import CharactersWindow from '../windows/game/CharactersWindow.vue'
import CompendiumWindow from '../windows/game/CompendiumWindow.vue'
import CharacterSheet from '../windows/game/dnd-5e/CharacterSheet.vue' import CharacterSheet from '../windows/game/dnd-5e/CharacterSheet.vue'
import WelcomeWindow from '../windows/WelcomeWindow.vue' import WelcomeWindow from '../windows/WelcomeWindow.vue'
import CompendiumWindow from '../windows/CompendiumWindow.vue'
import BookAnvilWindow from '../windows/BookAnvilWindow.vue'
// Gestionem ventanas // Gestionem ventanas
@ -56,12 +57,14 @@ let WindowMap = {
entity_window: EntityWindow, entity_window: EntityWindow,
characters_window: CharactersWindow, characters_window: CharactersWindow,
compendium_window: CompendiumWindow, compendium_window: CompendiumWindow,
book_anvil_window: BookAnvilWindow,
}; };
async function InjectSystemWindows(system){ async function InjectSystemWindows(system){
// Hack // Hack
let systemWidows = { let systemWidows = {
character_sheet: (await import(`../windows/game/${system}/CharacterSheet.vue`)).default character_sheet: (await import(`../windows/game/${system}/CharacterSheet.vue`)).default,
concept_sheet: (await import(`../windows/game/${system}/ConceptSheet.vue`)).default
}; };
WindowMap = {...WindowMap, ...systemWidows}; WindowMap = {...WindowMap, ...systemWidows};

View File

@ -44,7 +44,7 @@ function ViewCampaign(){
</div> </div>
</template> </template>
<style scoped> <style lang="scss" scoped>
.button-small { .button-small {
height: 32px; height: 32px;
padding: 10px; padding: 10px;
@ -54,6 +54,11 @@ function ViewCampaign(){
background-color: var(--color-background-softer); background-color: var(--color-background-softer);
width: 100%; width: 100%;
user-select: none; user-select: none;
border-bottom: 1px solid var(--color-border);
&:first-child {
border-top: 1px solid var(--color-border);
}
} }
.main-campaign-entry-container-inner { .main-campaign-entry-container-inner {

View File

@ -116,6 +116,7 @@ watch(chat, () => {
height: 41px; height: 41px;
max-height: 100px; max-height: 100px;
resize: none; resize: none;
border: 1px solid var(--color-border);
&:focus { &:focus {
outline: none; outline: none;

View File

@ -23,39 +23,54 @@ onMounted(() => {
<span v-if="data.type == 'text'">{{ text }}</span> <span v-if="data.type == 'text'">{{ text }}</span>
<div v-if="data.type == 'dice-roll'" class="dice-roll-container"> <div v-if="data.type == 'dice-roll'" class="dice-roll-container">
<span class="roll-title">Rolled {{ text }}</span> <span class="roll-title">Rolled {{ text }}</span>
<span class="roll-result">{{ roll }}</span> <div class="roll-result">
<span>{{ roll }}</span>
<img class="roll-bg" src="/img/d20.png"> <img class="roll-bg" src="/img/d20.png">
</div> </div>
</div>
</div> </div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.dice-roll-container { .dice-roll-container {
display: flex; display: flex;
flex-direction: column; flex-direction: row;
width: 300px; width: 300px;
padding-bottom: 10px; height: 50px;
align-items: center;
.roll-result {
margin-left: auto;
height: 100%;
position: relative;
span {
top: 5px;
left: -41px;
position: absolute;
font-size: 40px;
height: 40px;
line-height: 40px;
font-weight: bold;
font-family: MrEavesRemake;
text-align: center;
width: 60px;
}
img {
top: 5px;
left: -31px;
position: absolute;
filter: invert(0.9);
opacity: 0.1;
width: 40px;
}
}
} }
.roll-title { .roll-title {
font-weight: bold; font-weight: bold;
} }
.roll-result {
font-size: 48px;
font-weight: bold;
font-family: MrEavesRemake;
text-align: center;
margin-bottom: -75px;
}
.roll-bg {
filter: invert(0.9);
opacity: 0.1;
width: 75px;
position: relative;
left: 112px;
top: 0px;
}
</style> </style>

View File

@ -36,6 +36,11 @@ onMounted(() => {
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.msg-chunk {
border-bottom: 1px solid #ffffff08;
margin: 2px 0px 2px 0px;
}
.msg-title { .msg-title {
font-weight: bold; font-weight: bold;
} }
@ -44,13 +49,12 @@ onMounted(() => {
width: 100%; width: 100%;
background-color: var(--color-chat-other); background-color: var(--color-chat-other);
display: flex; display: flex;
margin-top: 2px;
padding-left: 10px; padding-left: 10px;
font-size: 0.9rem; font-size: 0.9rem;
} }
.content-container { .content-container {
max-width: 75%; width: 100%;
padding: 1px 15px; padding: 1px 15px;
margin-bottom: 7px; margin-bottom: 7px;

View File

@ -0,0 +1,73 @@
<script setup>
import WindowHandle from '@/views/partials/WindowHandle.vue';
import { onMounted, ref } from 'vue';
import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows';
import { SetMinSize, SetMaxSize, SetResizable } from '../../services/Windows';
const props = defineProps(['data']);
const data = props.data;
const handle = ref(null);
let id = data.id;
onMounted(() => {
SetupHandle(id, handle);
SetSize(id, {width: 700, height: 850});
SetResizable(id, true);
SetMinSize(id, {width: 700, height: 200});
SetMaxSize(id, {width: 700});
ResetPosition(id, "center");
});
</script>
<template>
<div class="window-wrapper" :id="'window-wrapper-' + id">
<WindowHandle :window="id" ref="handle"></WindowHandle>
<div class="book-anvil-container">
<div class="book-anvil-header">
<img class="img-selector"> <!-- TODO: Canviar això per un component ben fet -->
<div class="book-info">
<h1>New book</h1>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.img-selector {
width: 72px;
height: 72px;
}
.book-anvil-header {
display: flex;
width: 100%;
padding: 10px;
background-color: #27303b;
.book-info {
margin-left: 20px;
}
}
.book-anvil-container {
width: 100%;
height: 100%;
h1 {
font-family: NodestoCapsCondensed;
}
}
.window-wrapper {
display: flex;
align-items: center;
user-select: none;
}
</style>

View File

@ -3,6 +3,7 @@ import WindowHandle from '@/views/partials/WindowHandle.vue';
import { onMounted, ref } from 'vue'; import { onMounted, ref } from 'vue';
import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows'; import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows';
import { SetMinSize, SetMaxSize, SetResizable } from '../../services/Windows';
const props = defineProps(['data']); const props = defineProps(['data']);
const data = props.data; const data = props.data;
@ -12,8 +13,11 @@ let id = data.id;
onMounted(() => { onMounted(() => {
SetupHandle(id, handle); SetupHandle(id, handle);
SetSize(id, {width: 600, height: 850}); SetSize(id, {width: 700, height: 850});
ResetPosition(id, {x: window.innerWidth - 620, y: 60}); SetResizable(id, true);
SetMinSize(id, {width: 700, height: 200});
SetMaxSize(id, {width: 700});
ResetPosition(id, "center");
}); });
</script> </script>
@ -22,12 +26,19 @@ onMounted(() => {
<div class="window-wrapper" :id="'window-wrapper-' + id"> <div class="window-wrapper" :id="'window-wrapper-' + id">
<WindowHandle :window="id" ref="handle"></WindowHandle> <WindowHandle :window="id" ref="handle"></WindowHandle>
<div class="compendium-container">
</div> </div>
</div>
</template> </template>
<style scoped> <style scoped>
.compendium-container {
display: flex;
width: 100%;
height: 100%;
}
.window-wrapper { .window-wrapper {
display: flex; display: flex;

View File

@ -28,7 +28,7 @@ let title = data.title;
onMounted(() => { onMounted(() => {
SetupHandle(id, handle); SetupHandle(id, handle);
SetSize(id, {width: 500, height: 540}); SetSize(id, {width: 500, height: 460});
ResetPosition(id, "center", emitter); ResetPosition(id, "center", emitter);
/* /*
@ -55,6 +55,22 @@ function OpenCampaigns(){
CreateWindow('campaign_list'); CreateWindow('campaign_list');
} }
function OpenCompendium(){
ClearWindow(id);
CreateWindow('compendium_window', {
back: () => {
CreateWindow('main_menu');
ClearWindow('compendium_window');
},
close: false
});
}
function OpenBookAnvil(){
ClearWindow(id);
CreateWindow('book_anvil_window');
}
</script> </script>
@ -69,9 +85,8 @@ function OpenCampaigns(){
<div class="button-container"> <div class="button-container">
<button class="btn-primary button-expand sound-click" v-on:click="OpenCampaigns" ref="campaignButton">Campaigns</button> <button class="btn-primary button-expand sound-click" v-on:click="OpenCampaigns" ref="campaignButton">Campaigns</button>
<hr> <hr>
<button class="btn-primary button-expand sound-click" v-on:click="OpenCollection">Your Collection</button> <button class="btn-primary button-expand sound-click" v-on:click="OpenCompendium">The Cosmic Compendium</button>
<button class="btn-primary button-expand sound-click" v-on:click="OpenLibrary">The Cosmic Library</button> <button class="btn-primary button-expand sound-click" v-on:click="OpenBookAnvil">Book Anvil</button>
<button class="btn-primary button-expand sound-click" v-on:click="OpenLibrary">Book Anvil</button>
</div> </div>
<VersionRender></VersionRender> <VersionRender></VersionRender>
</div> </div>

View File

@ -390,8 +390,41 @@ function ConfigureBookmarks(){
<div class="sheet-content" v-show="selectedBookmark == 1"> <div class="sheet-content" v-show="selectedBookmark == 1">
<!-- Inventory --> <!-- Inventory -->
<div class="fixed-container"> <div class="fixed-container">
<div class="weight-container"></div> <div class="weight-info-container">
<div class="money-container"></div> <div class="weight-container">
<div class="weight-bar">
<div class="weight-bar-value-content" style="width: 130px;"></div>
<div class="weight-bar-content"><img class="text-icon" src="icons/game-icons/ffffff/delapouite/weight.svg"> 30 / 150</div>
</div>
<div class="three-columns">
<div class="grid-element-col">
<div class="big-number-container">
<span class="small">Strength</span>
<span class="big">10</span>
</div>
</div>
<div class="grid-element-col">
<div class="big-number-container">
<span class="small">Size</span>
<span class="big">Md</span>
</div>
</div>
<div class="grid-element-col">
<div class="big-number-container">
<span class="small">Multiplier</span>
<span class="big">x1</span>
</div>
</div>
</div>
</div>
<div class="money-container">
<div class="money-entry grid-element"><span>100</span></div>
<div class="money-entry grid-element"><span>100</span></div>
<div class="money-entry grid-element"><span>100</span></div>
<div class="money-entry grid-element"><span>100</span></div>
<div class="money-entry grid-element"><span>100</span></div>
</div>
</div>
<div class="filter-container"></div> <div class="filter-container"></div>
<div class="inventory-container"></div> <div class="inventory-container"></div>
</div> </div>
@ -419,6 +452,108 @@ function ConfigureBookmarks(){
<style scoped lang="scss"> <style scoped lang="scss">
@mixin shadow {
-moz-box-shadow: 0px 0px 10px -1px rgba(0,0,0,0.25);
box-shadow: 0px 0px 10px -1px rgba(0,0,0,0.25);
}
@mixin panel {
@include shadow();
background-color: #1B1B1B;
border: 1px solid var(--color-border);
}
.money-entry {
display: flex;
align-items: center;
justify-content: center;
@include panel();
}
.money-container {
height: 95px;
width: 200px;
margin-left: 20px;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(3, 1fr);
}
.weight-info-container {
display: flex;
}
.weight-container {
@include panel();
width: 300px;
height: 95px;
display: flex;
flex-direction: column;
}
.big-number-container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
.small {
margin-top: 5px;
flex-grow: 1;
}
.big {
font-size: 24px;
font-weight: bold;
flex-grow: 1;
}
}
.three-columns {
display: grid;
flex-grow: 1;
grid-template-columns: 1fr 1fr 1fr;
width: 100%;
position: relative;
overflow: hidden;
}
.grid-element-col, .grid-element {
position: relative;
&::before, &::after {
content: '';
position: absolute;
background-color: #333;
z-index: 1;
}
&::before {
width: 1px;
height: 100%;
left: -1px;
top: 0;
}
}
.grid-element {
&::after {
width: 100%;
height: 1px;
left: 0;
top: -1px;
}
}
.fixed-container {
width: 100%;
height: 100%;
overflow-y: auto;
display: flex;
align-items: center;
flex-direction: column;
padding: 20px;
}
.skill-throws-container { .skill-throws-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -448,6 +583,7 @@ function ConfigureBookmarks(){
} }
.saving-throws, .skill-throws { .saving-throws, .skill-throws {
@include shadow();
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background-color: #1B1B1B; background-color: #1B1B1B;
@ -568,6 +704,39 @@ span.player-info-div {
} }
} }
.weight-bar {
background-size: 99.5px 100px;
background-image:
linear-gradient(to right, grey 1px, transparent 1px),
linear-gradient(to bottom, grey 1px, transparent 1px);
height: 24px;
border-bottom: 1px solid var(--color-golden-border);
border-right: 1px solid var(--color-golden-border);
position: relative;
margin-top: 0px;
.weight-bar-value-content {
position: absolute;
height: 24px;
border: 1px solid var(--color-border);
width: 100%;
background-color: rgb(71, 134, 206);
}
.weight-bar-content {
position: absolute;
display: flex;
align-items: center;
height: 22px;
line-height: 22px;
font-size: 16px;
margin-left: 12px;
font-weight: bold;
}
}
.health-bar { .health-bar {
background-color: #181818; background-color: #181818;
height: 40px; height: 40px;
@ -689,6 +858,7 @@ div.player-info-div {
.flex-container { .flex-container {
&.border { &.border {
@include shadow();
border: 1px solid var(--color-border); border: 1px solid var(--color-border);
background-color: #1b1b1b; background-color: #1b1b1b;
/* Change */ /* Change */

View File

@ -0,0 +1,48 @@
<script setup>
import WindowHandle from '@/views/partials/WindowHandle.vue';
import { onMounted, ref } from 'vue';
import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows';
const props = defineProps(['data']);
const data = props.data;
const handle = ref(null);
let id = data.id;
onMounted(() => {
SetupHandle(id, handle);
SetSize(id, {width: 700, height: 850});
ResetPosition(id, "center");
});
</script>
<template>
<div class="window-wrapper" :id="'window-wrapper-' + id">
<WindowHandle :window="id" ref="handle" handleHeight="105px" custom="true" class="character-sheet-handle"></WindowHandle>
</div>
</template>
<style scoped lang="scss">
@mixin shadow {
-moz-box-shadow: 0px 0px 10px -1px rgba(0,0,0,0.25);
box-shadow: 0px 0px 10px -1px rgba(0,0,0,0.25);
}
@mixin panel {
@include shadow();
background-color: #1B1B1B;
border: 1px solid var(--color-border);
}
.window-wrapper {
display: flex;
align-items: center;
border: solid 1px var(--color-golden-border);
user-select: none;
}
</style>

View File

@ -4,9 +4,10 @@ const Schema = mongoose.Schema;
const BookSchema = new Schema({ const BookSchema = new Schema({
title: {type: String, required: true}, title: {type: String, required: true},
authors: { type: [String] }, authors: { type: [String] },
description: { type: String },
system: {type: String, required: true}, system: {type: String, required: true},
image: { type: String }, image: { type: String },
data: { type: Object }, contents: [ {type: mongoose.Types.ObjectId, ref: "Concept"} ],
}); });
module.exports = mongoose.model('Book', BookSchema); module.exports = mongoose.model('Book', BookSchema);

View File

@ -4,7 +4,7 @@ const Schema = mongoose.Schema;
const CharacterSchema = new Schema({ const CharacterSchema = new Schema({
name: {type: String, required: true}, name: {type: String, required: true},
data: { type: Object }, data: { type: Object },
campaign_user: {type: mongoose.Types.ObjectId, ref: "CampaignUser"}, owner: {type: mongoose.Types.ObjectId, ref: "CampaignUser"},
splash_image: { type: String }, splash_image: { type: String },
}); });

View File

@ -6,6 +6,8 @@ const ConceptSchema = new Schema({
system: {type: String, required: true}, system: {type: String, required: true},
type: { type: String }, type: { type: String },
data: { type: Object }, data: { type: Object },
book: {type: mongoose.Types.ObjectId, ref: "Book"},
campaign: {type: mongoose.Types.ObjectId, ref: "Campaign"},
}); });
module.exports = mongoose.model('Concept', ConceptSchema); module.exports = mongoose.model('Concept', ConceptSchema);