| @@ -1,7 +1,7 @@ | |||||
| <template> | <template> | ||||
| <div id="app"> | <div id="app"> | ||||
| <Header version="pre-alpha" /> | <Header version="pre-alpha" /> | ||||
| <Combat :left="left" :right="right" :combatants="combatants" /> | |||||
| <Combat :combatants="combatants" /> | |||||
| </div> | </div> | ||||
| </template> | </template> | ||||
| @@ -20,8 +20,6 @@ import { ProperNoun, TheyPronouns, FemalePronouns, MalePronouns, ImproperNoun } | |||||
| } | } | ||||
| }) | }) | ||||
| export default class App extends Vue { | export default class App extends Vue { | ||||
| left: Creature | |||||
| right: Creature | |||||
| combatants: Array<Creature> | combatants: Array<Creature> | ||||
| constructor () { | constructor () { | ||||
| super() | super() | ||||
| @@ -71,12 +69,9 @@ export default class App extends Vue { | |||||
| cleric.title = "Lv. 5 Cleric" | cleric.title = "Lv. 5 Cleric" | ||||
| cleric.items.push(Items.Mace) | cleric.items.push(Items.Mace) | ||||
| this.left = fighter | |||||
| this.right = new Creatures.Withers() | |||||
| const withers = new Creatures.Withers() | |||||
| const kenzie = new Creatures.Kenzie() | const kenzie = new Creatures.Kenzie() | ||||
| this.combatants = [this.left, this.right, wizard, rogue, cleric, kenzie] | |||||
| console.log(this.left) | |||||
| console.log(this.right) | |||||
| this.combatants = [fighter, withers, wizard, rogue, cleric, kenzie] | |||||
| } | } | ||||
| } | } | ||||
| </script> | </script> | ||||
| @@ -1,10 +1,10 @@ | |||||
| <template> | <template> | ||||
| <div class="combat-layout"> | <div class="combat-layout"> | ||||
| <div @wheel="horizWheelLeft" class="stat-column" id="left-stats"> | <div @wheel="horizWheelLeft" class="stat-column" id="left-stats"> | ||||
| <Statblock @selectAlly="right = combatant" @select="left = combatant" class="left-stats" :data-active="combatant === left" :data-active-ally="combatant === right" v-for="(combatant, index) in combatants.filter(c => c.side == Side.Heroes && !c.digested).slice().reverse()" v-bind:key="'left-stat-' + index" :subject="combatant" /> | |||||
| <Statblock @selectAlly="right = combatant" @select="left = combatant" class="left-stats" :data-active="combatant === left" :data-active-ally="combatant === right" :data-eaten="combatant.containedIn !== null" :data-dead="combatant.vigors.Health <= 0" v-for="(combatant, index) in combatants.filter(c => c.side == Side.Heroes && !c.digested).slice().reverse()" v-bind:key="'left-stat-' + index" :subject="combatant" /> | |||||
| </div> | </div> | ||||
| <div @wheel="horizWheelRight" class="stat-column" id="right-stats"> | <div @wheel="horizWheelRight" class="stat-column" id="right-stats"> | ||||
| <Statblock @selectAlly="left = combatant" @select="right = combatant" class="right-stats" :data-active="combatant === right" :data-active-ally="combatant === left" v-for="(combatant, index) in combatants.filter(c => c.side == Side.Monsters && !c.digested)" v-bind:key="'right-stat-' + index" :subject="combatant" /> | |||||
| <Statblock @selectAlly="left = combatant" @select="right = combatant" class="right-stats" :data-active="combatant === right" :data-active-ally="combatant === left" :data-eaten="combatant.containedIn !== null" :data-dead="combatant.vigors.Health <= 0" v-for="(combatant, index) in combatants.filter(c => c.side == Side.Monsters && !c.digested)" v-bind:key="'right-stat-' + index" :subject="combatant" /> | |||||
| </div> | </div> | ||||
| <div id="log"> | <div id="log"> | ||||
| </div> | </div> | ||||
| @@ -51,11 +51,16 @@ import { Side } from '@/game/combat' | |||||
| @Component( | @Component( | ||||
| { | { | ||||
| components: { Statblock, ActionButton }, | components: { Statblock, ActionButton }, | ||||
| data () { | |||||
| return { | |||||
| left: null, | |||||
| right: null | |||||
| } | |||||
| }, | |||||
| methods: { | methods: { | ||||
| horizWheelLeft (event: MouseWheelEvent) { | horizWheelLeft (event: MouseWheelEvent) { | ||||
| const target = this.$el.querySelector("#left-stats") | const target = this.$el.querySelector("#left-stats") | ||||
| console.log(target) | |||||
| if (target !== null) { | if (target !== null) { | ||||
| target.scrollBy({ top: 0, left: event.deltaY, behavior: 'smooth' }) | target.scrollBy({ top: 0, left: event.deltaY, behavior: 'smooth' }) | ||||
| } | } | ||||
| @@ -63,7 +68,6 @@ import { Side } from '@/game/combat' | |||||
| horizWheelRight (event: MouseWheelEvent) { | horizWheelRight (event: MouseWheelEvent) { | ||||
| const target = this.$el.querySelector("#right-stats") | const target = this.$el.querySelector("#right-stats") | ||||
| console.log(target) | |||||
| if (target !== null) { | if (target !== null) { | ||||
| target.scrollBy({ top: 0, left: -event.deltaY, behavior: 'smooth' }) | target.scrollBy({ top: 0, left: -event.deltaY, behavior: 'smooth' }) | ||||
| } | } | ||||
| @@ -71,13 +75,8 @@ import { Side } from '@/game/combat' | |||||
| } | } | ||||
| } | } | ||||
| ) | ) | ||||
| export default class Combat extends Vue { | |||||
| @Prop({ type: Creature, required: true }) | |||||
| left!: Creature | |||||
| @Prop({ type: Creature, required: true }) | |||||
| right!: Creature | |||||
| export default class Combat extends Vue { | |||||
| @Prop() | @Prop() | ||||
| combatants!: Array<Creature> | combatants!: Array<Creature> | ||||
| @@ -85,11 +84,16 @@ export default class Combat extends Vue { | |||||
| actionDescription = '' | actionDescription = '' | ||||
| created () { | |||||
| this.$data.left = this.combatants.filter(x => x.side === Side.Heroes)[0] | |||||
| this.$data.right = this.combatants.filter(x => x.side === Side.Monsters)[0] | |||||
| } | |||||
| mounted () { | mounted () { | ||||
| const left = this.$el.querySelector("#left-stats") | |||||
| const leftStats = this.$el.querySelector("#left-stats") | |||||
| if (left !== null) { | |||||
| left.scrollTo(left.getBoundingClientRect().width * 2, 0) | |||||
| if (leftStats !== null) { | |||||
| leftStats.scrollTo(leftStats.getBoundingClientRect().width * 2, 0) | |||||
| } | } | ||||
| } | } | ||||
| @@ -257,15 +261,7 @@ a { | |||||
| overflow-y: auto; | overflow-y: auto; | ||||
| padding: 64px 0 64px; | padding: 64px 0 64px; | ||||
| } | } | ||||
| .statblock:hover { | |||||
| background: #444; | |||||
| } | |||||
| .statblock:hover[data-active] { | |||||
| background: #666; | |||||
| } | |||||
| .statblock:hover[data-active-ally] { | |||||
| background: #966; | |||||
| } | |||||
| .action-label { | .action-label { | ||||
| font-size: 200%; | font-size: 200%; | ||||
| } | } | ||||
| @@ -1,53 +1,59 @@ | |||||
| <template> | <template> | ||||
| <div @click="$emit('select')" class="statblock"> | <div @click="$emit('select')" class="statblock"> | ||||
| <h2 class="name" v-if="subject.perspective === firstperson"> | |||||
| You | |||||
| <div class="tooltip-template"> | |||||
| <div class="tooltip-title">{{ subject.title }}</div> | |||||
| <div class="tooltip-body">{{ subject.desc }}</div> | |||||
| </div> | |||||
| </h2> | |||||
| <h2 class="name" v-if="subject.perspective !== firstperson"> | |||||
| {{subject.name.all.capital}} | |||||
| <div class="tooltip-template"> | |||||
| <div class="tooltip-title">{{ subject.title }}</div> | |||||
| <div class="tooltip-body">{{ subject.desc }}</div> | |||||
| </div> | |||||
| </h2> | |||||
| <div class="stat-entry" v-for="vigor in Object.keys(subject.vigors)" v-bind:key="vigor"> | |||||
| <div class="healthbar" v-bind:style="{'--fullness': (subject.vigors[vigor]/subject.maxVigors[vigor]*100) + '%', '--color': vigorColor(subject.vigors[vigor], subject.maxVigors[vigor]) }"> | |||||
| <i :class="vigorIcons[vigor]" /> | |||||
| <div class="healthbar-value"> {{ subject.vigors[vigor].toFixed(0) + '/' + subject.maxVigors[vigor].toFixed(0) }}</div> | |||||
| </div> | |||||
| <div class="statblock-shader statblock-shader-selected"></div> | |||||
| <div class="statblock-shader statblock-shader-dead"></div> | |||||
| <div class="statblock-shader statblock-shader-eaten"></div> | |||||
| <div class="statblock-shader statblock-shader-hover"></div> | |||||
| <div class="statblock-content"> | |||||
| <h2 class="name" v-if="subject.perspective === firstperson"> | |||||
| You | |||||
| <div class="tooltip-template"> | <div class="tooltip-template"> | ||||
| <div class="tooltip-title">{{ vigor }}</div> | |||||
| <div class="tooltip-body">{{ vigorDescs[vigor] }}</div> | |||||
| <div class="tooltip-title">{{ subject.title }}</div> | |||||
| <div class="tooltip-body">{{ subject.desc }}</div> | |||||
| </div> | </div> | ||||
| </div> | |||||
| <div class="stat-line stats"> | |||||
| <div :class="statClass(subject.stats[stat], subject.baseStats[stat])" v-for="stat in Object.keys(subject.stats)" v-bind:key="stat"> | |||||
| <i :class="statIcons[stat]" /> | |||||
| <div class="stat-value">{{subject.stats[stat].toFixed(0)}}</div> | |||||
| </h2> | |||||
| <h2 class="name" v-if="subject.perspective !== firstperson"> | |||||
| {{subject.name.all.capital}} | |||||
| <div class="tooltip-template"> | <div class="tooltip-template"> | ||||
| <div class="tooltip-title">{{ stat }}</div> | |||||
| <div class="tooltip-body">{{ statDescs[stat] }}</div> | |||||
| <div class="tooltip-title">{{ subject.title }}</div> | |||||
| <div class="tooltip-body">{{ subject.desc }}</div> | |||||
| </div> | |||||
| </h2> | |||||
| <div class="stat-entry" v-for="vigor in Object.keys(subject.vigors)" v-bind:key="vigor"> | |||||
| <div class="healthbar" v-bind:style="{'--fullness': (subject.vigors[vigor]/subject.maxVigors[vigor]*100) + '%', '--color': vigorColor(subject.vigors[vigor], subject.maxVigors[vigor]) }"> | |||||
| <i :class="vigorIcons[vigor]" /> | |||||
| <div class="healthbar-value"> {{ subject.vigors[vigor].toFixed(0) + '/' + subject.maxVigors[vigor].toFixed(0) }}</div> | |||||
| </div> | |||||
| <div class="tooltip-template"> | |||||
| <div class="tooltip-title">{{ vigor }}</div> | |||||
| <div class="tooltip-body">{{ vigorDescs[vigor] }}</div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="stat-line stats"> | |||||
| <div :class="statClass(subject.stats[stat], subject.baseStats[stat])" v-for="stat in Object.keys(subject.stats)" v-bind:key="stat"> | |||||
| <i :class="statIcons[stat]" /> | |||||
| <div class="stat-value">{{subject.stats[stat].toFixed(0)}}</div> | |||||
| <div class="tooltip-template"> | |||||
| <div class="tooltip-title">{{ stat }}</div> | |||||
| <div class="tooltip-body">{{ statDescs[stat] }}</div> | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | |||||
| <div class="stat-line vore-stats"> | |||||
| <div class="stat-entry" v-for="stat in Object.keys(subject.voreStats)" v-bind:key="stat"> | |||||
| <i :class="voreStatIcons[stat]" /> | |||||
| <div class="stat-value">{{subject.voreStats[stat].toFixed(0)}}</div> | |||||
| <div class="tooltip-template"> | |||||
| <div class="tooltip-title">{{ stat }}</div> | |||||
| <div class="tooltip-body">{{ voreStatDescs[stat] }}</div> | |||||
| <div class="stat-line vore-stats"> | |||||
| <div class="stat-entry" v-for="stat in Object.keys(subject.voreStats)" v-bind:key="stat"> | |||||
| <i :class="voreStatIcons[stat]" /> | |||||
| <div class="stat-value">{{subject.voreStats[stat].toFixed(0)}}</div> | |||||
| <div class="tooltip-template"> | |||||
| <div class="tooltip-title">{{ stat }}</div> | |||||
| <div class="tooltip-body">{{ voreStatDescs[stat] }}</div> | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div>Status: {{subject.status}}</div> | |||||
| <button v-if="subject.perspective !== firstperson" @click="subject.perspective = firstperson">First-person</button> | |||||
| <button v-if="subject.perspective !== thirdperson" @click="subject.perspective = thirdperson">Third-person</button> | |||||
| <button class="if-not-selected" @click.stop="$emit('selectAlly')">Select ally as target</button> | |||||
| </div> | </div> | ||||
| <div>Status: {{subject.status}}</div> | |||||
| <button v-if="subject.perspective !== firstperson" @click="subject.perspective = firstperson">First-person</button> | |||||
| <button v-if="subject.perspective !== thirdperson" @click="subject.perspective = thirdperson">Third-person</button> | |||||
| <button class="if-not-selected" @click.stop="$emit('selectAlly')">Select ally as target</button> | |||||
| </div> | </div> | ||||
| </template> | </template> | ||||
| @@ -137,6 +143,9 @@ a { | |||||
| flex-basis: 100pt; | flex-basis: 100pt; | ||||
| margin: 0pt 4pt 0pt; | margin: 0pt 4pt 0pt; | ||||
| user-select: none; | user-select: none; | ||||
| position: relative; | |||||
| overflow: hidden; | |||||
| background: none; | |||||
| } | } | ||||
| .stat-line { | .stat-line { | ||||
| @@ -213,19 +222,45 @@ a { | |||||
| color: green; | color: green; | ||||
| } | } | ||||
| .statblock[data-active] { | |||||
| background: #444; | |||||
| border-radius: 4px; | |||||
| .statblock-content { | |||||
| position: relative; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| background: none; | |||||
| } | |||||
| .statblock-shader { | |||||
| position: absolute; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| opacity: 0%; | |||||
| pointer-events: none; | |||||
| z-index: 0; | |||||
| } | } | ||||
| .statblock[data-active-ally] { | |||||
| background: #744; | |||||
| border-radius: 4px; | |||||
| .statblock[data-eaten] .statblock-shader-eaten { | |||||
| background: green; | |||||
| opacity: 35%; | |||||
| } | } | ||||
| .statblock[data-active] .stats, | |||||
| .statblock[data-active] .vore-stats { | |||||
| display: flex; | |||||
| .statblock[data-active] .statblock-shader-selected { | |||||
| background: white; | |||||
| opacity: 15%; | |||||
| } | |||||
| .statblock[data-active-ally] .statblock-shader-selected-ally { | |||||
| background: #f88; | |||||
| opacity: 20%; | |||||
| } | |||||
| .statblock[data-dead] .statblock-shader-dead { | |||||
| background: red; | |||||
| opacity: 50%; | |||||
| } | |||||
| .statblock:hover .statblock-shader-hover { | |||||
| background: white; | |||||
| opacity: 10%; | |||||
| } | } | ||||
| .statblock[data-active] .if-not-selected { | .statblock[data-active] .if-not-selected { | ||||
| @@ -45,7 +45,6 @@ export class StatVigorTest extends RandomTest { | |||||
| userPercent *= 4 | userPercent *= 4 | ||||
| } | } | ||||
| console.log(userPercent, targetPercent, this.f(user.stats[this.stat] * userPercent - target.stats[this.stat] * targetPercent)) | |||||
| return this.f(user.stats[this.stat] * userPercent - target.stats[this.stat] * targetPercent) | return this.f(user.stats[this.stat] * userPercent - target.stats[this.stat] * targetPercent) | ||||
| } | } | ||||
| @@ -79,7 +79,6 @@ export class Creature extends Vore implements Combatant { | |||||
| this.side = Side.Heroes | this.side = Side.Heroes | ||||
| this.voreStats = { | this.voreStats = { | ||||
| get [VoreStat.Bulk] () { | get [VoreStat.Bulk] () { | ||||
| console.log(containers) | |||||
| return containers.reduce( | return containers.reduce( | ||||
| (total: number, container: VoreContainer) => { | (total: number, container: VoreContainer) => { | ||||
| return total + container.contents.reduce( | return total + container.contents.reduce( | ||||
| @@ -130,7 +130,6 @@ export class DynText { | |||||
| } | } | ||||
| toString (): string { | toString (): string { | ||||
| console.log(this.parts) | |||||
| return (this.parts.map(part => part.toString())).join('') | return (this.parts.map(part => part.toString())).join('') | ||||
| } | } | ||||
| } | } | ||||