|  |  | @@ -40,8 +40,11 @@ | 
		
	
		
			
			|  |  |  | <ActionButton @described="described" @executed="executedRight" v-for="(action, index) in right.validActions(right)" :key="'right-' + action.name + '-' + index" :action="action" :user="right" :target="right" :combatants="combatants" /> | 
		
	
		
			
			|  |  |  | </div> | 
		
	
		
			
			|  |  |  | </div> | 
		
	
		
			
			|  |  |  | <div class="action-description"> | 
		
	
		
			
			|  |  |  | <div v-if="encounter.winner === null" class="action-description"> | 
		
	
		
			
			|  |  |  | </div> | 
		
	
		
			
			|  |  |  | <button @click="$emit('leaveCombat')" v-if="encounter.winner !== null" class="exit-combat"> | 
		
	
		
			
			|  |  |  | Exit Combat | 
		
	
		
			
			|  |  |  | </button> | 
		
	
		
			
			|  |  |  | </div> | 
		
	
		
			
			|  |  |  | </template> | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -49,7 +52,7 @@ | 
		
	
		
			
			|  |  |  | import { Component, Prop, Vue, Watch, Emit } from 'vue-property-decorator' | 
		
	
		
			
			|  |  |  | import { Creature } from '@/game/creature' | 
		
	
		
			
			|  |  |  | import { POV } from '@/game/language' | 
		
	
		
			
			|  |  |  | import { LogEntry } from '@/game/interface' | 
		
	
		
			
			|  |  |  | import { LogEntry, LogLine } from '@/game/interface' | 
		
	
		
			
			|  |  |  | import Statblock from './Statblock.vue' | 
		
	
		
			
			|  |  |  | import ActionButton from './ActionButton.vue' | 
		
	
		
			
			|  |  |  | import { Side, Encounter } from '@/game/combat' | 
		
	
	
		
			
				|  |  | @@ -93,7 +96,7 @@ export default class Combat extends Vue { | 
		
	
		
			
			|  |  |  | executedLeft (entry: LogEntry) { | 
		
	
		
			
			|  |  |  | this.writeLog(entry, "left-move") | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | this.writeLog(this.encounter.nextMove(), "left-move") | 
		
	
		
			
			|  |  |  | this.writeLog(this.encounter.nextMove(), "center-move") | 
		
	
		
			
			|  |  |  | this.pickNext() | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -103,11 +106,11 @@ export default class Combat extends Vue { | 
		
	
		
			
			|  |  |  | executedRight (entry: LogEntry) { | 
		
	
		
			
			|  |  |  | this.writeLog(entry, "right-move") | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | this.writeLog(this.encounter.nextMove(), "right-move") | 
		
	
		
			
			|  |  |  | this.writeLog(this.encounter.nextMove(), "center-move") | 
		
	
		
			
			|  |  |  | this.pickNext() | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | writeLog (entry: LogEntry, cls: string) { | 
		
	
		
			
			|  |  |  | writeLog (entry: LogEntry, cls = "") { | 
		
	
		
			
			|  |  |  | const log = this.$el.querySelector(".log") | 
		
	
		
			
			|  |  |  | if (log !== null) { | 
		
	
		
			
			|  |  |  | const before = log.querySelector("div.log-entry") | 
		
	
	
		
			
				|  |  | @@ -118,7 +121,10 @@ export default class Combat extends Vue { | 
		
	
		
			
			|  |  |  | holder.appendChild(element) | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | holder.classList.add(cls) | 
		
	
		
			
			|  |  |  | if (cls !== "") { | 
		
	
		
			
			|  |  |  | holder.classList.add(cls) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | const hline = document.createElement("div") | 
		
	
		
			
			|  |  |  | hline.classList.add("log-separator") | 
		
	
		
			
			|  |  |  | log.insertBefore(hline, before) | 
		
	
	
		
			
				|  |  | @@ -129,30 +135,41 @@ export default class Combat extends Vue { | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | pickNext () { | 
		
	
		
			
			|  |  |  | if (this.encounter.currentMove.side === Side.Heroes) { | 
		
	
		
			
			|  |  |  | this.$data.left = this.encounter.currentMove | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (this.encounter.currentMove.containedIn !== null) { | 
		
	
		
			
			|  |  |  | this.$data.right = this.encounter.currentMove.containedIn.owner | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } else if (this.encounter.currentMove.side === Side.Monsters) { | 
		
	
		
			
			|  |  |  | this.$data.right = this.encounter.currentMove | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (this.encounter.currentMove.containedIn !== null) { | 
		
	
		
			
			|  |  |  | this.$data.left = this.encounter.currentMove.containedIn.owner | 
		
	
		
			
			|  |  |  | // Did one side win? | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (this.encounter.winner !== null) { | 
		
	
		
			
			|  |  |  | this.writeLog( | 
		
	
		
			
			|  |  |  | new LogLine( | 
		
	
		
			
			|  |  |  | `game o-vore lmaoooooooo` | 
		
	
		
			
			|  |  |  | ), | 
		
	
		
			
			|  |  |  | "center-move" | 
		
	
		
			
			|  |  |  | ) | 
		
	
		
			
			|  |  |  | } else { | 
		
	
		
			
			|  |  |  | if (this.encounter.currentMove.side === Side.Heroes) { | 
		
	
		
			
			|  |  |  | this.$data.left = this.encounter.currentMove | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (this.encounter.currentMove.containedIn !== null) { | 
		
	
		
			
			|  |  |  | this.$data.right = this.encounter.currentMove.containedIn.owner | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } else if (this.encounter.currentMove.side === Side.Monsters) { | 
		
	
		
			
			|  |  |  | this.$data.right = this.encounter.currentMove | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (this.encounter.currentMove.containedIn !== null) { | 
		
	
		
			
			|  |  |  | this.$data.left = this.encounter.currentMove.containedIn.owner | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | // scroll to the newly selected creature | 
		
	
		
			
			|  |  |  | this.$nextTick(() => { | 
		
	
		
			
			|  |  |  | const creature: HTMLElement|null = this.$el.querySelector("[data-current-turn]") | 
		
	
		
			
			|  |  |  | if (creature !== null) { | 
		
	
		
			
			|  |  |  | this.scrollParentTo(creature) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | const target: HTMLElement|null = this.$el.querySelector("[data-active]") | 
		
	
		
			
			|  |  |  | if (target !== null) { | 
		
	
		
			
			|  |  |  | this.scrollParentTo(target) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | // scroll to the newly selected creature | 
		
	
		
			
			|  |  |  | this.$nextTick(() => { | 
		
	
		
			
			|  |  |  | const creature: HTMLElement|null = this.$el.querySelector("[data-current-turn]") | 
		
	
		
			
			|  |  |  | if (creature !== null) { | 
		
	
		
			
			|  |  |  | this.scrollParentTo(creature) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | const target: HTMLElement|null = this.$el.querySelector("[data-active]") | 
		
	
		
			
			|  |  |  | if (target !== null) { | 
		
	
		
			
			|  |  |  | this.scrollParentTo(target) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | selectable (creature: Creature): boolean { | 
		
	
	
		
			
				|  |  | @@ -243,6 +260,19 @@ export default class Combat extends Vue { | 
		
	
		
			
			|  |  |  | min-height: 100%; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | .exit-combat { | 
		
	
		
			
			|  |  |  | grid-area: 2 / main-col-start / main-row-start / main-col-end; | 
		
	
		
			
			|  |  |  | width: 100%; | 
		
	
		
			
			|  |  |  | padding: 4pt; | 
		
	
		
			
			|  |  |  | flex: 0 1; | 
		
	
		
			
			|  |  |  | background: #333; | 
		
	
		
			
			|  |  |  | border-color: #666; | 
		
	
		
			
			|  |  |  | border-style: outset; | 
		
	
		
			
			|  |  |  | user-select: none; | 
		
	
		
			
			|  |  |  | color: #eee; | 
		
	
		
			
			|  |  |  | font-size: 36px; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | .combat-layout { | 
		
	
		
			
			|  |  |  | position: relative; | 
		
	
		
			
			|  |  |  | display: grid; | 
		
	
	
		
			
				|  |  | @@ -258,6 +288,7 @@ export default class Combat extends Vue { | 
		
	
		
			
			|  |  |  | .log { | 
		
	
		
			
			|  |  |  | grid-area: main-row-start / main-col-start / main-row-end / main-col-end; | 
		
	
		
			
			|  |  |  | overflow-y: scroll; | 
		
	
		
			
			|  |  |  | overflow-x: hidden; | 
		
	
		
			
			|  |  |  | font-size: 12pt; | 
		
	
		
			
			|  |  |  | width: 100%; | 
		
	
		
			
			|  |  |  | max-height: 100%; | 
		
	
	
		
			
				|  |  | @@ -494,4 +525,56 @@ div.right-move { | 
		
	
		
			
			|  |  |  | margin: 4pt 0pt 4pt; | 
		
	
		
			
			|  |  |  | background: linear-gradient(90deg, transparent, #444 10%, #444 90%, transparent 100%); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | .left-move { | 
		
	
		
			
			|  |  |  | animation: left-fly-in 1s; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | .right-move { | 
		
	
		
			
			|  |  |  | animation: right-fly-in 1s; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | .center-move { | 
		
	
		
			
			|  |  |  | animation: center-fly-in 1s; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | @keyframes left-fly-in { | 
		
	
		
			
			|  |  |  | 0% { | 
		
	
		
			
			|  |  |  | opacity: 0; | 
		
	
		
			
			|  |  |  | transform: translate(-50px, 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 50% { | 
		
	
		
			
			|  |  |  | transform: translate(0, 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 100% { | 
		
	
		
			
			|  |  |  | opacity: 1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | @keyframes right-fly-in { | 
		
	
		
			
			|  |  |  | 0% { | 
		
	
		
			
			|  |  |  | opacity: 0; | 
		
	
		
			
			|  |  |  | transform: translate(50px, 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 50% { | 
		
	
		
			
			|  |  |  | transform: translate(0, 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 100% { | 
		
	
		
			
			|  |  |  | opacity: 1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | @keyframes center-fly-in { | 
		
	
		
			
			|  |  |  | 0% { | 
		
	
		
			
			|  |  |  | opacity: 0; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 100% { | 
		
	
		
			
			|  |  |  | opacity: 1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | </style> |