| @@ -1,12 +1,14 @@ | |||||
| <template> | <template> | ||||
| <div class="combat-layout"> | <div class="combat-layout"> | ||||
| <div>{{ encounter.currentMove.name }}</div> | |||||
| <div @wheel="horizWheelLeft" class="stat-column" id="left-stats"> | <div @wheel="horizWheelLeft" class="stat-column" id="left-stats"> | ||||
| <Statblock @selectPredator="right = combatant.containedIn.owner" @selectAlly="right = combatant" @select="doSelectLeft(combatant)" class="left-stats" :data-destroyed="combatant.destroyed" :data-disabled="encounter.currentMove.side === combatant.side && encounter.currentMove !== combatant" :data-current-turn="encounter.currentMove === combatant" :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).slice().reverse()" v-bind:key="'left-stat-' + index" :subject="combatant" :initiative="encounter.initiatives.get(combatant)" /> | <Statblock @selectPredator="right = combatant.containedIn.owner" @selectAlly="right = combatant" @select="doSelectLeft(combatant)" class="left-stats" :data-destroyed="combatant.destroyed" :data-disabled="encounter.currentMove.side === combatant.side && encounter.currentMove !== combatant" :data-current-turn="encounter.currentMove === combatant" :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).slice().reverse()" v-bind:key="'left-stat-' + index" :subject="combatant" :initiative="encounter.initiatives.get(combatant)" /> | ||||
| </div> | </div> | ||||
| <div @wheel="horizWheelRight" class="stat-column" id="right-stats"> | <div @wheel="horizWheelRight" class="stat-column" id="right-stats"> | ||||
| <Statblock @selectPredator="left = combatant.containedIn.owner" @selectAlly="left = combatant" @select="doSelectRight(combatant)" class="right-stats" :data-destroyed="combatant.destroyed" :data-disabled="encounter.currentMove.side === combatant.side && encounter.currentMove !== combatant" :data-current-turn="encounter.currentMove === combatant" :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)" v-bind:key="'right-stat-' + index" :subject="combatant" :initiative="encounter.initiatives.get(combatant)" /> | <Statblock @selectPredator="left = combatant.containedIn.owner" @selectAlly="left = combatant" @select="doSelectRight(combatant)" class="right-stats" :data-destroyed="combatant.destroyed" :data-disabled="encounter.currentMove.side === combatant.side && encounter.currentMove !== combatant" :data-current-turn="encounter.currentMove === combatant" :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)" v-bind:key="'right-stat-' + index" :subject="combatant" :initiative="encounter.initiatives.get(combatant)" /> | ||||
| </div> | </div> | ||||
| <div class="statblock-separator" id="statblock-separator-left"></div> | |||||
| <div class="statblock-separator" id="statblock-separator-center"></div> | |||||
| <div class="statblock-separator" id="statblock-separator-right"></div> | |||||
| <div id="log"> | <div id="log"> | ||||
| </div> | </div> | ||||
| <div class="left-fader"> | <div class="left-fader"> | ||||
| @@ -59,32 +61,6 @@ import { Side, Encounter } from '@/game/combat' | |||||
| right: null, | right: null, | ||||
| combatants: null | combatants: null | ||||
| } | } | ||||
| }, | |||||
| methods: { | |||||
| horizWheelLeft (event: MouseWheelEvent) { | |||||
| const target = this.$el.querySelector("#left-stats") | |||||
| if (target !== null) { | |||||
| target.scrollBy({ top: 0, left: event.deltaY, behavior: 'smooth' }) | |||||
| } | |||||
| }, | |||||
| horizWheelRight (event: MouseWheelEvent) { | |||||
| const target = this.$el.querySelector("#right-stats") | |||||
| if (target !== null) { | |||||
| target.scrollBy({ top: 0, left: event.deltaY, behavior: 'smooth' }) | |||||
| } | |||||
| }, | |||||
| doSelectLeft (combatant: Creature) { | |||||
| if (combatant.side !== this.$props.encounter.currentMove.side) { | |||||
| this.$data.left = combatant | |||||
| } | |||||
| }, | |||||
| doSelectRight (combatant: Creature) { | |||||
| if (combatant.side !== this.$props.encounter.currentMove.side) { | |||||
| this.$data.right = combatant | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| ) | ) | ||||
| @@ -127,21 +103,7 @@ export default class Combat extends Vue { | |||||
| } | } | ||||
| this.encounter.nextMove() | this.encounter.nextMove() | ||||
| if (this.encounter.currentMove.side === Side.Heroes) { | |||||
| this.$data.left = this.encounter.currentMove | |||||
| this.$el.querySelector("#left-stats ") | |||||
| } else if (this.encounter.currentMove.side === Side.Monsters) { | |||||
| this.$data.right = this.encounter.currentMove | |||||
| } | |||||
| // scroll to the newly selected creature | |||||
| this.$nextTick(() => { | |||||
| const creature: HTMLElement|null = this.$el.querySelector("[data-current-turn]") | |||||
| if (creature !== null) { | |||||
| creature.scrollIntoView() | |||||
| } | |||||
| }) | |||||
| this.pickNext() | |||||
| } | } | ||||
| @Emit("executedRight") | @Emit("executedRight") | ||||
| @@ -160,7 +122,10 @@ export default class Combat extends Vue { | |||||
| } | } | ||||
| this.encounter.nextMove() | this.encounter.nextMove() | ||||
| this.pickNext() | |||||
| } | |||||
| pickNext () { | |||||
| if (this.encounter.currentMove.side === Side.Heroes) { | if (this.encounter.currentMove.side === Side.Heroes) { | ||||
| this.$data.left = this.encounter.currentMove | this.$data.left = this.encounter.currentMove | ||||
| } else if (this.encounter.currentMove.side === Side.Monsters) { | } else if (this.encounter.currentMove.side === Side.Monsters) { | ||||
| @@ -176,6 +141,38 @@ export default class Combat extends Vue { | |||||
| }) | }) | ||||
| } | } | ||||
| selectable (creature: Creature): boolean { | |||||
| return !creature.destroyed | |||||
| } | |||||
| horizWheelLeft (event: MouseWheelEvent) { | |||||
| const target = this.$el.querySelector("#left-stats") | |||||
| if (target !== null) { | |||||
| target.scrollBy({ top: 0, left: event.deltaY, behavior: 'smooth' }) | |||||
| } | |||||
| } | |||||
| horizWheelRight (event: MouseWheelEvent) { | |||||
| const target = this.$el.querySelector("#right-stats") | |||||
| if (target !== null) { | |||||
| target.scrollBy({ top: 0, left: event.deltaY, behavior: 'smooth' }) | |||||
| } | |||||
| } | |||||
| doSelectLeft (combatant: Creature) { | |||||
| if (combatant.side !== this.$props.encounter.currentMove.side && this.selectable(combatant)) { | |||||
| this.$data.left = combatant | |||||
| } | |||||
| } | |||||
| doSelectRight (combatant: Creature) { | |||||
| if (combatant.side !== this.$props.encounter.currentMove.side && this.selectable(combatant)) { | |||||
| this.$data.right = combatant | |||||
| } | |||||
| } | |||||
| created () { | created () { | ||||
| this.$data.left = this.encounter.combatants.filter(x => x.side === Side.Heroes)[0] | this.$data.left = this.encounter.combatants.filter(x => x.side === Side.Heroes)[0] | ||||
| this.$data.right = this.encounter.combatants.filter(x => x.side === Side.Monsters)[0] | this.$data.right = this.encounter.combatants.filter(x => x.side === Side.Monsters)[0] | ||||
| @@ -188,21 +185,8 @@ export default class Combat extends Vue { | |||||
| if (leftStats !== null) { | if (leftStats !== null) { | ||||
| leftStats.scrollTo(leftStats.getBoundingClientRect().width * 2, 0) | leftStats.scrollTo(leftStats.getBoundingClientRect().width * 2, 0) | ||||
| } | } | ||||
| this.encounter.nextMove() | |||||
| if (this.encounter.currentMove.side === Side.Heroes) { | |||||
| this.$data.left = this.encounter.currentMove | |||||
| } else if (this.encounter.currentMove.side === Side.Monsters) { | |||||
| this.$data.right = this.encounter.currentMove | |||||
| } | |||||
| // scroll to the newly selected creature | |||||
| this.$nextTick(() => { | |||||
| const creature: HTMLElement|null = this.$el.querySelector("[data-current-turn]") | |||||
| if (creature !== null) { | |||||
| creature.scrollIntoView() | |||||
| } | |||||
| }) | |||||
| this.pickNext() | |||||
| } | } | ||||
| } | } | ||||
| </script> | </script> | ||||
| @@ -210,6 +194,7 @@ export default class Combat extends Vue { | |||||
| <!-- Add "scoped" attribute to limit CSS to this component only --> | <!-- Add "scoped" attribute to limit CSS to this component only --> | ||||
| <style scoped> | <style scoped> | ||||
| .combat-layout { | .combat-layout { | ||||
| position: relative; | |||||
| display: grid; | display: grid; | ||||
| grid-template-rows: fit-content(50%) 10% [main-row-start] 1fr 20% [main-row-end] ; | grid-template-rows: fit-content(50%) 10% [main-row-start] 1fr 20% [main-row-end] ; | ||||
| grid-template-columns: 20% [main-col-start] 1fr 1fr [main-col-end] 20%; | grid-template-columns: 20% [main-col-start] 1fr 1fr [main-col-end] 20%; | ||||
| @@ -249,6 +234,26 @@ export default class Combat extends Vue { | |||||
| grid-area: 1 / 3 / 2 / 5; | grid-area: 1 / 3 / 2 / 5; | ||||
| } | } | ||||
| #statblock-separator-left { | |||||
| grid-area: 1 / 1 / 2 / 1; | |||||
| } | |||||
| #statblock-separator-center { | |||||
| grid-area: 1 / 3 / 2 / 3; | |||||
| } | |||||
| #statblock-separator-right { | |||||
| grid-area: 1 / 5 / 2 / 5; | |||||
| } | |||||
| .statblock-separator { | |||||
| position: absolute; | |||||
| width: 10px; | |||||
| height: 100%; | |||||
| transform: translate(-5px, 0); | |||||
| background: linear-gradient(90deg, transparent, #111 3px, #111 7px, transparent 10px); | |||||
| } | |||||
| .stat-column { | .stat-column { | ||||
| overflow-x: scroll; | overflow-x: scroll; | ||||
| overflow-y: auto; | overflow-y: auto; | ||||