|
|
@@ -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" /> |
|
|
<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> |
|
|
</div> |
|
|
<div class="action-description"> |
|
|
|
|
|
|
|
|
<div v-if="encounter.winner === null" class="action-description"> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<button @click="$emit('leaveCombat')" v-if="encounter.winner !== null" class="exit-combat"> |
|
|
|
|
|
Exit Combat |
|
|
|
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</template> |
|
|
</template> |
|
|
|
|
|
|
|
|
@@ -49,7 +52,7 @@ |
|
|
import { Component, Prop, Vue, Watch, Emit } from 'vue-property-decorator' |
|
|
import { Component, Prop, Vue, Watch, Emit } from 'vue-property-decorator' |
|
|
import { Creature } from '@/game/creature' |
|
|
import { Creature } from '@/game/creature' |
|
|
import { POV } from '@/game/language' |
|
|
import { POV } from '@/game/language' |
|
|
import { LogEntry } from '@/game/interface' |
|
|
|
|
|
|
|
|
import { LogEntry, LogLine } from '@/game/interface' |
|
|
import Statblock from './Statblock.vue' |
|
|
import Statblock from './Statblock.vue' |
|
|
import ActionButton from './ActionButton.vue' |
|
|
import ActionButton from './ActionButton.vue' |
|
|
import { Side, Encounter } from '@/game/combat' |
|
|
import { Side, Encounter } from '@/game/combat' |
|
|
@@ -93,7 +96,7 @@ export default class Combat extends Vue { |
|
|
executedLeft (entry: LogEntry) { |
|
|
executedLeft (entry: LogEntry) { |
|
|
this.writeLog(entry, "left-move") |
|
|
this.writeLog(entry, "left-move") |
|
|
|
|
|
|
|
|
this.writeLog(this.encounter.nextMove(), "left-move") |
|
|
|
|
|
|
|
|
this.writeLog(this.encounter.nextMove(), "center-move") |
|
|
this.pickNext() |
|
|
this.pickNext() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@@ -103,11 +106,11 @@ export default class Combat extends Vue { |
|
|
executedRight (entry: LogEntry) { |
|
|
executedRight (entry: LogEntry) { |
|
|
this.writeLog(entry, "right-move") |
|
|
this.writeLog(entry, "right-move") |
|
|
|
|
|
|
|
|
this.writeLog(this.encounter.nextMove(), "right-move") |
|
|
|
|
|
|
|
|
this.writeLog(this.encounter.nextMove(), "center-move") |
|
|
this.pickNext() |
|
|
this.pickNext() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
writeLog (entry: LogEntry, cls: string) { |
|
|
|
|
|
|
|
|
writeLog (entry: LogEntry, cls = "") { |
|
|
const log = this.$el.querySelector(".log") |
|
|
const log = this.$el.querySelector(".log") |
|
|
if (log !== null) { |
|
|
if (log !== null) { |
|
|
const before = log.querySelector("div.log-entry") |
|
|
const before = log.querySelector("div.log-entry") |
|
|
@@ -118,7 +121,10 @@ export default class Combat extends Vue { |
|
|
holder.appendChild(element) |
|
|
holder.appendChild(element) |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
holder.classList.add(cls) |
|
|
|
|
|
|
|
|
if (cls !== "") { |
|
|
|
|
|
holder.classList.add(cls) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
const hline = document.createElement("div") |
|
|
const hline = document.createElement("div") |
|
|
hline.classList.add("log-separator") |
|
|
hline.classList.add("log-separator") |
|
|
log.insertBefore(hline, before) |
|
|
log.insertBefore(hline, before) |
|
|
@@ -129,30 +135,41 @@ export default class Combat extends Vue { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
pickNext () { |
|
|
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 { |
|
|
selectable (creature: Creature): boolean { |
|
|
@@ -243,6 +260,19 @@ export default class Combat extends Vue { |
|
|
min-height: 100%; |
|
|
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 { |
|
|
.combat-layout { |
|
|
position: relative; |
|
|
position: relative; |
|
|
display: grid; |
|
|
display: grid; |
|
|
@@ -258,6 +288,7 @@ export default class Combat extends Vue { |
|
|
.log { |
|
|
.log { |
|
|
grid-area: main-row-start / main-col-start / main-row-end / main-col-end; |
|
|
grid-area: main-row-start / main-col-start / main-row-end / main-col-end; |
|
|
overflow-y: scroll; |
|
|
overflow-y: scroll; |
|
|
|
|
|
overflow-x: hidden; |
|
|
font-size: 12pt; |
|
|
font-size: 12pt; |
|
|
width: 100%; |
|
|
width: 100%; |
|
|
max-height: 100%; |
|
|
max-height: 100%; |
|
|
@@ -494,4 +525,56 @@ div.right-move { |
|
|
margin: 4pt 0pt 4pt; |
|
|
margin: 4pt 0pt 4pt; |
|
|
background: linear-gradient(90deg, transparent, #444 10%, #444 90%, transparent 100%); |
|
|
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> |
|
|
</style> |