map checker preview version

This commit is contained in:
Alexander Drozdov
2020-06-24 12:14:57 +03:00
parent fe76cafbb9
commit ef7e1bbb90
13 changed files with 260 additions and 22 deletions
+6
View File
@@ -16,6 +16,12 @@ class MainProcessBinding extends EventTarget {
this.selfEmitPriceCheck(data)
})
electron.ipcRenderer.on(ipcEvent.MAP_CHECK, (e, data) => {
this.dispatchEvent(new CustomEvent(ipcEvent.MAP_CHECK, {
detail: data
}))
})
electron.ipcRenderer.on(ipcEvent.LEAGUE_SELECTED, (e, leagueId) => {
this.dispatchEvent(new CustomEvent(ipcEvent.LEAGUE_SELECTED, {
detail: leagueId
+16 -1
View File
@@ -112,7 +112,22 @@ export const defaultConfig: Config = {
wmZorder: 3,
wmFlags: ['hide-on-blur', 'skip-menu'],
selectedStats: [
// { text: '' }
{
text: 'Slaying Enemies close together has a #% chance to attract monsters from Beyond',
markedAs: 'desirable'
},
{
text: '#% maximum Player Resistances',
markedAs: 'warning'
},
{
text: 'Monsters reflect #% of Physical Damage',
markedAs: 'danger'
},
{
text: 'Area contains two Unique Bosses',
markedAs: 'desirable'
}
]
},
// --- DEFAULT ---
+68
View File
@@ -0,0 +1,68 @@
<template>
<button @click="handleClick"
class="px-2 leading-none py-2 m-0 text-left flex items-center"
:class="state === 'danger' ? 'bg-red-700'
: state === 'warning' ? 'bg-orange-600'
: state === 'desirable' ? 'bg-green-700'
: 'hover:bg-gray-700'">
<template>
<i v-if="!state"
class="inline-block mr-2" style="min-width: 1rem;">{{ '\u2009' }}</i>
<i v-else
class="fas mr-2 text-center" style="min-width: 1rem;"
:class="state === 'danger' ? 'fa-skull-crossbones'
: state === 'warning' ? 'fa-exclamation-triangle'
: 'fa-check'"></i>
</template>
<item-modifier-text :text="stat.text" :roll="stat.roll" class="truncate" />
</button>
</template>
<script>
import ItemModifierText from '../ui/ItemModifierText'
import { Config } from '@/web/Config'
export default {
components: { ItemModifierText },
props: {
stat: {
type: Object,
required: true
}
},
computed: {
state () {
return this.entryInSelected && this.entryInSelected.markedAs
},
entryInSelected () {
return this.config.selectedStats.find(_ => _.text === this.stat.ref)
},
config () {
return Config.store.widgets.find(widget => widget.wmType === 'map-check')
}
},
methods: {
handleClick () {
if (!this.entryInSelected) {
this.config.selectedStats.push({
text: this.stat.ref,
markedAs: 'danger'
})
return
}
switch (this.entryInSelected.markedAs) {
case 'danger':
this.entryInSelected.markedAs = 'warning'
break
case 'warning':
this.entryInSelected.markedAs = 'desirable'
break
case 'desirable':
this.config.selectedStats = this.config.selectedStats.filter(selected => selected !== this.entryInSelected)
break
}
}
}
}
</script>
+92
View File
@@ -0,0 +1,92 @@
<template>
<widget :config="{ ...config, anchor }" move-handles="none" readonly :removable="false">
<div class="bg-gray-800 text-gray-200" style="min-width: 320px;" :style="{ 'max-width': `${wm.width - wm.poeUiWidth}px` }">
<div class="bg-gray-900 py-1 px-4 text-center">{{ mapName }}</div>
<div v-if="!item" class="px-8 py-2">
Item under cursor is not a map.
</div>
<div v-else class="py-2 pr-8 flex flex-col">
<map-stat-button v-for="stat in mapStats" :key="stat.text"
:stat="stat" />
</div>
<div class="px-8 py-2">
<span class="bg-gray-200 text-gray-800 rounded px-1">Preview Version</span><span> More features and configuration options to come in the next release</span>
</div>
</div>
</widget>
</template>
<script>
import Widget from '../overlay/Widget'
import { MainProcess } from '@/ipc/main-process-bindings'
import { MAP_CHECK } from '@/ipc/ipc-event'
import { parseClipboard, ItemCategory, ItemRarity } from '@/parser'
import MapStatButton from './MapStatButton'
import { prepareMapStats } from './prepare-map-stats'
// import CheckPositionCircle from './CheckPositionCircle'
export default {
components: {
Widget,
MapStatButton
},
props: {
config: {
type: Object,
required: true
}
},
created () {
MainProcess.addEventListener(MAP_CHECK, ({ detail: e }) => {
this.wm.show(this.config.wmId)
this.checkPosition = {
x: e.position.x - window.screenX,
y: e.position.y - window.screenY
}
this.item = null
const item = parseClipboard(e.clipboard)
if (item.category === ItemCategory.Map) {
this.item = item
}
})
},
inject: ['wm'],
data () {
this.config.wmWants = 'hide'
return {
checkPosition: { x: 1, y: 1 },
item: null
}
},
computed: {
anchor () {
const side = this.checkPosition.x > (this.wm.width / 2)
? 'inventory'
: 'stash'
return {
pos: side === 'stash' ? 'cl' : 'cr',
y: 50,
x: side === 'stash'
? (this.wm.poeUiWidth / this.wm.width) * 100
: ((this.wm.width - this.wm.poeUiWidth) / this.wm.width) * 100
}
},
mapName () {
if (!this.item) {
return 'Invalid item'
}
if (this.item.rarity === ItemRarity.Unique) {
return this.item.name || this.item.baseType
} else {
return this.item.baseType || this.item.name
}
},
mapStats () {
return prepareMapStats(this.item)
}
}
}
</script>
+26
View File
@@ -0,0 +1,26 @@
import { ParsedItem } from '@/parser/ParsedItem'
import { getRollAsSingleNumber } from '@/parser/utils'
type PreparedStat = {
text: string
ref: string
roll?: number
}
export function prepareMapStats (item: ParsedItem): PreparedStat[] {
return item.modifiers.map(mod => {
const prepared = {
text: mod.string,
ref: mod.stat.ref,
roll: mod.values && getRollAsSingleNumber(mod.values)
}
if (mod.negate) {
if (prepared.roll != null) {
prepared.roll = -1 * prepared.roll
}
}
return prepared
})
}
+11 -2
View File
@@ -44,7 +44,9 @@ export default {
active: false,
gameFocused: false,
hideUI: false,
devicePixelRatio: null
devicePixelRatio: null,
width: window.innerWidth,
height: window.innerHeight
}
},
watch: {
@@ -98,8 +100,10 @@ export default {
})
window.addEventListener('resize', () => {
this.devicePixelRatio = window.devicePixelRatio
this.width = window.innerWidth
this.height = window.innerHeight
})
this.devicePixelRatio = window.devicePixelRatio
this.devicePixelRatio = window.devicePixelRatio // trigger watcher
},
mounted () {
this.$nextTick(() => {
@@ -134,6 +138,11 @@ export default {
return this.widgets
.filter(w => w.wmZorder !== 'exclusive')
.sort((a, b) => b.wmZorder - a.wmZorder)[0] // guaranteed to always exist because of the 'widget-menu'
},
poeUiWidth () {
// sidebar is 370px at 800x600
const ratio = 370 / 600
return Math.round(this.height * ratio)
}
},
methods: {
+1 -1
View File
@@ -10,7 +10,7 @@
:class="$style.action">hide</button>
<button v-if="!readonly" @click="toggleEdit"
:class="[$style.action, { [$style.active]: isEditing }]">edit</button>
<button @click="toggleMove"
<button v-if="moveHandles !== 'none'" @click="toggleMove"
:class="[$style.action, { [$style.active]: isMoving }]">move</button>
<button v-if="removable" @mousedown="startRemoveTimer" @mouseup="cancelRemoveTimer" @mouseleave="cancelRemoveTimer"
:class="[$style.action, $style.removable, { [$style.removing]: isRemoving }]">delete</button>
+1 -9
View File
@@ -6,7 +6,7 @@
'flex-row-reverse': clickPosition === 'inventory',
}">
<div v-if="!isBrowserShown" class="layout-column flex-shrink-0"
:style="{ width: poeUiWidth }">
:style="{ width: `${wm.poeUiWidth}px` }">
</div>
<div id="price-window" class="layout-column flex-shrink-0 text-gray-200" style="width: 460px;">
<app-titlebar @close="closePriceCheck" :title="title">
@@ -110,15 +110,12 @@ export default {
MainProcess.addEventListener(PRICE_CHECK_CANCELED, () => {
this.wm.hide(this.config.wmId)
})
window.addEventListener('resize', this.updatePoeUiWidth)
this.updatePoeUiWidth()
},
data () {
this.config.wmWants = 'hide'
this.config.wmFlags = ['hide-on-blur', 'skip-menu']
return {
poeUiWidth: '1px',
checkPosition: { x: 1, y: 1 },
item: null,
showTips: false
@@ -179,11 +176,6 @@ export default {
methods: {
closePriceCheck () {
MainProcess.closeOverlay()
},
updatePoeUiWidth () {
// sidebar is 370px at 800x600
const ratio = 370 / 600
this.poeUiWidth = `${Math.round(window.innerHeight * ratio)}px`
}
}
}
@@ -7,8 +7,8 @@
'fas fa-check-square': !filter.disabled
}"></i>
<div class="search-text flex-1 mr-1 relative flex min-w-0" style="line-height: 1rem;">
<span class="truncate"><filter-stat-text :filter="filter" /></span>
<span class="search-text-full"><filter-stat-text :filter="filter" /></span>
<span class="truncate"><item-modifier-text :text="filter.text" :roll="filter.roll" /></span>
<span class="search-text-full"><item-modifier-text :text="filter.text" :roll="filter.roll" /></span>
</div>
</button>
<div class="flex">
@@ -76,10 +76,10 @@
</template>
<script>
import FilterStatText from './FilteStatText'
import ItemModifierText from '../../ui/ItemModifierText'
export default {
components: { FilterStatText },
components: { ItemModifierText },
props: {
filter: {
type: Object,
+5
View File
@@ -30,6 +30,11 @@ export default new Router({
path: 'debug',
name: 'settings.debug',
component: () => import(/* webpackChunkName: "settings" */ './settings/debug.vue')
},
{
path: 'maps',
name: 'settings.maps',
component: () => import(/* webpackChunkName: "settings" */ './settings/maps.vue')
}
]
}
+1
View File
@@ -5,6 +5,7 @@
<div class="px-2 pb-10 bg-gray-900 flex flex-col">
<router-link :to="{ name: 'settings.hotkeys' }" class="menu-item">Hotkeys</router-link>
<router-link :to="{ name: 'settings.general' }" class="menu-item">General</router-link>
<router-link :to="{ name: 'settings.maps' }" class="menu-item">Maps</router-link>
<router-link :to="{ name: 'settings.debug' }" class="menu-item">Debug</router-link>
<div style="min-width: 150px;"></div>
</div>
+20
View File
@@ -0,0 +1,20 @@
<template>
<div class="max-w-md p-2">
<div class="bg-gray-700 rounded px-2 py-1 mb-2 leading-none">
<i class="fas fa-info-circle"></i> You can click on stat to cycle through available marks: danger, warning, desirable, none.</div>
<span class="bg-gray-200 text-gray-800 rounded px-1">Preview Version</span><span> More features and configuration options to come in the next release</span>
</div>
</template>
<script>
import { Config } from '@/web/Config'
export default {
computed: {
config () {
return Config.store
}
}
}
</script>
@@ -12,24 +12,28 @@
<script>
export default {
props: {
filter: {
type: Object,
text: {
type: String,
required: true
},
roll: {
type: Number,
default: undefined
}
},
computed: {
parts () {
const res = []
this.filter.text.split(/(?<![#])[+-]?[#]/gm).forEach((text, idx, parts) => {
this.text.split(/(?<![#])[+-]?[#]/gm).forEach((text, idx, parts) => {
if (text !== '') {
res.push({ text })
}
if (idx !== (parts.length - 1)) {
if (this.filter.roll == null) {
if (this.roll == null) {
res.push({ text: '#' })
} else {
res.push({
text: this.filter.roll,
text: this.roll,
placeholder: true
})
}