- // ==UserScript==
- // @name Janka Tietzova
- // @namespace http://tampermonkey.net/
- // @version 2.1.1
- // @description A user script for The West, optimized Dobby2 for butt plugs and cake decorations.
- // @author Chvostnatý Gábor
- // @include https://*.the-west.*/game.php*
- // @license MIT
- // @icon data:image/jpeg;base64,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
- // @grant none
- // @downloadURL https://update.gf.qytechs.cn/scripts/497915/Zdenka%20Studenkova.user.js
- // @updateURL https://update.gf.qytechs.cn/scripts/497915/Zdenka%20Studenkova.meta.js
- // ==/UserScript==
-
-
-
-
- (function() {
- async function sleep(milliseconds) {
- await new Promise(r => setTimeout(r, milliseconds))
- }
-
- function parseConsumableBonuses(bonuses) {
- const { energyText, motivationText, healthText, speedText, luckText, dropText, experienceText, moneyText } = Vajda.searchKeys[Vajda.language]
-
- const result = {
- energy: 0,
- health: 0,
- motivation: 0,
- hasBuffs: false,
- buffs: {
- character: {
- luck: 0,
- money: 0,
- experience: 0,
- drop: 0
- },
- travel: 0
- }
- }
-
- function getValue(bonus, bonusText) {
- return Number(bonus.toLowerCase().replace(bonusText.toLowerCase(), '').replace(' ', '').replace('%', '').replace('+', ''))
- }
-
- for (const bonus of bonuses) {
- if ( bonus.includes(energyText) ) {
- result.energy = getValue(bonus, energyText)
- continue
- }
-
- if ( bonus.includes(motivationText) ) {
- result.motivation = getValue(bonus, motivationText)
- continue
- }
-
- if ( bonus.includes(healthText) ) {
- result.health = getValue(bonus, healthText)
- continue
- }
-
- if ( bonus.includes(speedText) ) {
- result.buffs.travel = getValue(bonus, speedText)
- result.hasBuffs = true
- continue
- }
-
- if ( bonus.includes(luckText) ) {
- result.buffs.character.luck = getValue(bonus, luckText)
- result.hasBuffs = true
- continue
- }
-
- if ( bonus.includes(experienceText) ) {
- result.buffs.character.experience = getValue(bonus, experienceText)
- result.hasBuffs = true
- continue
- }
-
- if ( bonus.includes(moneyText) ) {
- result.buffs.character.money = getValue(bonus, moneyText)
- result.hasBuffs = true
- continue
- }
-
- if ( bonus.includes(dropText) ) {
- result.buffs.character.drop = getValue(bonus, dropText)
- result.hasBuffs = true
- }
- }
-
- return result
- }
-
-
- class Job {
- constructor(x, y, id, groupId) {
- this.x = x
- this.y = y
- this.id = id
- this.groupId = groupId
- this.isSilver = false
- this.distances = []
- this.experience = 0
- this.money = 0
- this.motivation = 0
- this.stopMotivation = 75
- this.set = -1
- this.bestEquipment_ = undefined
- }
-
- setIsSilver(val) {
- this.isSilver = val
- return this
- }
-
- setExperience(val) {
- this.experience = val
- return this
- }
-
- setMoney(val) {
- this.money = val
- return this
- }
-
- setMotivation(valOrUpdater) {
- if ( typeof valOrUpdater === 'function' ) {
- this.motivation = valOrUpdater(this.motivation)
- } else {
- this.motivation = valOrUpdater
- }
-
- this.motivation = Math.min(100, this.motivation)
-
- return this
- }
-
- setStopMotivation(val) {
- this.stopMotivation = val
- return this
- }
-
- setSet(index) {
- this.set = index
- return this
- }
-
- getDistances() {
- return this.distances
- }
-
- async loadMotivation() {
- await Ajax.get('job', 'job', {jobId: this.id, x: this.x, y: this.y}, (r) => {
- this.motivation = r.motivation * 100
- })
-
- return this.motivation
- }
-
- /**
- * Calculate job distance to current character position
- */
- calculateDistance() {
- this.distance = GameMap.calcWayTime({x: this.x, y: this.y}, Character.position)
- return this.distance
- }
-
- /**
- * Calculate job distance to other selected jobs
- */
- calculateJobDistances() {
- this.distances = []
- for ( const job of Vajda.addedJobs ) {
- this.distances.push(GameMap.calcWayTime({x: this.x, y: this.y}, {x: job.x, y: job.y}))
- }
- return this.distances
- }
-
-
- saveBestEquipment() {
- const skills = JobsModel.Jobs.find(j => j.id === this.id).get('skills')
- const set = west.item.Calculator.getBestSet(skills, this.id)
- const itemIds = set && set.getItems() || []
- this.bestEquipment_ = itemIds
- return itemIds
- }
-
- get bestEquipment() {
- return this.bestEquipment_ === undefined ? this.saveBestEquipment() : this.bestEquipment_
- }
-
-
- getBestEquipment() {
- if (!Bag.loaded) {
- EventHandler.listen('inventory_loaded', function() {
- this.getBestEquipment()
- return EventHandler.ONE_TIME_EVENT
- })
- return
- }
-
- const items = Bag.getItemsByItemIds(this.bestEquipment)
- const result = []
-
- for (const item of items) {
- const wearItem = Wear.get(item.getType())
- if (!wearItem || (wearItem && (wearItem.getItemBaseId() !== item.getItemBaseId() || wearItem.getItemLevel() < item.getItemLevel()))) {
- result.push(item)
- }
- }
- return result.map(item => item.obj.getId())
- }
- }
-
- class Consumable {
- constructor(id, image, name) {
- this.id = id
- this.image = image
- this.name = name
- this.energy = 0
- this.motivation = 0
- this.health = 0
- this.isSelected_ = false
- this.count = 0
- }
-
- isCakeDecoration() {
- return this.id === 53339000
- }
-
-
- removeOne() {
- this.count -= 1
-
- if ( this.count === 0 ) {
- const consumables = Manager.consumables
- const index = consumables.findIndex(c => c.id === this.id)
- consumables.splice(index, 1)
- }
- return this
- }
-
- setCount(valOrUpdater) {
- if ( typeof valOrUpdater === 'function' ) {
- this.count = valOrUpdater(this.count)
- } else {
- this.count = valOrUpdater
- }
-
- this.count = Math.max(0, this.count)
- return this
- }
-
- setEnergy(val) {
- this.energy = val
- return this
- }
-
- setMotivation(val) {
- this.motivation = val
- return this
- }
-
- setHealth(val) {
- this.health = val
- return this
- }
-
- setIsSelected(isSelected) {
- this.isSelected_ = isSelected
- return this
- }
-
- hasCooldown() {
- return this.energy > 0 || this.motivation > 0 || this.health > 0
- }
-
- getBuffHTML() {
- return '<strong>No Buffs</strong>'
- }
-
- get isSelected() {
- return this.isSelected_
- }
- }
-
- class Buff extends Consumable {
- constructor(id, image, name, buffs) {
- super(id, image, name, buffs)
- this.buffs_ = buffs
- }
-
- getBuffImage() {
- return `https://westsk.innogamescdn.com/images/buffs/${this.getBuffType()}.jpg`
- }
-
- getBuffType() {
- return this.buffs_.travel === 0 ? 'character' : 'travel'
- }
-
- canUseAsBuff() {
- return CharacterSkills.buffs[this.getBuffType()] === null && !this.hasCooldown()
- }
-
- getBuffHTML() {
- const containerStyle = `'
- display: grid;
- grid-template-columns: 30px auto;
- '`
-
- const imgContainerStyle = `'
- display: flex;
- padding-bottom: 5px;
- '`
-
- const buffsContainerStyle = `'
- display: grid;
- grid-template-rows: repeat(auto-fill, 15px);
- transform: translateY(5px)
- '`
- const buffs = this.buffs.reduce((acc, b) => acc.concat(`<p>${b}</p>`), '')
-
- const html = `
- <div style=${containerStyle}>
- <span style=${imgContainerStyle}>
- <img style=align-self:end width=25px height=25px src=${this.getBuffImage()} alt='Buff Image'>
- </span>
-
- <span style=${buffsContainerStyle}>
- ${
- buffs
- }
- </span>
- </div>
- `
-
- return html
- }
-
- removeOne() {
- this.count -= 1
-
- if ( this.count === 0 ) {
- const consumables = Manager.consumables
- const buffs = Manager.buffs
- let index = consumables.findIndex(c => c.id === this.id)
- if ( index !== -1 ) {
- consumables.splice(index, 1)
- return this
- }
- index = buffs.findIndex(b => b.id === this.id)
- if ( index !== -1 ) {
- buffs.splice(index, 1)
- if ( Manager.selectedBuffs.some(b => b.id === this.id) ) {
- Manager.selectedBuffs_[this.getBuffType()] = null
- }
- }
- }
- return this
- }
-
- get isSelected() {
- return Manager.selectedBuffs.some(b => b.id === this.id) || this.isSelected_
- }
-
-
- get buffs() {
- if ( this.getBuffType() === 'travel' ) {
- return [`+${this.buffs_.travel}% speed`]
- }
-
- const buffs = []
- for ( const buff in this.buffs_.character ) {
- if ( this.buffs_.character[buff] > 0 ) {
- buffs.push(`+${this.buffs_.character[buff]}% ${buff}`)
- }
- }
- return buffs
- }
- }
-
-
- class ConsumablesManager {
- selectedBuffs_ = {
- travel: null,
- character: null
- }
-
- constructor() {
- this.consumables_ = []
- this.buffs_ = []
- this.isOptimized_ = false
- this.jobsLeftInRound_ = 0
- this.schedule_ = []
- this.selectedBuffs_ = {
- travel: null,
- character: null
- }
- }
-
- async loadJobMotivation(updatedJobsMotivation = undefined) {
- let expectedJobCount = 0
- const uniqueJobsCount = Vajda.addedJobs.length
-
- if ( updatedJobsMotivation !== undefined ) {
- expedtedJobCount = updatedJobsMotivation.reduce((acc, curr) => acc + curr, 0)
-
- return { expectedJobCount, uniqueJobsCount }
- }
-
- for ( const job of Vajda.addedJobs ) {
- expectedJobCount += Math.max(await job.loadMotivation() - job.stopMotivation, 0)
-
- await sleep(500)
- }
-
- return { expectedJobCount, uniqueJobsCount }
- }
-
- async createSchedule(updatedJobsMotivation) {
- const bottlePlugs = this.consumables.find(c => c.id === 52871000)
-
- //in case the game runs in the background and the job to travel to is not canceled we gonna need extra energy point
- //this is unlikely to happen but the energy wont go to waste anyway so why the fuck not
- const { expectedJobCount, uniqueJobsCount } = await this.loadJobMotivation(updatedJobsMotivation)
-
- this.jobsLeftInRound = expectedJobCount
-
- const availableEnergy = Character.energy
- const energyToFill = expectedJobCount + uniqueJobsCount - availableEnergy
- const refillCount = Math.ceil(
- energyToFill / ( bottlePlugs.energy / 100 * Character.maxEnergy )
- )
-
- //use plugs when n jobs left in round
- const schedule = []
-
- for ( let i = 0; i < refillCount; i++ ) {
- //40 15s jobs in consumable cooldown
- schedule.push(40 + i*40)
- }
-
- this.schedule_ = schedule
-
- return schedule
- }
-
- isScheduledRefill() {
- return this.isOptimized_ && this.refillsLeft > 0 && this.jobsLeftInRound <= this.schedule.at(-1)
- }
-
- async checkSchedule(jobCount) {
- const bottlePlug = this.consumables.find(c => c.id === 52871000)
-
- for ( let i = 0; i < jobCount; i++ ) {
- this.jobsLeftInRound = p => p - 1
- if ( this.isScheduledRefill() ) {
- //the use of consumable blocks the start of new jobs for a short amount of time, so this sleep exists to prevent that
- await sleep(10000)
- this.useConsumableOrWaitForCooldown(bottlePlug)
- this.schedule.pop()
- this.jobsLeftInRound = p => p - (jobCount - i - 1)
- return
- }
- }
-
- if ( Character.energy - jobCount <= 10 ) {
- //same here
- await sleep(10000)
- this.useConsumableOrWaitForCooldown(bottlePlug)
- this.schedule.pop()
- }
- }
-
- canUseConsumable(consumable) {
- if ( consumable instanceof Buff ) {
- return consumable.canUseAsBuff()
- }
-
- if ( BuffList.cooldowns[consumable.id] !== undefined && BuffList.cooldowns[consumable.id].time > new ServerDate().getTime() ) {
- return false
- }
- return true
- }
-
- findProperConsumable(motivationMissing, energyMissing, averageMotivationMissing) {
- const consumablesPool = this.getSelectedConsumables()
-
- function betterEnergy(item1, item2) {
- let distanceItem1 = Math.abs(energyMissing - item1.energy)
- let distanceItem2 = Math.abs(energyMissing - item2.energy)
- return (distanceItem1 < distanceItem2 ) ? -1 : (distanceItem1 > distanceItem2) ? 1 : 0
- }
- function betterMotivation(item1, item2) {
- let distanceItem1 = Math.abs(averageMotivationMissing - item1.motivation)
- let distanceItem2 = Math.abs(averageMotivationMissing - item2.motivation)
- return (distanceItem2 < distanceItem1) ? item2 : item1
- }
- function findMotivationConsume(consumes) {
- let consumeToChoose = null
- for ( let i = 0; i < consumes.length; i++ ) {
- if ( consumeToChoose === null && consumes[i].motivation !== 0) {
- consumeToChoose = consumes[i]
- continue
- }
-
- if ( consumeToChoose !== null && consumes[i].motivation !== 0) {
- consumeToChoose = betterMotivation(consumeToChoose, consumables[i])
- }
- }
- return consumeToChoose
- }
- function findHealthConsume(consumes) {
- for ( let i = 0; i < consumes.length; i++ ) {
- if ( consumes[i].health !== 0 ) {
- return consumes[i]
- }
- }
- return null
- }
-
- if ( consumablesPool.length === 0 ) return null
-
- const consumables = consumablesPool.sort(betterEnergy)
-
- if ( Vajda.settings.addEnergy && energyMissing === 100 ) {
- return consumables[0]
- }
-
- if ( Vajda.settings.addMotivation && motivationMissing === Vajda.addedJobs.length ) {
- return findMotivationConsume(consumables)
- }
-
- if ( Vajda.settings.addHealth && Vajda.isHealthBelowLimit() ) {
- if ( this.isOptimized ) {
- this.schedule.pop()
- }
- return findHealthConsume(consumables)
- }
- }
-
- async useConsumable(consumable) {
- const item = Bag.getItemByItemId(consumable.id)
- item.showCooldown()
-
- if ( Vajda.shouldEquipHealthSet(consumable) )
- await Vajda.equipSet(Vajda.healthSet)
-
- ItemUse.doIt(consumable.id)
- consumable.removeOne()
-
- while(true) {
- if ( !this.canUseConsumable(consumable) ) {
- $('.tw2gui_dialog_framefix').remove()
- break
- }
- await sleep(1)
- }
-
- Vajda.currentState = 1
- }
-
- async useConsumableOrWaitForCooldown(consumableOrId, isSync = false) {
- const consumable = consumableOrId instanceof Consumable ? consumableOrId : this.getSelectedConsumables().find(c => c.id === consumableOrId)
- if ( consumable === undefined ) {
- return false
- }
-
- Vajda.currentState = 2
-
- while (true) {
- if ( consumable.hasCooldown() === false || this.canUseConsumable(consumable) ) {
- break
- }
-
- if ( !Vajda.isRunning ) {
- break
- }
-
- await sleep(1000)
- }
-
- await this.useConsumable(consumable)
-
- isSync && Vajda.run()
- }
-
- isConsumableAdded (item) {
- if ( item === undefined )
- return true
- for ( const consumable of this.consumables_ ) {
- if ( consumable.id === item.obj.item_id ) {
- return true
- }
- }
- for ( const buff of this.buffs_ ) {
- if ( buff.id === item.obj.item_id ) {
- return true
- }
- }
- return false
- }
-
- useBuff(type) {
- const buff = this.selectedBuffs_[type]
-
- if ( buff?.canUseAsBuff() ) {
- this.useConsumable(buff)
- }
- }
-
- addNewConsumable(item) {
- if ( this.isConsumableAdded(item) ) {
- return
- }
-
- const { energy, motivation, health, hasBuffs, buffs } = parseConsumableBonuses(item.obj.usebonus)
-
- if ( health === 0 && motivation === 0 && energy === 0 && !hasBuffs )
- return
-
- if ( hasBuffs ) {
- const buff = new Buff(item.obj.item_id, item.obj.image, item.obj.name, buffs)
- .setEnergy(energy)
- .setMotivation(motivation)
- .setHealth(health)
- .setCount(item.count)
-
- return buff.hasCooldown() ? this.consumables_.push(buff) : this.buffs_.push(buff)
- }
-
- const consumable = new Consumable(item.obj.item_id, item.obj.image, item.obj.name)
- .setEnergy(energy)
- .setMotivation(motivation)
- .setHealth(health)
- .setCount(item.count)
- this.consumables.push(consumable)
- }
-
- hasEnoughPlugsAndDecorations() {
- const bottlePlugs = this.consumables.find(c => c.id === 52871000)
- const decorations = this.consumables.find(c => c.id === 53339000)
-
- if ( !bottlePlugs || !decorations ) {
- new UserMessage("No plugs or decorations were found, defaulting back to selected consumables", UserMessage.TYPE_HINT).show()
- this.isOptimized_ = false
- return false
- }
- return true
- }
-
- getSelectedConsumables() {
- if ( this.isOptimized_ ) {
- const bottlePlugs = this.consumables.find(c => c.id === 52871000)
- const decorations = this.consumables.find(c => c.id === 53339000)
-
- return [bottlePlugs, decorations]
- } else {
- return this.consumables.filter(c => c.isSelected === true)
- }
- }
-
- addSelectedConsumable(val) {
- if ( typeof val === 'number' )
- this.consumables.at(val).isSelected = true
-
- if ( val instanceof Consumable )
- this.consumables.find(c => c.id === val.id).isSelected = true
- }
-
- get schedule() {
- return this.schedule_
- }
-
- set schedule(val) {
- this.schedule_ = val
- }
-
- get consumables() {
- return this.consumables_
- }
-
- set consumables(val) {
- this.consumables_ = val
- }
-
- get isOptimized() {
- return this.isOptimized_
- }
-
- set isOptimized(valOrUpdater) {
- if ( typeof valOrUpdater === 'function' ) {
- this.isOptimized_ = valOrUpdater(this.isOptimized_)
- } else {
- this.isOptimized_ = valOrUpdater
- }
- }
-
- get jobsLeftInRound() {
- return this.jobsLeftInRound_
- }
-
- set jobsLeftInRound(valOrUpdater) {
- if ( typeof valOrUpdater === 'function' ) {
- this.jobsLeftInRound_ = valOrUpdater(this.jobsLeftInRound_)
- } else {
- this.jobsLeftInRound_ = valOrUpdater
- }
- }
-
- get refillsLeft() {
- return this.schedule.length
- }
-
- get buffs() {
- return this.buffs_
- }
-
- get selectedBuffs() {
- const res = []
- for ( const type in this.selectedBuffs_ ) {
- this.selectedBuffs_[type] && res.push(this.selectedBuffs_[type])
- }
-
- return res
- }
-
- set selectedBuffs(buff) {
- const type = buff.getBuffType()
- if ( this.selectedBuffs_[type]?.id === buff.id ) {
- this.selectedBuffs_[type] = null
-
- return
- }
- this.selectedBuffs_[type] = buff
- new UserMessage(`New ${type} buff selected`, UserMessage.TYPE_SUCCESS).show()
- }
- }
-
-
- class ActivityObserver {
- constructor() {
- const fiveMinutes = 5 * 60 * 1000
- this.activityCheckTimeout_ = null
- this.refreshCount = 0
- this._isEnabled = false
- this.timeOut_ = fiveMinutes
- this.selectedConsumables = null
- }
-
- saveTempCookies() {
- const selectedConsumables = Manager.consumables.reduce((acc, c) => {
- c.isSelected && acc.push(c.id)
- return acc
- }, [])
- const timeOut = this.timeOut_
- const buffs = {
- travel: Manager.selectedBuffs_.travel?.id || null,
- character: Manager.selectedBuffs_.character?.id || null
- }
-
- const settings = {
- statistics: Vajda.statistics,
- selectedConsumables,
- buffs,
- timeOut,
- direction: Vajda.direction,
- currentJob: Vajda.currentJob,
- refreshCount: this.refreshCount + 1,
- schedule: Manager.schedule,
- jobsLeftInRound: Manager.jobsLeftInRound,
- travelSet: Vajda.travelSet,
- jobSet: Vajda.jobSet,
- healthSet: Vajda.healthSet
- }
-
- const expiracyDateTemporary = new Date()
- const hour = expiracyDateTemporary.getHours()
- expiracyDateTemporary.setHours(2,0,0)
-
- if ( hour > 2 )
- expiracyDateTemporary.setDate(expiracyDateTemporary.getDate() + 1)
-
- document.cookie = `vajdasession=${JSON.stringify(settings)};expires=${expiracyDateTemporary.toGMTString()};`
- }
-
- getTempCookies() {
- const cookies = document.cookie.split("=")
- for ( let i = 0; i < cookies.length; i++ ) {
- if ( cookies[i].includes("vajdasession") ) {
- const {
- timeOut, schedule, selectedConsumables, buffs, jobsLeftInRound, refreshCount, ...vajdaSettings
- } = JSON.parse(cookies[i+1].split(";")[0])
-
- this.selectedConsumables = selectedConsumables
- this.buffs = buffs
- this.refreshCount = refreshCount
- this.timeOut_ = timeOut
- this.isEnabled = true
- Manager.jobsLeftInRound = jobsLeftInRound
- Manager.schedule = schedule
- Vajda = {...Vajda, ...vajdaSettings, isRunning: true}
- document.cookie = 'vajdasession=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'
- return true
- }
- }
-
- return false
- }
-
- restartSession() {
- if ( Vajda.currentState === 2 ) {
- this.start()
- return
- }
-
- this.saveTempCookies()
- location.reload()
- }
-
- resumeSession() {
- Vajda.findAllConsumables()
- if ( !this.getTempCookies() ) return
- Vajda.createWindow(false)
- Vajda.run()
- }
-
- start(forceStart = false) {
- if ( !this.isEnabled && !forceStart ) return
-
- clearTimeout(this.activityCheckTimeout_)
- this.activityCheckTimeout_ = setTimeout(this.restartSession.bind(this), this.timeOut_)
- }
-
- stop() {
- this.isEnabled = false
- if ( this.activityCheckTimeout_ !== null )
- clearTimeout(this.activityCheckTimeout_)
- this.activityCheckTimeout_ = null
- }
-
- getTimeOut(convertToMinutes) {
- if ( convertToMinutes ) {
- return this.timeOut_ / 1000 / 60
- }
- return this.timeOut_
- }
-
- get isEnabled() {
- return this._isEnabled
- }
-
- set isEnabled(valOrUpdater) {
- if ( typeof valOrUpdater === 'function' ) {
- this._isEnabled = valOrUpdater(this._isEnabled)
- } else {
- this._isEnabled = valOrUpdater
- }
- }
-
- set timeOut(val) {
- this.timeOut_ = Math.max(Number(val) * 60 * 1000, 2.5 * 60 * 1000)
- }
- }
-
- window.Manager = new ConsumablesManager()
- window.Observer = new ActivityObserver()
-
-
- Vajda = {
- addedJobs: [],
- allJobs: [],
- addedJobTablePosition: {
- content: "0px",
- scrollbar:"0px"
- },
- consumableSelection: {
- energy: false,
- motivation: false,
- health: false,
- hideBuffs: false
- },
- consumableTablePosition: {
- content: '0px',
- scrollbar: '0px'
- },
- consumableUsed: [],
- currentJob: {
- job: 0,
- direction: true
- },
- currentState: 0,
- healthSet: -1,
- language: "",
- isLoaded: false,
- isRunning: false,
- jobFilter: {
- filterOnlySilver: false,
- filterNoSilver: false,
- filterCenterJobs: false,
- filterJob: ""
- },
- jobSet: -1,
- jobsLoaded: false,
- jobTablePosition: {
- content: "0px",
- scrollbar: "0px"
- },
- lastJobStartTime: undefined,
- states: [
- 'Idle',
- 'Running',
- 'Waiting for a consumable cooldown',
- 'Calculating optimal route'
- ],
- statistics: {
- sessionJobsCount: 0,
- sessionXpCount: 0,
- sessionMoneyCount: 0,
- totalJobsCount: 0,
- totalXpCount: 0,
- totalMoneyCount: 0
- },
- selectedSet: 0,
- sets: null,
- settings: {
- addEnergy: false,
- addMotivation: false,
- addHealth: false,
- healthStop: 10,
- setWearDelay: 5,
- jobDelayMin: 0,
- jobDelayMax: 0,
- addDeposit: {
- isEnabled: false,
- limit: NaN
- }
- },
- sortJobTableXp:0,
- sortJobTableDistance:0,
- travelSet: -1,
- regenerationSet: -1,
- window: null,
- searchKeys: {
- "en_DK":{
- energy:"Energy",
- energyText:"Energy increase:",
- motivation:"Work motivation",
- motivationText:"Work motivation increase:",
- health: "Health point bonus",
- healthText:"Health point bonus:"
- },
- "sk_SK": {
- energy:"Energie",
- energyText:"Zvýšenie energie:",
- motivation:"Pracovnej motivácie",
- motivationText:"Zvýšenie pracovnej motivácie:",
- health: "Bonus bodov zdravia",
- healthText:"Bonus bodov zdravia:",
- speedText: "Rýchlosť",
- experience: "skúseností",
- experienceText: "Skúseností z práce, duelov a boja o pevnosť",
- money: "peňazí",
- moneyText: "Peňazí z práce a duelov",
- luck: "šťastie",
- luckText: "Vylepšené šťastie",
- drop: "produktu",
- dropText: "Vylepšenie šance na získanie produktu"
- },
- "cs_CZ":{
- energy:"Energie",
- energyText:"Zvýšení energie:",
- motivation:"Pracovní motivace",
- motivationText:"Zvýšení pracovní motivace:",
- health: "Bonus zdraví",
- healthText:"Bonus zdraví:",
- speedText: "Rychlost",
- experience: "zkušeností",
- experienceText: "zkušeností z prací, duelů a bitev o pevnost",
- money: "prací",
- moneyText: "$ z prací a duelů",
- luck: "štěstí",
- luckText: "Vyšší šance na štěstí",
- drop: "produktu",
- dropText: "Vylepšené šance nálezu produktu"
- },
- "hu_HU":{
- energy:"Energia növekedése:",
- energyText:"Energia növekedése:",
- motivation:"Munka motiváció növelése:",
- motivationText:"Munka motiváció növelése:",
- health: "Életerő bónusz",
- healthText:"Életerő bónusz:"
- },
- "pl_PL":{
- energy:"Wzrost energii:",
- energyText:"Wzrost energii:",
- motivation:"Zwiększenie motywacji do pracy:",
- motivationText:"Zwiększenie motywacji do pracy:",
- health: "Bonus Punktów życia:",
- healthText:"Bonus Punktów życia:"
- },
- "ro_RO":{
- energy:"Energie mărită:",
- energyText:"Energie mărită:",
- motivation:"Creştere a motivaţiei de muncă:",
- motivationText:"Creştere a motivaţiei de muncă:",
- health: "Puncte de viaţă:",
- healthText:"Puncte de viaţă:"
- }
- }
- }
-
-
- Vajda.isNumber = function(potentialNumber) {
- return Number.isInteger(parseInt(potentialNumber))
- }
-
- Vajda.RNG = function(min, max) {
- let minN = Math.min(min, max)
- let maxN = Math.max(min, max)
-
- let number = Math.floor((minN + Math.random() * (maxN - minN + 1)))
- return number
- }
-
-
- Vajda.isAllowedToDepositMoney = function() {
- const hasMoreMoneyThanLimit = Vajda.settings.addDeposit.limit <= Character.money
- const hasHomeTown = Character.homeTown.town_id !== 0
-
- if ( hasHomeTown == false ) {
- new UserMessage("You don't have a home town", UserMessage.TYPE_HINT).show()
- return false
- }
-
- return Vajda.settings.addDeposit.isEnabled && hasMoreMoneyThanLimit
- }
-
-
- Vajda.getCookies = function() {
- const cookies = document.cookie.split("=")
- for ( let i = 0; i < cookies.length; i++ ) {
- if ( cookies[i].includes("vajdatemporary") ) {
- const obj = cookies[i+1].split(";")
- const tempObject = JSON.parse(obj[0])
- const tmpAddedJobs = tempObject.addedJobs
-
- for ( const job of tmpAddedJobs ) {
- const newJob = new Job(job.x, job.y, job.id, job.groupId)
- newJob
- .setIsSilver(job.isSilver)
- .setExperience(job.experience)
- .setMoney(job.money)
- .setMotivation(job.motivation)
- .setStopMotivation(job.stopMotivation)
- .setSet(job.set)
- Vajda.addedJobs.push(newJob)
- }
-
- Vajda.travelSet = tempObject.travelSet
- Vajda.jobSet = tempObject.jobSet
- Vajda.healthSet = tempObject.healthSet
- Vajda.currentJob = tempObject.currentJob
- Vajda.setSetForAllJobs()
- }
- if ( cookies[i].includes("vajdapermanent") ) {
- const obj = cookies[i+1].split(";")
- const permanentObject = JSON.parse(obj[0])
- const { isOptimized, isEnabled, timeOut, ...settings } = permanentObject.settings
-
- Manager.isOptimized = !!isOptimized
- Observer.isEnabled = !!isEnabled
- Observer.timeOut = timeOut || 5
- Vajda.settings = settings
- if ( !settings.addDeposit ) {
- Vajda.settings.addDeposit = {
- isEnabled: false,
- limit: NaN
- }
- }
- Vajda.statistics.totalJobsCount = Math.floor(permanentObject.totalJobs)
- Vajda.statistics.totalXpCount = permanentObject.totalXp
- Vajda.statistics.totalMoneyCount = permanentObject.totalMoney
- }
- }
- }
-
- Vajda.setCookies = function() {
- let expiracyDateTemporary = new Date()
- let hour = expiracyDateTemporary.getHours()
- expiracyDateTemporary.setHours(2,0,0)
- if ( hour > 2 )
- expiracyDateTemporary.setDate(expiracyDateTemporary.getDate() + 1)
-
- const addedJobs = Vajda.addedJobs.map(j => ({
- x: j.x,
- y: j.y,
- id: j.id,
- groupId: j.groupId,
- isSilver: j.isSilver,
- experience: j.experience,
- money: j.money,
- motivation: j.motivation,
- stopMotivation: j.stopMotivation,
- set: j.set
- }))
-
- let temporaryObject = {
- addedJobs,
- travelSet: Vajda.travelSet,
- jobSet: Vajda.jobSet,
- healthSet: Vajda.healthSet,
- currentJob: Vajda.currentJob
- }
- let expiracyDatePernament = new Date()
- expiracyDatePernament.setDate(expiracyDatePernament.getDate() + 360000)
- let pernamentObject = {
- settings: {...Vajda.settings, isOptimized: Manager.isOptimized, isEnabled: Observer.isEnabled, timeOut: Observer.getTimeOut(true)},
- totalJobs: Vajda.statistics.totalJobsCount,
- totalXp: Vajda.statistics.totalXpCount,
- totalMoney: Vajda.statistics.totalMoneyCount
- }
- const jsonTemporary = JSON.stringify(temporaryObject)
- const jsonPernament = JSON.stringify(pernamentObject)
- document.cookie = `vajdatemporary=${jsonTemporary};expires=${expiracyDateTemporary.toGMTString()};`
- document.cookie = `vajdapermanent=${jsonPernament};expires=${expiracyDatePernament.toGMTString()};`
- }
-
-
- Vajda.shouldEquipHealthSet = function(consumable) {
- if ( !consumable.hasCooldown() ) {
- return false
- }
-
- if ( Manager.isOptimized ) {
- return false
- }
-
- return consumable.health > 0 && Vajda.healthSet > -1
- }
-
-
- Vajda.parseConsumableBonuses = function(bonuses) {
- let getBonus = (text,type) => {
- switch(type) {
- case 0:
- text = text.replace(Vajda.searchKeys[Vajda.language].energyText,"")
- break
- case 1:
- text = text.replace(Vajda.searchKeys[Vajda.language].motivationText,"")
- break
- case 2:
- text = text.replace(Vajda.searchKeys[Vajda.language].healthText,"")
- break
- }
- text = text.slice(1)
- text = text.replace("%","")
- return parseInt(text)
- }
- let result = Array(3).fill(0)
- for ( let i = 0 ; i < bonuses.length; i++ ) {
- let type = -1
- if ( bonuses[i].includes(Vajda.searchKeys[Vajda.language].energyText) ) {
- type = 0
- }else if ( bonuses[i].includes(Vajda.searchKeys[Vajda.language].motivationText) ) {
- type = 1
- }else if ( bonuses[i].includes(Vajda.searchKeys[Vajda.language].healthText) ) {
- type = 2
- }
- if ( type !=-1 )
- result[type] = getBonus(bonuses[i],type)
-
- }
- return result
- }
-
- Vajda.findAllConsumables = function() {
- if ( Vajda.searchKeys[Vajda.language] === undefined ) return
- const energyConsumables = Bag.search(Vajda.searchKeys[Vajda.language].energy)
- for ( const consumable of energyConsumables ) {
- Manager.addNewConsumable(consumable)
- }
-
- const motivationConsumables = Bag.search(Vajda.searchKeys[Vajda.language].motivation)
- for ( const consumable of motivationConsumables ) {
- Manager.addNewConsumable(consumable)
- }
-
- const healthConsumables = Bag.search(Vajda.searchKeys[Vajda.language].health)
- for ( const consumable of healthConsumables ) {
- Manager.addNewConsumable(consumable)
- }
-
- const speedConsumables = Bag.search(Vajda.searchKeys[Vajda.language].speedText)
- for ( const consumable of speedConsumables ) {
- if ( consumable.obj.usetype !== 'none' ) {
- Manager.addNewConsumable(consumable)
- }
- }
-
- const luckConsumables = Bag.search(Vajda.searchKeys[Vajda.language].luck)
- for ( const consumable of luckConsumables ) {
- if ( consumable.obj.usetype !== 'none' ) {
- Manager.addNewConsumable(consumable)
- }
- }
-
- const experienceConsumables = Bag.search(Vajda.searchKeys[Vajda.language].experience)
- for ( const consumable of experienceConsumables ) {
- if ( consumable.obj.usetype !== 'none' ) {
- Manager.addNewConsumable(consumable)
- }
- }
-
- const moneyConsumables = Bag.search(Vajda.searchKeys[Vajda.language].money)
- for ( const consumable of moneyConsumables ) {
- if ( consumable.obj.usetype !== 'none' ) {
- Manager.addNewConsumable(consumable)
- }
- }
-
- const dropConsumables = Bag.search(Vajda.searchKeys[Vajda.language].drop)
- for ( const consumable of dropConsumables ) {
- if ( consumable.obj.usetype !== 'none' ) {
- Manager.addNewConsumable(consumable)
- }
- }
-
- Observer.selectedConsumables?.forEach(id => {
- Manager.consumables.find(c => c.id === id).setIsSelected(true)
- })
-
- for ( const type in Observer.buffs ) {
- Manager.selectedBuffs_[type] = Manager.buffs_.find(b => b.id === Observer.buffs[type]) || null
- }
- Observer.selectedConsumables = null
- Observer.buffs = null
- }
-
- Vajda.filterConsumables = function(energy, motivation, health, hideBuffs) {
- const result = hideBuffs ? [] : [...Manager.buffs]
-
- for ( const consumable of Manager.consumables ) {
- if ( energy && consumable.energy === 0 ) {
- continue
- }
-
- if ( motivation && consumable.motivation === 0 ) {
- continue
- }
-
- if ( health && consumable.health === 0 ) {
- continue
- }
- result.push(consumable)
- }
-
- return result
- }
-
- Vajda.changeConsumableSelection = function(id, isSelected) {
- Manager.consumables.find(c => c.id === id)?.setIsSelected(isSelected)
- }
-
- Vajda.changeSelectionAllConsumables = function(selected) {
- for ( const consumable of Manager.consumables ) {
- consumable.setIsSelected(selected)
- }
- }
-
- Vajda.loadJobs = function() {
- if ( !Vajda.jobsLoaded ) {
- new UserMessage("Loading...", UserMessage.TYPE_HINT).show()
- let index = 0
- let currentLength = 0
- let maxLength = 299
- Ajax.get('map', 'get_minimap', {}, function(r) {
- var tiles = []
- var jobs = []
-
- for ( let townNumber in r.towns ) {
- if ( r.towns[townNumber].town_id === Character.homeTown.town_id ) {
- Vajda.homeTown = r.towns[townNumber]
- break
- }
- }
-
-
- for ( let jobGroup in r.job_groups ) {
- const groupId = parseInt(jobGroup)
- let group = r.job_groups[jobGroup]
- let jobsGroup = JobList.getJobsByGroupId(groupId)
-
- for ( let tilecoord = 0; tilecoord < group.length; tilecoord++ ) {
- let xCoord = Math.floor(group[tilecoord][0]/GameMap.tileSize)
- let yCoord = Math.floor(group[tilecoord][1]/GameMap.tileSize)
- if ( currentLength == 0 ) {
- tiles[index] = []
- }
-
- tiles[index].push([xCoord,yCoord])
- currentLength++
-
- if ( currentLength === maxLength ) {
- currentLength = 0
- index++
- }
-
- for ( let i = 0; i < jobsGroup.length; i++ ) {
- jobs.push(new Job(group[tilecoord][0],group[tilecoord][1],jobsGroup[i].id, groupId))
- }
- }
- }
- let toLoad = tiles.length
- let loaded = 0
- for ( let blocks = 0; blocks < tiles.length; blocks++ ) {
- GameMap.Data.Loader.load(tiles[blocks], function() {
- loaded++
- if ( loaded === toLoad ) {
- Vajda.jobsLoaded = true
- Vajda.allJobs = jobs
- Vajda.findAllConsumables()
- Vajda.createWindow()
- }
- })
- }
- })
- } else {
- Vajda.findAllConsumables()
- Vajda.createWindow()
- }
- }
-
- Vajda.loadJobData = function(callback) {
- Ajax.get('work','index', {}, function(r) {
- if( r.error ) {
- console.log(r.error)
- return
- }
- JobsModel.initJobs(r.jobs)
- callback()
- })
- }
-
- Vajda.getJobSet = function(x, y, id) {
- const job = Vajda.findAddedJob(x, y, id)
- if ( job !== null )
- return job.set
- }
-
- Vajda.setJobSet = function(x,y,id,set) {
- const job = Vajda.findAddedJob(x, y, id)
- if ( job !== null)
- return job.setSet(set)
- }
-
- Vajda.findAddedJob = function(x, y, id) {
- for ( const job of Vajda.addedJobs ) {
- if ( job.x === x && job.y === y && job.id === id ) {
- return job
- }
- }
- return null
- }
-
- Vajda.loadSets = async function(callback) {
- Ajax.remoteCallMode('inventory', 'show_equip', {}, function(r) {
- Vajda.sets = r.data
- if ( callback !== undefined )
- callback()
- })
- }
-
- Vajda.loadJobMotivation = function(index, callback) {
- const job = Vajda.addedJobs.at(index)
- Ajax.get('job', 'job', {jobId: job.id, x: job.x, y: job.y}, function(r) {
- if ( callback !== undefined )
- callback(r.motivation*100)
- })
- }
-
- Vajda.loadLanguage = function() {
- Ajax.remoteCall("settings", "settings", {}, function(resp) {
- Vajda.language = resp.lang.account.key
- })
- }
-
- Vajda.getConsumableIcon = function(src) {
- return `<div><img src='${src}'></div>`
- }
-
- Vajda.getItemImage = function(id) {
- return ItemManager.get(id).wear_image
- }
-
- Vajda.createComboxJobSets = function(x, y, id) {
- let combobox = new west.gui.Combobox()
- Vajda.addComboboxItems(combobox)
- combobox = combobox.select(Vajda.getJobSet(x, y, id))
- combobox.setWidth(60)
- combobox.addListener(function(value) {
- Vajda.setJobSet(x, y, id, value)
- Vajda.selectTab("chosenJobs")
- });
- return combobox.getMainDiv()
- }
-
- Vajda.addComboboxItems = function(combobox) {
- combobox.addItem(-1, "None")
- for ( let i = 0 ; i < Vajda.sets.length; i++) {
- combobox.addItem(i.toString(), Vajda.sets[i].name)
- }
- }
-
- Vajda.updateJobDistances = function() {
- for ( let i = 0; i < Vajda.allJobs.length; i++ ) {
- Vajda.allJobs[i].calculateDistance()
- }
- }
-
- Vajda.findJobData = function(job) {
- for ( let i = 0 ;i < JobsModel.Jobs.length; i++ ) {
- if ( JobsModel.Jobs[i].id === job.id ) {
- return JobsModel.Jobs[i]
- }
- }
- }
-
- Vajda.findJob = function(x, y, id) {
- for ( let i = 0; i < Vajda.allJobs.length; i++ ) {
- if ( Vajda.allJobs[i].id === id && Vajda.allJobs[i].x === x && Vajda.allJobs[i].y === y ) {
- return Vajda.allJobs[i]
- }
- }
- }
-
- Vajda.addJob = function(x, y, id) {
- if ( !Vajda.checkIfJobAdded(id) ) {
- Vajda.addedJobs.push(Vajda.findJob(x, y, id))
- }
- }
-
- Vajda.removeJob = function(x, y, id) {
- for ( let i = 0; i < Vajda.addedJobs.length; i++ ) {
- if ( Vajda.addedJobs[i].id === id && Vajda.addedJobs[i].x === x && Vajda.addedJobs[i].y === y) {
- Vajda.addedJobs.splice(i,1)
- Vajda.consolidePosition(i)
- break
- }
- }
- }
-
- Vajda.parseJobData = function(jobs) {
- for ( let job = 0; job < jobs.length; job++ ) {
- let currentJob = jobs[job]
- let data = Vajda.findJobData(currentJob)
- let xp = data.basis.short.experience
- let money = data.basis.short.money
- currentJob.setMotivation(data.jobmotivation*100)
- if ( currentJob.isSilver ) {
- xp = Math.ceil(1.5*xp)
- money = Math.ceil(1.5*money)
- }
- currentJob.setExperience(xp)
- currentJob.setMoney(money)
- }
- }
-
- Vajda.getJobName = function(id) {
- return JobList.getJobById(id).name
- }
-
- Vajda.getJobIcon = function(isSilver, id, x, y) {
- return `
- <div class="job" style="left: 0; top: 0; position: relative;">
- <div onclick="JobWindow.open(${id}, ${x}, ${y})" class="featured ${isSilver && 'silver'}"></div>
- <div class='centermap' onclick='GameMap.center(${x}, ${y})' style="position: absolute; background-image: url('../images/map/icons/instantwork.png'); width: 20px; height: 20px; top: 0; right: 3px; cursor: pointer"></div>
- <img src="../images/jobs/${JobList.getJobById(id).shortname}.png" class="job_icon" alt='job_image'>
- </div>
- `
- }
-
- Vajda.checkIfJobAdded = function(id) {
- for ( const job of Vajda.addedJobs ) {
- if ( job.id === id ) {
- return true
- }
- }
-
- return false
- }
-
- Vajda.isJobSilver = function(x, y, id) {
- const key = `${x}-${y}`
- const jobData = GameMap.JobHandler.Featured[key]
- if ( jobData === undefined || jobData[id] === undefined ) {
- return false
- } else {
- return jobData[id].silver
- }
- }
-
- Vajda.compareUniqueJobs = function(job, jobs){
- for ( let i = 0 ; i < jobs.length; i++ ) {
- if ( jobs[i].id === job.id ) {
- if ( job.isSilver && !jobs[i].isSilver || (job.isSilver === jobs[i].isSilver && job.distance < jobs[i].distance) ) {
- const j = jobs.at(i)
- if ( !Vajda.isJobSilver(j.x, j.y, j.id) )
- jobs.splice(i,1)
- jobs.push(job)
- }
- return
- }
- }
- jobs.push(job)
- }
-
- Vajda.getAllUniqueJobs = function() {
- Vajda.updateJobDistances()
- let jobs = []
- for ( let i = 0 ; i < Vajda.allJobs.length; i++ ) {
- const currentJob = Vajda.allJobs.at(i)
- if ( Vajda.jobFilter.filterJob !== "" ) {
- if ( !Vajda.getJobName(currentJob.id).toLowerCase().includes(Vajda.jobFilter.filterJob)) {
- continue
- }
- }
-
- if ( Vajda.checkIfJobAdded(currentJob.id) ) {
- continue
- }
-
- let isSilver = Vajda.isJobSilver(currentJob.x, currentJob.y, currentJob.id)
- currentJob.isSilver = isSilver
- currentJob.calculateDistance()
-
- if ( isSilver && Vajda.jobFilter.filterNoSilver ) {
- continue
- }
-
- if ( !isSilver && Vajda.jobFilter.filterOnlySilver ) {
- continue
- }
-
- if ( Vajda.jobFilter.filterCenterJobs && currentJob.id < 131 ) {
- continue
- }
-
- Vajda.compareUniqueJobs(currentJob, jobs)
- }
-
- Vajda.parseJobData(jobs)
-
- let experienceSort = function(a, b) {
- if ( a === null && b === null ) {
- return 0
- }
-
- if ( a === null && b !== null ) {
- return 1
- }
-
- if ( a !== null && b === null ) {
- return -1
- }
-
- let a1 = a.experience
- let b1 = b.experience
- return (a1 > b1) ? -1 :(a1 < b1) ? 1 :0
- }
-
- let reverseExperienceSort = function(a, b) {
- if ( a === null && b === null ) {
- return 0
- }
- if ( a === null && b !== null ) {
- return -1
- }
-
- if ( a !== null && b === null ) {
- return 1
- }
-
- let a1 = a.experience
- let b1 = b.experience
- return (a1 > b1) ? 1 :(a1 < b1) ? -1 :0
- }
-
- let distanceSort = function(a, b) {
- if ( a === null && b === null ) {
- return 0
- }
-
- if ( a === null && b !== null ) {
- return 1
- }
-
- if ( a !== null && b === null ) {
- return -1
- }
-
- let a1 = a.distance
- let b1 = b.distance
- return (a1 > b1) ? -1 :(a1 < b1) ? 1 :0
- }
-
- let reverseDistanceSort = function(a, b) {
- if ( a === null && b === null ) {
- return 0
- }
-
- if ( a === null && b !== null ) {
- return -1
- }
-
- if(a !== null && b === null ) {
- return 1
- }
-
- let a1 = a.distance
- let b1 = b.distance
- return (a1 > b1) ? 1 :(a1 < b1) ? -1 :0
- }
-
- if ( Vajda.sortJobTableXp === 1 ) {
- jobs.sort(experienceSort)
- }
-
- if ( Vajda.sortJobTableXp === -1 ) {
- jobs.sort(reverseExperienceSort)
- }
-
- if ( Vajda.sortJobTableDistance === 1 ) {
- jobs.sort(distanceSort)
- }
-
- if ( Vajda.sortJobTableDistance === -1 ) {
- jobs.sort(reverseDistanceSort)
- }
-
- return jobs
- }
-
- Vajda.parseStopMotivation = function() {
- for ( let i = 0; i < Vajda.addedJobs.length; i++ ) {
- let stopMotivation = $(".vajda-window #x-" + Vajda.addedJobs[i].x + "y-" + Vajda.addedJobs[i].y + "id-" + Vajda.addedJobs[i].id).prop("value")
- if ( Vajda.isNumber(stopMotivation) ) {
- Vajda.addedJobs[i].setStopMotivation(parseInt(stopMotivation))
- } else {
- return false
- }
- }
- return true
- }
-
- Vajda.setSetForAllJobs = function() {
- for ( let i = 0; i < Vajda.addedJobs.length; i++ ) {
- Vajda.addedJobs[i].setSet(Vajda.jobSet)
- }
- }
-
- Vajda.consolidePosition = function(removeIndex) {
- if ( removeIndex <= Vajda.currentJob.job && Vajda.currentJob.job > 0 ) {
- Vajda.currentJob.job--
- }
- if ( Vajda.addedJobs.length === 1 ) {
- Vajda.currentJob.direction = true
- }
- }
-
- Vajda.createDistanceMatrix = function() {
- const matrix = new Array(Vajda.addedJobs.length)
-
- for ( let i = 0; i < matrix.length; i++ ) {
- matrix[i] = Vajda.addedJobs[i].calculateJobDistances()
- }
-
- return matrix
- }
-
- Vajda.countSetBits = function(n) {
- let count = 0
- while (n) {
- n &= n - 1
- count++
- }
- return count
- }
-
- Vajda.heldKarpSymmetric = function(distances, startJob) {
- const n = distances.length
- const memo = Array(1 << n).fill().map(() => Array(n).fill({ cost: Infinity, path: [] }))
- memo[1 << startJob][startJob] = { cost: 0, path: [startJob] }
-
- for ( let subsetSize = 2; subsetSize <= n; subsetSize++ ) {
- for ( let subset = 0; subset < (1 << n); subset++ ) {
- if ( Vajda.countSetBits(subset) === subsetSize && (subset & (1 << startJob)) ) {
- for ( let end = 0; end < n; end++ ) {
- if ( (subset & (1 << end)) !== 0 ) {
- for ( let prevEnd = 0; prevEnd < n; prevEnd++ ) {
- if ( prevEnd !== end && (subset & (1 << prevEnd)) !== 0 ) {
- const newCost = memo[subset ^ (1 << end)][prevEnd].cost + distances[prevEnd][end]
- if (newCost < memo[subset][end].cost) {
- memo[subset][end] = { cost: newCost, path: memo[subset ^ (1 << end)][prevEnd].path.concat([end]) }
- }
- }
- }
- }
- }
- }
- }
- }
-
- let minCost = Infinity
- let minPath = []
- for ( let end = 0; end < n; end++ ) {
- if ( end !== startJob && memo[(1 << n) - 1][end].cost < minCost ) {
- minCost = memo[(1 << n) - 1][end].cost
- minPath = memo[(1 << n) - 1][end].path
- }
- }
-
- return { cost: minCost, path: minPath }
- }
-
-
- Vajda.setEntryPoint = function(route) {
- const firstJob = route.at(0)
- const lastJob = route.at(-1)
-
- if ( firstJob.calculateDistance() > lastJob.calculateDistance() )
- route.reverse()
-
- //i could in theory make vajda start with the job nearest to current character position but cba
- }
-
- Vajda.getOptimalRoute = function(distanceMatrix) {
- const jobsCount = distanceMatrix.length
-
- if ( jobsCount === 1 )
- return {
- cost: 0,
- path: [0]
- }
-
- const routes = []
- for ( let startJob = 0; startJob < jobsCount; startJob++ ) {
- const { cost, path } = Vajda.heldKarpSymmetric(distanceMatrix, startJob)
- routes.push({ cost, path })
- }
-
- return routes.reduce(function(prev, curr) {
- return prev.cost < curr.cost ? prev : curr
- })
- }
-
- Vajda.createRoute = function() {
- Vajda.currentJob = {
- job: 0,
- direction: true
- }
-
- const distanceMatrix = Vajda.createDistanceMatrix()
- const optimalRoute = Vajda.getOptimalRoute(distanceMatrix)
-
- const addedJobsOrder = []
- for ( const index of optimalRoute.path ) {
- addedJobsOrder.push(Vajda.addedJobs.at(index))
- }
-
- Vajda.setEntryPoint(addedJobsOrder)
-
- Vajda.addedJobs = addedJobsOrder
- Vajda.selectTab("chosenJobs")
- }
-
- Vajda.createSetGui = function() {
- if ( Vajda.sets.length === 0 ) {
- return $(`<span style='font-size: 20px'>No sets available</span>`)
- }
- let htmlSkel = $(`
- <div id='vajda_sets_window' style='display: block; position: relative; width: 650px; height:430px'>
- <div id='vajda_sets_left' style='display: block; position: absolute; width: 250px; height: 430px; top:0px; left:0px'></div>
- <div id='vajda_sets_right' style='display: block; position: absolute; width:300px; height: 410px; top: 0px; left: 325px'></div>
- </div>`)
- let combobox = new west.gui.Combobox("combobox_sets")
- Vajda.addComboboxItems(combobox)
- combobox = combobox.select(Vajda.selectedSet)
- combobox.addListener(function(value) {
- Vajda.selectedSet = value
- Vajda.selectTab("sets")
- })
- let buttonSelectTravelSet = new west.gui.Button("Select travel set", function() {
- Vajda.travelSet = Vajda.selectedSet
- Vajda.selectTab("sets")
- })
- let buttonSelectJobSet = new west.gui.Button("Select job set", function() {
- Vajda.jobSet = Vajda.selectedSet
- Vajda.setSetForAllJobs()
- Vajda.selectTab("sets")
- })
- let buttonSelectHealthSet = new west.gui.Button("Select health set", function() {
- Vajda.healthSet = Vajda.selectedSet
- Vajda.selectTab("sets")
- })
- let buttonSelectRegenSet = new west.gui.Button("Select regeneration set", function() {
- Vajda.regenerationSet = Vajda.selectedSet
- Vajda.selectTab("sets")
- })
- let travelSetText = "None"
-
- if ( Vajda.travelSet != -1 ) {
- travelSetText = Vajda.sets[Vajda.travelSet].name
- }
-
- let jobSetText = "None"
- if ( Vajda.jobSet != -1 ) {
- jobSetText = Vajda.sets[Vajda.jobSet].name
- }
-
- let healthSetText = "None"
- if ( Vajda.healthSet != -1 ) {
- healthSetText = Vajda.sets[Vajda.healthSet].name
- }
-
- let regenSetText = "None"
- if ( Vajda.regenerationSet != -1 ) {
- regenSetText = Vajda.sets[Vajda.regenerationSet].name
- }
-
- const left = $("<div></div>")
- .append(
- new west.gui.Groupframe()
- .appendToContentPane($("<span>Sets</span><br><br>"))
- .appendToContentPane(combobox.getMainDiv())
- .appendToContentPane($("<br><br><span>Travel set:"+ travelSetText +"</span><br><br>"))
- .appendToContentPane(buttonSelectTravelSet.getMainDiv())
- .appendToContentPane($("<br><br><span>Job set:"+ jobSetText +"</span><br><br>"))
- .appendToContentPane(buttonSelectJobSet.getMainDiv())
- .appendToContentPane($("<br><br><span>Health set:"+ healthSetText +"</span><br><br>"))
- .appendToContentPane(buttonSelectHealthSet.getMainDiv())
- .getMainDiv()
- )
- const right = $("<div style=\'display:block; position:relative; width:300px; height:410px'\></div>")
- //head div
- right.append("<div class=\'wear_head wear_slot'\ style=\'display:block; position:absolute; left:30px; top:1px; width:93px; height:94px; background:url(https://westzz.innogamescdn.com/images/window/wear/bg_sprite.png) 0 0 no-repeat; background-position: -95px 0'\></div>")
- //chest div
- right.append("<div class=\'wear_body wear_slot'\ style=\'display:block; position:absolute; left:30px; top:106px; width:95px; height:138px; background:url(https://westzz.innogamescdn.com/images/window/wear/bg_sprite.png) 0 0 no-repeat; background-position:0 0'\></div>")
- //pants div
- right.append("<div class=\'wear_pants wear_slot'\ style=\'display:block; position:absolute; left:30px; top:258px; width:93px; height:138px; background:url(https://westzz.innogamescdn.com/images/window/wear/bg_sprite.png) 0 0 no-repeat; background-position:0 0'\></div>")
- //neck div
- right.append("<div class=\'wear_neck wear_slot'\ style=\'display:block; position:absolute; left:-47px; top:1px; width:74px; height:74px; background:url(https://westzz.innogamescdn.com/images/window/wear/bg_sprite.png) 0 0 no-repeat; background-position:-189px 0'\></div>")
- //right arm div
- right.append("<div class=\'wear_right_arm wear_slot'\ style=\'display:block; position:absolute; left:-64px; top:79px; width:95px; height:138px; background:url(https://westzz.innogamescdn.com/images/window/wear/bg_sprite.png) 0 0 no-repeat; background-position:0 0'\></div>")
- //animal div
- right.append("<div class=\'wear_animal wear_slot'\ style=\'display:block; position:absolute; left:-64px; top:223px; width:93px; height:94px; background:url(https://westzz.innogamescdn.com/images/window/wear/bg_sprite.png) 0 0 no-repeat; background-position:-95px 0'\></div>")
- //yield div
- right.append("<div class=\'wear_yield wear_slot'\ style=\'display:block; position:absolute; left:-47px; top:321px; width:74px; height:74px; background:url(https://westzz.innogamescdn.com/images/window/wear/bg_sprite.png) 0 0 no-repeat; background-position:-189px 0'\></div>")
- //left arm div
- right.append("<div class=\'wear_left_arm wear_slot'\ style=\'display:block; position:absolute; left:127px; top:52px; width:95px; height:138px; background:url(https://westzz.innogamescdn.com/images/window/wear/bg_sprite.png) 0 0 no-repeat; background-position:0 0'\></div>")
- //belt div
- right.append("<div class=\'wear_belt wear_slot'\ style=\'display:block; position:absolute; left:127px; top:200px; width:93px; height:94px; background:url(https://westzz.innogamescdn.com/images/window/wear/bg_sprite.png) 0 0 no-repeat; background-position:-95px 0'\></div>")
- //boots div
- right.append("<div class=\'wear_foot wear_slot'\ style=\'display:block; position:absolute; left:127px; top:302px; width:93px; height:94px; background:url(https://westzz.innogamescdn.com/images/window/wear/bg_sprite.png) 0 0 no-repeat; background-position:-95px 0'\></div>")
- let keys = ["head","body","pants","neck","right_arm","animal","yield","left_arm","belt","foot"]
- if ( Vajda.selectedSet !== -1 )
- Vajda.insertSetImages(right,keys)
- $("#vajda_sets_left",htmlSkel).append(left)
- $("#vajda_sets_right",htmlSkel).append(right)
- return htmlSkel
- }
-
- Vajda.getImageSkel = function() {
- return $("<img src=\''\>")
- }
-
- Vajda.insertSetImages = function(html,keys) {
- for ( let i = 0; i < keys.length; i++ ) {
- if ( Vajda.sets[Vajda.selectedSet][keys[i]] !== null ) {
- $(".wear_"+keys[i], html).append(Vajda.getImageSkel().attr("src", Vajda.getItemImage(Vajda.sets[Vajda.selectedSet][keys[i]])))
- }
- }
- return html
- }
-
- Vajda.addEventsHeader = function() {
- $(".vajda-window .jobXp").click(function() {
- if ( Vajda.sortJobTableXp === 0 ) {
- Vajda.sortJobTableXp = 1
- } else {
- ( Vajda.sortJobTableXp === 1 ) ? Vajda.sortJobTableXp = -1 : Vajda.sortJobTableXp = 1
- }
- Vajda.sortJobTableDistance = 0
- Vajda.selectTab("jobs")
- })
- $(".vajda-window .jobDistance").click(function() {
- if ( Vajda.sortJobTableDistance === 0 ) {
- Vajda.sortJobTableDistance = 1
- } else {
- ( Vajda.sortJobTableDistance === 1 ) ? Vajda.sortJobTableDistance = -1 : Vajda.sortJobTableDistance = 1
- }
- Vajda.sortJobTableXp = 0
- Vajda.selectTab("jobs")
- })
- }
-
- Vajda.isInHomeTown = function() {
- const homeTown = Character.homeTown
- return GameMap.calcWayTime(Character.position,{x: homeTown.x, y: homeTown.y}) == 0
- }
-
- Vajda.addDeposit = async function(townId) {
- const amount = Character.money
- await Ajax.remoteCall("building_bank", "deposit", {
- town_id: townId,
- amount: amount
- }, function(data) {
- if (data.error == false) {
- BankWindow.Balance.Mupdate(data)
- Character.setDeposit(data.deposit)
- Character.setMoney(data.own_money)
- //new UserMessage(s(sextext('Vložil si $ %1 a zaplatil si poplatok $ %2', 'Vložila si $ %1 a zaplatila si poplatok $ %2', Character.charSex), amount, data.fee),UserMessage.TYPE_SUCCESS).show()
- } else
- new UserMessage(data.msg,UserMessage.TYPE_ERROR).show()
- }, BankWindow)
- }
-
-
- Vajda.goDepositMoney = async function() {
- const townId = Character.homeTown.town_id
- if ( !townId ) return
-
- await Vajda.equipSet(Vajda.travelSet)
- TaskQueue.add(new TaskWalk(townId, 'town'))
-
- while(true) {
- if ( Vajda.isInHomeTown() ) {
- break
- }
-
- if( !Vajda.isRunning ) {
- break
- }
-
- await sleep(1000)
- }
-
- await Vajda.addDeposit(townId)
- $('.tw2gui_dialog_framefix').remove()
- }
-
- Vajda.updateJobsMotivationOnRefill = function(val) {
- return Vajda.addedJobs.map(job => job.setMotivation(p => p + val).motivation - job.stopMotivation)
- }
-
-
- Vajda.checkMotivation = async function(index, result, callback) {
- let check = function(index, result) {
- Vajda.loadJobMotivation(index, function(motivation) {
- Vajda.addedJobs.at(index).setMotivation(motivation)
- result.push(motivation)
- if ( index + 1 < Vajda.addedJobs.length ) {
- check(++index, result)
- } else if( index + 1 === Vajda.addedJobs.length ) {
- callback(result)
- return
- }
- })
- }
- check(index, result)
- }
-
- Vajda.isMotivationAbove = function(result) {
- for ( let i = 0; i < result.length; i++ ) {
- if ( result.at(i) > Vajda.addedJobs.at(i).stopMotivation ) {
- return true
- }
- }
- return false
- }
-
- Vajda.isStopMotivationZero = function() {
- for ( let i = 0; i < Vajda.addedJobs.length; i++ ) {
- if( Vajda.addedJobs[i].stopMotivation === 0 ) {
- return true
- }
- }
- return false
- }
-
- Vajda.isHealthBelowLimit = function() {
- if ( Vajda.settings.healthStop >= ((Character.health/Character.maxHealth) * 100) ) {
- return true
- }
- return false
- }
-
- Vajda.changeJob = function() {
- Vajda.currentJob.direction ? Vajda.currentJob.job++ : Vajda.currentJob.job--;
- if ( Vajda.currentJob.job === Vajda.addedJobs.length ) {
- Vajda.currentJob.job--
- Vajda.currentJob.direction = false
- } else if ( Vajda.currentJob.job < 0 ) {
- Vajda.currentJob.job++
- Vajda.currentJob.direction = true
- }
- Vajda.setCookies()
- Vajda.run()
- }
-
- Vajda.searchBest = function(skills, jobId, onlyWearable = true) {
- if (!Bag.loaded) {
- EventHandler.listen('inventory_loaded', function() {
- Vajda.searchBest(skills, jobId, onlyWearable)
- return EventHandler.ONE_TIME_EVENT
- })
- return
- }
- let set = west.item.Calculator.getBestSet(skills, jobId), items = set && set.getItems() || [], invItems = Bag.getItemsByItemIds(items), result = [], i, invItem, wearItem
- for (i = 0; i < invItems.length; i++) {
- invItem = invItems[i]
- wearItem = Wear.get(invItem.getType())
- if (!wearItem || (wearItem && (wearItem.getItemBaseId() !== invItem.getItemBaseId() || wearItem.getItemLevel() < invItem.getItemLevel()))) {
- result.push(invItem)
- }
- }
- return result.map(item => item.obj.getId())
- }
-
- Vajda.getBestGear = function(jobid) {
- let modelId = function(jobid) {
- for ( let i = 0; i < JobsModel.Jobs.length; i++ ) {
- if ( JobsModel.Jobs[i].id === jobid )
- return i
- }
- return -1
- }
- const result = west.item.Calculator.getBestSet(JobsModel.Jobs[modelId(jobid)].get('skills'), jobid)
- const bestItems = result && result.getItems()
- return bestItems
- }
-
- Vajda.isWearing = function(itemId) {
- if ( Wear.wear[ItemManager.get(itemId).type] === undefined) return false
- return Wear.wear[ItemManager.get(itemId).type].obj.item_id == itemId
- }
-
- Vajda.isGearEquiped = async function(items) {
- for ( const itemId of items ) {
- if ( !Vajda.isWearing(itemId) ) {
- return false
- }
- }
-
- return true
- }
-
- Vajda.equipBestGear = async function(job) {
- const bestGear = job.getBestEquipment()
-
- for ( const itemId of bestGear ) {
- Wear.carry(Bag.getItemByItemId(itemId))
- }
-
- while (true) {
- const isFinished = await Vajda.isGearEquiped(bestGear)
- if ( isFinished ) break
- await sleep(50)
- }
- return Promise.resolve(true)
- }
-
- Vajda.getSetItemArray = function(set) {
- var items = []
- if ( set.head !== null )
- items.push(set.head)
- if ( set.neck !== null )
- items.push(set.neck)
- if ( set.body !== null )
- items.push(set.body)
- if ( set.right_arm !== null )
- items.push(set.right_arm)
- if ( set.left_arm !== null )
- items.push(set.left_arm)
- if ( set.belt !== null )
- items.push(set.belt)
- if ( set.foot !== null )
- items.push(set.foot)
- if ( set.animal !== null )
- items.push(set.animal)
- if ( set.yield !== null )
- items.push(set.yield)
- if ( set.pants !== null )
- items.push(set.pants)
- return items
- }
-
- Vajda.equipSet = async function(set) {
- if ( set === -1 ) return true
- EquipManager.switchEquip(Vajda.sets[set].equip_manager_id)
- while ( true ) {
- let isFinished = await Vajda.isGearEquiped(Vajda.getSetItemArray(Vajda.sets[set]))
- if ( isFinished ) break
- await sleep(50)
- }
- return Promise.resolve(true)
- }
-
- Vajda.cancelJobs = function() {
- if ( TaskQueue.queue.length > 0 )
- TaskQueue.cancelAll()
- }
-
-
- //https://prnt.sc/KAgbLNqB4zK6
- Vajda.runJob = async function(jobIndex, jobCount) {
- Vajda.statistics.sessionJobsCount += jobCount
- Vajda.statistics.totalJobsCount += jobCount
- const oldXp = Character.experience
- const oldMoney = Character.money
- const job = Vajda.addedJobs.at(jobIndex)
- await Vajda.equipBestGear(job)
- for ( let i = 0; i < jobCount; i++ ) {
- JobWindow.startJob(job.id, job.x, job.y, 15)
- }
- Observer.start()
- await sleep(Vajda.settings.setWearDelay * 1000)
- Vajda.equipSet(job.set)
- Manager.useBuff('character')
- while (true) {
- if ( TaskQueue.queue.length === 0 ) {
- Vajda.updateStatistics(oldXp, oldMoney)
- Vajda.setCookies()
- Vajda.prepareJobRun(jobIndex)
- return
- }
- if ( !Vajda.isRunning || Vajda.isHealthBelowLimit() ) {
- break
- }
- await sleep(1000)
- }
- Vajda.statistics.sessionJobsCount -= TaskQueue.queue.length
- Vajda.statistics.totalJobsCount -= TaskQueue.queue.length
- Vajda.updateStatistics(oldXp, oldMoney)
- Vajda.setCookies()
- Vajda.cancelJobs()
-
- if ( Vajda.isRunning && Vajda.isHealthBelowLimit() ) {
- await sleep(2000)
- Vajda.run()
-
- }
- }
-
- Vajda.walkToJob = async function(index) {
- const job = Vajda.addedJobs.at(index)
- const jobGroup = JobList.getJobsByGroupId(job.groupId)
-
- const jobToWalkTo = jobGroup.map(j =>
- j.id
- ).map( id => {
- const j = JobsModel.getById(id)
-
- return {
- id: id,
- workpoints: j.workpoints, //required LP
- jobpoints: j.jobpoints //character has LP
- }
- }).reduce((prev, curr) => {
- return prev.workpoints < curr.workpoints ? prev : curr
- })
-
- await Manager.useBuff('travel')
-
- if ( Vajda.isAllowedToDepositMoney() ) {
- Observer.start()
- await Vajda.goDepositMoney()
- }
-
- JobWindow.startJob(jobToWalkTo.id, job.x, job.y, 15)
- Observer.start()
-
- while (true) {
- if ( GameMap.calcWayTime(Character.position, {x: job.x, y: job.y} ) === 0 ) {
- break
- }
-
- if ( !Vajda.isRunning ) {
- break
- }
- await sleep(1000)
- }
- Vajda.cancelJobs()
- if ( Vajda.isRunning )
- Vajda.prepareJobRun(index)
- }
-
- Vajda.prepareJobRun = async function(index) {
- const job = Vajda.addedJobs.at(index)
- setTimeout(function() {
- Vajda.loadJobMotivation(index, async function(motivation) {
- if ( Character.energy === 0 || Vajda.isHealthBelowLimit() ) {
- Vajda.run()
- } else if ( motivation <= job.stopMotivation && job.stopMotivation > 0 ) {
- Vajda.checkMotivation(0, [], function(result) {
- if ( Vajda.isMotivationAbove(result) ) {
- Vajda.changeJob()
- } else {
- Vajda.run()
- }
- })
- } else if ( GameMap.calcWayTime(Character.position,{x: job.x, y: job.y}) === 0 ) {
- let maxJobs = Premium.hasBonus('automation') ? 9 : 4
- let numberOfJobs
- if (job.stopMotivation !== 0 ) {
- numberOfJobs = Math.min(Math.min(motivation - job.stopMotivation, Character.energy), maxJobs)
- } else {
- numberOfJobs = Math.min(Character.energy, maxJobs)
- }
- Vajda.runJob(index, Math.floor(numberOfJobs))
- if ( Manager.isOptimized )
- Manager.checkSchedule(numberOfJobs)
- } else {
- await Vajda.equipSet(Vajda.travelSet)
- Vajda.walkToJob(index)
- }
- })
- }, Vajda.RNG(Vajda.settings.jobDelayMin, Vajda.settings.jobDelayMax) * 1000)
- }
-
- Vajda.canAddMissing = function(result) {
- if ( !Vajda.settings.addMotivation && Vajda.jobsBelowMotivation(result) && !Vajda.isStopMotivationZero() ) {
- alert("Can't continue because of motivation")
- return false
- }
-
- if ( !Vajda.settings.addEnergy && Character.energy === 0 ) {
- alert("Can't continue because of energy")
- return false
- }
-
- if ( !Vajda.settings.addHealth && Vajda.isHealthBelowLimit() ) {
- alert("Can't continue because of health")
- return false
- }
- return true
- }
-
- Vajda.finishRun = function() {
- Vajda.currentState = 0
- Vajda.isRunning = false
- Vajda.selectTab("chosenJobs")
- alert("Finished")
- }
-
- Vajda.jobsBelowMotivation = function(result) {
- let count = 0
- for ( let i = 0; i < result.length; i++ ) {
- if ( result[i] <= Vajda.addedJobs[i].stopMotivation ) {
- count++
- }
- }
- return count
- }
-
-
-
- Vajda.averageMissingMotivation = function(result) {
- let motivation = 0
- for ( let i = 0; i < result.length; i++ ) {
- motivation += 100-result[i]
- }
- return motivation/result.length
- }
-
-
- Vajda.fillUp = async function(result) {
- const energyMissing = 100 - (Character.energy/Character.maxEnergy) * 100
- const motivationMissing = Vajda.jobsBelowMotivation(result)
- const averageMotivationMissing = Vajda.averageMissingMotivation(result)
-
- const consumableToUse = Manager.findProperConsumable(motivationMissing, energyMissing, averageMotivationMissing)
-
-
- if ( consumableToUse === null ) return false
-
- await Manager.useConsumableOrWaitForCooldown(consumableToUse, true)
-
- if ( Manager.isOptimized && consumableToUse.isCakeDecoration() ) {
- const updatedMotivation = Vajda.updateJobsMotivationOnRefill(consumableToUse.motivation)
- await Manager.createSchedule(updatedMotivation)
- }
-
- return true
- }
-
- Vajda.updateStatistics = function(oldXp, oldMoney) {
- const xpDiff = Character.experience - oldXp
- const moneyDiff = Character.money - oldMoney
-
- Vajda.statistics.sessionXpCount += xpDiff
- Vajda.statistics.totalXpCount += xpDiff
-
- if ( moneyDiff > 0 ) { //spending money while vajda is running would make this a bit funky
- Vajda.statistics.sessionMoneyCount += moneyDiff
- Vajda.statistics.totalMoneyCount += moneyDiff
- }
- }
-
- Vajda.run = async function() {
- Vajda.checkMotivation(0, [], async function(result) {
- if ( ( Vajda.isMotivationAbove(result) || Vajda.isStopMotivationZero()) && Character.energy > 0 && !Vajda.isHealthBelowLimit() ) {
- Vajda.currentState = 1
- Vajda.selectTab("chosenJobs")
- Vajda.prepareJobRun(Vajda.currentJob.job)
- } else {
- if ( !Vajda.canAddMissing(result) ) {
- Vajda.finishRun()
- } else {
- let answer = await Vajda.fillUp(result)
- if ( !answer ) {
- Vajda.finishRun()
- }
- }
- }
- })
- }
-
- Vajda.formatNumber = function(number) {
- if ( typeof number === 'number' ) {
- number = String(number)
- }
-
- const numberString = number.replace(/[ ,]/g, '')
-
- let formattedNumber = ''
- for ( let i = 0; i < numberString. length; i++ ) {
- if ( i > 0 && i % 3 === 0 ) {
- formattedNumber = ' ' + formattedNumber
- }
-
- formattedNumber = numberString[numberString.length - 1 - i] + formattedNumber
- }
-
- return formattedNumber
- }
-
- Vajda.createConsumablesTable = function() {
- let htmlSkel = $(`<div id='consumables_overview'></div>`)
- let html = $(`
- <div class ='consumables_filter' style='position: relative'>
- <div id='energy_consumables' style='position: absolute; top: 10px; left: 15px'></div>
- <div id='motivation_consumables' style='position: absolute; top: 10px; left: 160px'></div>
- <div id='health_consumables' style='position: absolute; top: 10px; left: 320px'></div>
- <div id='buff_consumables' style='position: absolute; top: 10px; left: 460px'></div>
- </div>`
- )
-
- let table = new west.gui.Table()
- let consumableList = Vajda.filterConsumables(Vajda.consumableSelection.energy, Vajda.consumableSelection.motivation, Vajda.consumableSelection.health, Vajda.consumableSelection.hideBuffs)
- table.addColumn("consumIcon","consumIcon").addColumn("consumCount","consumCount").addColumn("consumEnergy","consumEnergy").addColumn("consumMotivation","consumMotivation").addColumn("consumHealth","consumHealth").addColumn("consumBuffs", "consumBuffs").addColumn("consumSelected","consumSelected")
- table.appendToCell("head","consumIcon","Image").appendToCell("head","consumCount","Count").appendToCell("head","consumEnergy","Energy").appendToCell("head","consumMotivation","Motivation").appendToCell("head","consumHealth","Health").appendToCell("head", "consumBuffs", "Buffs").appendToCell("head","consumSelected","Use")
- for ( const consumable of consumableList ) {
- const checkbox = new west.gui.Checkbox()
- checkbox.setSelected(consumable.isSelected)
- checkbox.setId(consumable.id)
- checkbox.setCallback(function() {
- Vajda.consumableTablePosition.content = $(".vajda-window .tw2gui_scrollpane_clipper_contentpane").css("top")
- Vajda.consumableTablePosition.scrollbar = $(".vajda-window .tw2gui_scrollbar_pulley").css("top")
- if ( consumable instanceof Buff && !consumable.hasCooldown() ) {
- Manager.selectedBuffs = consumable
- Vajda.selectTab('consumables')
- Vajda.setCookies()
- return
- }
- Vajda.changeConsumableSelection(parseInt(this.divMain.attr("id")), this.isSelected())
- Vajda.selectTab("consumables")
- Vajda.setCookies()
- })
- table.appendRow().appendToCell(-1,"consumIcon", Vajda.getConsumableIcon(consumable.image)).appendToCell(-1,"consumCount",consumable.count).appendToCell(-1,"consumEnergy",consumable.energy).appendToCell(-1,"consumMotivation",consumable.motivation).appendToCell(-1,"consumHealth",consumable.health).appendToCell(-1, "consumBuffs", consumable.getBuffHTML()).appendToCell(-1,"consumSelected",checkbox.getMainDiv())
- }
- const buttonSelect = new west.gui.Button("Select all", function() {
- Vajda.changeSelectionAllConsumables(true)
- Vajda.selectTab("consumables")
- Vajda.setCookies()
- })
- const buttonDeselect = new west.gui.Button("Deselect all", function() {
- Vajda.changeSelectionAllConsumables(false)
- Vajda.selectTab("consumables")
- Vajda.setCookies()
- })
- table.appendToFooter("consumEnergy",buttonSelect.getMainDiv())
- table.appendToFooter("consumHealth",buttonDeselect.getMainDiv())
- htmlSkel.append(table.getMainDiv())
- const checkboxEnergyConsumes = new west.gui.Checkbox()
- checkboxEnergyConsumes.setLabel("Energy consumables")
- checkboxEnergyConsumes.setSelected(Vajda.consumableSelection.energy)
- checkboxEnergyConsumes.setCallback(function() {
- Vajda.consumableSelection.energy = this.isSelected()
- Vajda.selectTab("consumables")
- })
- const checkboxMotivationConsumes = new west.gui.Checkbox()
- checkboxMotivationConsumes.setLabel("Motivation consumables")
- checkboxMotivationConsumes.setSelected(this.consumableSelection.motivation)
- checkboxMotivationConsumes.setCallback(function() {
- Vajda.consumableSelection.motivation = this.isSelected()
- Vajda.selectTab("consumables")
- })
- const checkboxHealthConsumes = new west.gui.Checkbox()
- checkboxHealthConsumes.setLabel("Health consumables")
- checkboxHealthConsumes.setSelected(this.consumableSelection.health)
- checkboxHealthConsumes.setCallback(function() {
- Vajda.consumableSelection.health = this.isSelected()
- Vajda.selectTab("consumables")
- })
- const buffsFilter = new west.gui.Checkbox()
- buffsFilter.setLabel("Hide buffs")
- buffsFilter.setSelected(this.consumableSelection.hideBuffs)
- buffsFilter.setCallback(function() {
- Vajda.consumableSelection.hideBuffs = this.isSelected()
- Vajda.selectTab("consumables")
- })
- $("#energy_consumables", html).append(checkboxEnergyConsumes.getMainDiv())
- $("#motivation_consumables", html).append(checkboxMotivationConsumes.getMainDiv())
- $("#health_consumables", html).append(checkboxHealthConsumes.getMainDiv())
- $("#buff_consumables", html).append(buffsFilter.getMainDiv())
- htmlSkel.append(html)
- return htmlSkel
- }
-
- Vajda.createAddedJobsTab = function() {
- const htmlSkel = $(`<div id='added_jobs_overview'></div>`)
- const footerHtml = $(`
- <div id='start_vajda' style='position: relative'>
- <span id='vajda-state-info' class='vajda_state' style='position: absolute; left: 20px; top: 10px; font-family: Arial, Helvetica, sans-serif; font-size: 15px; font-weight: bold;'>
- Current state: ${Vajda.states[Vajda.currentState]}
- </span>
- <div class='vajda_run' style='position: absolute; left: 350px; top: 20px'></div>
- </div>
- `)
- const table = new west.gui.Table()
- table.addColumn("jobIcon","jobIcon").addColumn("jobName","jobName").addColumn("jobStopMotivation","jobStopMotivation").addColumn("jobSet","jobSet").addColumn("jobRemove","jobRemove")
- table.appendToCell("head","jobIcon","Job icon").appendToCell("head","jobName","Job name").appendToCell("head","jobStopMotivation","Stop motivation").appendToCell("head","jobSet","Job set").appendToCell("head","jobRemove","")
- for ( let job = 0; job < Vajda.addedJobs.length; job++ ) {
- table.appendRow().appendToCell(-1,"jobIcon", Vajda.getJobIcon(Vajda.addedJobs[job].isSilver, Vajda.addedJobs[job].id, Vajda.addedJobs[job].x, Vajda.addedJobs[job].y)).appendToCell(-1,"jobName", Vajda.getJobName(Vajda.addedJobs[job].id)).appendToCell(-1,"jobStopMotivation", Vajda.createMinMotivationTextfield(Vajda.addedJobs[job].x, Vajda.addedJobs[job].y, Vajda.addedJobs[job].id, Vajda.addedJobs[job].stopMotivation)).appendToCell(-1,"jobSet", Vajda.createComboxJobSets(Vajda.addedJobs[job].x, Vajda.addedJobs[job].y, Vajda.addedJobs[job].id)).appendToCell(-1,"jobRemove", Vajda.createRemoveJobButton(Vajda.addedJobs[job].x, Vajda.addedJobs[job].y, Vajda.addedJobs[job].id))
- }
- const buttonStart = new west.gui.Button("Start", async function() {
- const parseSuccesful = Vajda.parseStopMotivation()
- if ( parseSuccesful ) {
- Vajda.currentState = 3
- $(`#vajda-state-info`).text(`Current state: ${Vajda.states[3]}`)
- Vajda.createRoute()
- Vajda.isRunning = true
- Vajda.setCookies()
- if ( Manager.isOptimized && Manager.hasEnoughPlugsAndDecorations() ) {
- await Manager.createSchedule()
- }
- Observer.start()
- Vajda.run()
- } else {
- new UserMessage("Wrong format of set stop motivation", UserMessage.TYPE_ERROR).show()
- }
- });
- const buttonStop = new west.gui.Button("Stop",function() {
- Vajda.isRunning = false
- Vajda.currentState = 0
- Vajda.selectTab("chosenJobs")
- Observer.stop()
- })
- htmlSkel.append(table.getMainDiv())
- $(".vajda_run",footerHtml).append(buttonStart.getMainDiv())
- $(".vajda_run",footerHtml).append(buttonStop.getMainDiv())
- htmlSkel.append(footerHtml)
- return htmlSkel
- }
-
-
- Vajda.createStatisticsGui = function() {
- const offsetLeft = '.5rem'
-
- const statsBubbleStyle = `'
- padding: 1rem 2rem;
- border-radius: 10px;
- background-color: rgba(255, 255, 228, .3);
- position: relative;
- box-shadow: 0 0 5px rgba(0, 0, 0, .2)
- '`
-
- const pseudoHeadingStyle = `'
- display: block;
- width: calc(100% - ${offsetLeft});
- padding-left: ${offsetLeft};
- border-bottom: 1px solid black;
- margin-bottom: .5rem
- '`
-
- const refreshStats = `
- <div style=${statsBubbleStyle}>
- <b style=${pseudoHeadingStyle}>REFRESH COUNT</b>
- <p style='padding-left:${offsetLeft}'>Total in this session: ${Observer.refreshCount}</p>
- </div>
- `
-
- return $(`
- <div id='statistics_overview' style='padding: 0 2rem; display: grid; gap: 1rem'>
- <div style=${statsBubbleStyle}>
- <b style=${pseudoHeadingStyle}>EXPERIENCE</b>
- <p style='padding-left: ${offsetLeft}'>Total in this session: ${Vajda.formatNumber(Vajda.statistics.sessionXpCount)}</p>
- <p style='padding-left: ${offsetLeft}'>Total overall: ${Vajda.formatNumber(Vajda.statistics.totalXpCount)}</p>
- </div>
-
- <div style=${statsBubbleStyle}>
- <b style=${pseudoHeadingStyle}>MONEY</b>
- <p style='padding-left: ${offsetLeft}'>Total in this session: ${Vajda.formatNumber(Vajda.statistics.sessionMoneyCount)}</p>
- <p style='padding-left: ${offsetLeft}'>Total overall: ${Vajda.formatNumber(Vajda.statistics.totalMoneyCount)}</p>
- </div>
-
- <div style=${statsBubbleStyle}>
- <b style=${pseudoHeadingStyle}>JOBS</b>
- <p style='padding-left: ${offsetLeft}'>Total in this session: ${Vajda.formatNumber(Vajda.statistics.sessionJobsCount)}</p>
- <p style='padding-left: ${offsetLeft}'>Total overall: ${Vajda.formatNumber(Vajda.statistics.totalJobsCount)}</p>
- </div>
-
- ${Observer.isEnabled ? refreshStats : ''}
- </div>
- `)
- }
-
- Vajda.createSettingsGui = function() {
- const htmlSkel = $(`<div id='settings_overview' style='padding: 10px'></div>`)
- const checkboxAddEnergy = new west.gui.Checkbox()
- checkboxAddEnergy.setLabel("Add energy")
- checkboxAddEnergy.setSelected(Vajda.settings.addEnergy)
- checkboxAddEnergy.setCallback(function() {
- Vajda.settings.addEnergy = !Vajda.settings.addEnergy
- })
- const checkboxAddMotivation = new west.gui.Checkbox()
- checkboxAddMotivation.setLabel("Add motivation")
- checkboxAddMotivation.setSelected(Vajda.settings.addMotivation)
- checkboxAddMotivation.setCallback(function() {
- Vajda.settings.addMotivation = !Vajda.settings.addMotivation
- })
- const checkboxAddHealth = new west.gui.Checkbox()
- checkboxAddHealth.setLabel("Add health")
- checkboxAddHealth.setSelected(Vajda.settings.addHealth)
- checkboxAddHealth.setCallback(function() {
- Vajda.settings.addHealth = !Vajda.settings.addHealth
- })
-
- const buttPlugsCheckbox = new west.gui.Checkbox()
- buttPlugsCheckbox.setLabel('Optimize for butt plugs and cake decorations')
- buttPlugsCheckbox.setSelected(Manager.isOptimized)
- buttPlugsCheckbox.setCallback(() => {
- Manager.isOptimized = p => !p
- })
-
- const enableObserverCheckbox = new west.gui.Checkbox()
- enableObserverCheckbox.setLabel('[Experimental] Enable auto refresh → Read user manual')
- enableObserverCheckbox.setSelected(Observer.isEnabled)
- enableObserverCheckbox.setCallback(() => {
- Observer.isEnabled = previous => {
- $('#observer-delay-input').css('max-height', previous ? '0px' : '30px')
-
- Vajda.isRunning && !previous && Observer.start(forceStart = true)
- Vajda.isRunning && previous && Observer.stop()
-
- return !previous
- }
- })
-
- const observerDelayInput = new west.gui.Textfield()
- observerDelayInput.setWidth(100)
- observerDelayInput.setValue(Observer.getTimeOut(true))
- observerDelayInput.getMainDiv()[0].querySelector('input').addEventListener('change', e => {
- const val = e.target.value
-
- if ( Vajda.isNumber(val) ) {
- Observer.timeOut = val
- }
- })
-
- const style = (isOpen) => `'
- overflow: hidden;
- max-height: ${isOpen ? '30' : '0'}px;
- transition: max-height .5s;
- margin-bottom: 1rem;
- '`
- const observerDelay = $(`
- <div style=${style(Observer.isEnabled)} id='observer-delay-input'>
- Refresh page after
- </div>
- `)
- observerDelay.append(observerDelayInput.getMainDiv())
- observerDelay.append(` minutes since the last action`)
-
- const saveMoneyCheckbox = new west.gui.Checkbox()
- saveMoneyCheckbox.setLabel('Deposit money in your hometown')
- saveMoneyCheckbox.setSelected(Vajda.settings.addDeposit.isEnabled)
- saveMoneyCheckbox.setCallback(() => {
- if ( Character.homeTown.town_id === 0 ) {
- new UserMessage("You don' have a home town", UserMessage.TYPE_HINT).show()
- return
- }
-
- const oldVal = !!Vajda.settings.addDeposit.isEnabled
- Vajda.settings.addDeposit.isEnabled = !oldVal
-
- $(`#deposit-limit-input`).css('max-height', oldVal ? '0px' : '30px')
- })
-
- const depositLimit = $(`
- <div style=${style(Vajda.settings.addDeposit.isEnabled)} id='deposit-limit-input'>
- Deposit when more than
- </div>
- `)
-
- const limitInput = new west.gui.Textfield()
- limitInput.setWidth(100)
- limitInput.setValue(Number.isNaN(Vajda.settings.addDeposit.limit) ? '' : Vajda.settings.addDeposit.limit)
- limitInput.getMainDiv()[0].querySelector('input').addEventListener('change', e => {
- const val = e.target.value
-
- if ( Vajda.isNumber(val) ) {
- Vajda.settings.addDeposit.limit = val
- }
- })
-
- depositLimit.append(limitInput.getMainDiv())
- depositLimit.append(` $ in cash`)
-
-
-
- const htmlHealthStop = $("<div></div>")
- htmlHealthStop.append(`<span>Stoppage health percent value</span>`)
- const healthStopTextfiled = new west.gui.Textfield("healthStop")
- healthStopTextfiled.setValue(Vajda.settings.healthStop)
- healthStopTextfiled.setWidth(100)
- htmlHealthStop.append(healthStopTextfiled.getMainDiv())
- const htmlSetWearDelay = $("<div></div>")
- htmlSetWearDelay.append("<span> Job set equip delay </span>")
- const setWearDelayTextfiled = new west.gui.Textfield("setWearDelay")
- setWearDelayTextfiled.setValue(Vajda.settings.setWearDelay)
- setWearDelayTextfiled.setWidth(100)
- htmlSetWearDelay.append(setWearDelayTextfiled.getMainDiv())
-
- const htmlJobDelay = $("<div></div>")
- htmlJobDelay.append(`<span>Random delay between jobs(seconds)</span>`)
- const jobDelayTextFieldMin = new west.gui.Textfield("jobDelay")
- jobDelayTextFieldMin.setValue(Vajda.settings.jobDelayMin)
- jobDelayTextFieldMin.setWidth(50)
- const jobDelayTextFieldMax = new west.gui.Textfield("jobDelay")
- jobDelayTextFieldMax.setValue(Vajda.settings.jobDelayMax)
- jobDelayTextFieldMax.setWidth(50)
-
- htmlJobDelay.append(jobDelayTextFieldMin.getMainDiv())
- htmlJobDelay.append("<span> - </span>")
- htmlJobDelay.append(jobDelayTextFieldMax.getMainDiv())
-
-
- const manualLink = `
- <div onclick=Vajda.selectTab('manual') style="cursor: pointer; text-decoration: underline; position: absolute; top: 20px; right: 25px;">
- Open User Manual <svg style="width: 10px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M352 0c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9L370.7 96 201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L416 141.3l41.4 41.4c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6V32c0-17.7-14.3-32-32-32H352zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z"/></svg>
- </div>
- `
-
- const buttonApply = new west.gui.Button("Apply", function() {
- Vajda.settings.addEnergy = checkboxAddEnergy.isSelected()
- Vajda.settings.addMotivation = checkboxAddMotivation.isSelected()
- Vajda.settings.addHealth = checkboxAddHealth.isSelected()
- if ( Vajda.isNumber(healthStopTextfiled.getValue()) ) {
- let healthStop = parseInt(healthStopTextfiled.getValue())
- healthStop = Math.min(30,healthStop)
- Vajda.settings.healthStop = healthStop
- }
-
- if ( Vajda.isNumber(setWearDelayTextfiled.getValue()) ) {
- let setWearDelay = parseInt(setWearDelayTextfiled.getValue())
- setWearDelay = Math.min(10,setWearDelay)
- Vajda.settings.setWearDelay = setWearDelay
- }
-
- if ( Vajda.isNumber(jobDelayTextFieldMin.getValue()) ) {
- let jobDelayTimeMin = parseInt(jobDelayTextFieldMin.getValue())
- Vajda.settings.jobDelayMin = jobDelayTimeMin
- } else {
- Vajda.settings.jobDelayMin = 0
- Vajda.settings.jobDelayMax = 0
- new UserMessage("Wrong format of delay job min value. Please set a number.", UserMessage.TYPE_ERROR).show()
- }
-
- if ( Vajda.isNumber(jobDelayTextFieldMax.getValue()) ) {
- let jobDelayTimeMax = parseInt(jobDelayTextFieldMax.getValue())
- Vajda.settings.jobDelayMax = jobDelayTimeMax
- } else {
- Vajda.settings.jobDelayMin = 0
- Vajda.settings.jobDelayMax = 0
- new UserMessage("Wrong format of delay job max value. Please set a number.", UserMessage.TYPE_ERROR).show()
- }
- Vajda.setCookies()
- Vajda.selectTab("settings")
- })
-
- htmlSkel.append(manualLink)
-
- htmlSkel.append(checkboxAddEnergy.getMainDiv())
- htmlSkel.append("<br>")
- htmlSkel.append(checkboxAddMotivation.getMainDiv())
- htmlSkel.append("<br>")
- htmlSkel.append(checkboxAddHealth.getMainDiv())
- htmlSkel.append("<br>")
- htmlSkel.append(buttPlugsCheckbox.getMainDiv())
- htmlSkel.append("<br>")
- htmlSkel.append(enableObserverCheckbox.getMainDiv())
- htmlSkel.append("<br>")
- htmlSkel.append(observerDelay)
- htmlSkel.append(saveMoneyCheckbox.getMainDiv())
- htmlSkel.append(depositLimit)
- htmlSkel.append(htmlHealthStop)
- htmlSkel.append("<br>")
- htmlSkel.append(htmlSetWearDelay)
- htmlSkel.append("<br>")
- htmlSkel.append(htmlJobDelay)
- htmlSkel.append("<br>")
- htmlSkel.append(buttonApply.getMainDiv())
- return htmlSkel
- }
-
- Vajda.createManualGui = function() {
- const listStyle = `'padding-inline-start: 14px'`
- const nestedListStyle = `'padding-inline-start: 30px'`
- const containerStyle = `'
- padding: 0 30px 30px
- '`
-
- const html = `
- <div style=${containerStyle}>
- <h3>Read Before use</h3>
- <ol style=${listStyle}>
- <li>
- <strong>Calculating optimal route</strong> takes time and memory, a lot of it. It might not be noticeable for up to 12-14 jobs,
- but anything more than that... you will notice a short freeze of the window. I don't recommend selecting more than 18 jobs, as the
- algorithm will take about a minute (depending on the hardware, of course) to execute, while it takes almost 8 minutes to
- find the best route for 20 jobs. In these scenarios, your browser may appear unresponsive and prompt you to reload the page
- or wait. I recommend being patient and allowing some time for the algorithm to complete. If that doesn't work, remove one
- or two jobs; that's the cheapest way to solve this problem.
- </li>
-
- <li>
- <strong>The optimization for butt plugs and cake decorations</strong> setting, which is most likely why you are here:
- <ul style=${nestedListStyle}>
- <li>The setting has to be enabled <i>before</i> you start Zdenka, it won't work otherwise</li>
- <li>The <i>Add motivation</i> setting has to be enabled as well</li>
- <li>Do not start Zdenka with low energy and consumables on cooldown</li>
- <li>Do not use consumables yourself while it's running</li>
- <li>
- You don't have to select consumables manually with this setting, Zdenka will do it for you. Just make sure
- you have enough of them butt plugs and decorations
- </li>
- </ul>
-
- These restrictions are simply the cost of having Zdenka refill energy <i>while</i> doing jobs.
- </li>
-
- <li>
- Zdenka can <strong>travel</strong> to jobs that you can't do in travel set (unless you are super low level).
- </li>
-
- <li>
- <strong>Buffs</strong> will be used automatically when selected (and when no buff is active, of course). Only one buff
- of each type can be selected at once. Keep in mind that consumables with cooldown are <b>not</b> treated as buffs and will
- only be used to refill whatever your character needs.
- </li>
-
- <li>
- Zdenka will display <strong>all silver jobs</strong>, not just those you can do and are closest to yoor character. This
- allows you <i>some</i> control of the route, for instance there might be multiple silver jobs of the same kind and one
- of them might simply be in a more advantageous position.
- </li>
-
- <li>
- When <strong>Auto Refresh</strong> is enabled, Zdenka will refresh the page and start automatically <i>n</i> minutes
- after starting a job (or walking to one). Starting new jobs will restart this countdown. Do not set the delay to low numbers,
- Zdenka enforces a minimum of 2.5 minutes anyway, however, I do recommend a slightly longer delay.
- </li>
- </ol>
- </div>
- `
-
- const container = new west.gui.Scrollpane().getMainDiv()
- container.style = 'height: 400px; overflow-y: scroll'
- container.innerHTML = html
-
-
- return container
- }
-
- Vajda.createMenuIcon = function() {
- const menuImage = 'data:image/jpeg;base64,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'
- let div = $('<div class="ui_menucontainer" />')
- let link = $('<div id="vajda_menu" class="menulink" onclick=Vajda.loadJobs() title="Zdenka Studenková" />').css('background-image', 'url(' + menuImage + ')')
- $('#ui_menubar').append((div).append(link).append('<div class="menucontainer_bottom" />'))
- }
-
-
- Vajda.createWindow = function(isHumanAction = true) {
- const window = wman.open("vajda").setResizeable(false).setMinSize(650, 480).setSize(650, 480).setMiniTitle("Vajda Jožo")
- const tabs = {
- "jobs": "Jobs",
- "chosenJobs": "Chosen Jobs",
- "sets": "Sets",
- "consumables": "Consumables",
- "stats": "Statistics",
- "settings": "Settings",
- "manual": "User manual"
- }
-
- let tabLogic = function(win,id) {
- const content = $(`<div class='vajda-window'></div>`)
- switch(id) {
- case 'jobs':
- Vajda.loadJobData(function(){
- Vajda.removeActiveTab(this)
- Vajda.removeWindowContent()
- Vajda.addActiveTab("jobs",this)
- content.append(Vajda.createJobsTab())
- Vajda.window.appendToContentPane(content)
- Vajda.addJobTableCss()
- $(".vajda-window .tw2gui_scrollpane_clipper_contentpane").css({"top": Vajda.jobTablePosition.content})
- $(".vajda-window .tw2gui_scrollbar_pulley").css({"top": Vajda.jobTablePosition.scrollbar})
- Vajda.addEventsHeader()
- })
- break
- case 'chosenJobs':
- Vajda.removeActiveTab(this)
- Vajda.removeWindowContent()
- Vajda.addActiveTab("chosenJobs", this)
- content.append(Vajda.createAddedJobsTab())
- Vajda.window.appendToContentPane(content)
- $(".vajda-window .tw2gui_scrollpane_clipper_contentpane").css({"top": Vajda.addedJobTablePosition.content})
- $(".vajda-window .tw2gui_scrollbar_pulley").css({"top": Vajda.addedJobTablePosition.scrollbar})
- Vajda.addAddedJobsTableCss()
- break
- case 'sets':
- Vajda.loadSets(function() {
- Vajda.removeActiveTab(this)
- Vajda.removeWindowContent()
- Vajda.addActiveTab("sets",this)
- content.append(Vajda.createSetGui())
- Vajda.window.appendToContentPane(content)
- })
- break
- case 'consumables':
- Vajda.removeActiveTab(this)
- Vajda.removeWindowContent()
- Vajda.addActiveTab("consumables",this)
- Vajda.findAllConsumables()
- content.append(Vajda.createConsumablesTable())
- Vajda.window.appendToContentPane(content)
- $(".vajda-window .tw2gui_scrollpane_clipper_contentpane").css({"top": Vajda.consumableTablePosition.content})
- $(".vajda-window .tw2gui_scrollbar_pulley").css({"top": Vajda.consumableTablePosition.scrollbar})
- Vajda.addConsumableTableCss()
- break
- case 'stats':
- Vajda.removeActiveTab(this)
- Vajda.removeWindowContent()
- Vajda.addActiveTab("stats",this)
- content.append(Vajda.createStatisticsGui())
- Vajda.window.appendToContentPane(content)
- break
- case 'settings':
- Vajda.removeActiveTab(this)
- Vajda.removeWindowContent()
- Vajda.addActiveTab("settings",this)
- content.append(Vajda.createSettingsGui())
- Vajda.window.appendToContentPane(content)
- break
- case 'manual':
- Vajda.removeActiveTab(this)
- Vajda.removeWindowContent()
- Vajda.addActiveTab("manual", this)
- content.append(Vajda.createManualGui())
- Vajda.window.appendToContentPane(content)
- break
- }
- }
-
- for(let tab in tabs) {
- window.addTab(tabs[tab],tab,tabLogic)
- }
-
- Vajda.window = window
-
- if ( !isHumanAction ) wman.close('vajda')
-
- Vajda.selectTab('jobs')
- }
-
- Vajda.selectTab = function(key) {
- Vajda.window.tabIds[key].f(Vajda.window,key)
- }
-
- Vajda.removeActiveTab = function(window) {
- $('div.tw2gui_window_tab', window.divMain).removeClass('tw2gui_window_tab_active')
- }
-
- Vajda.addActiveTab = function(key, window) {
- $(`div._tab_id_${key}`, window.divMain).addClass('tw2gui_window_tab_active')
- }
-
- Vajda.removeWindowContent = function() {
- $(".vajda-window").remove()
- }
-
- Vajda.addConsumableTableCss = function() {
- $(".vajda-window .consumIcon").css({"width":"80px"})
- $(".vajda-window .consumCount").css({"width":"60px"})
- $(".vajda-window .consumEnergy").css({"width":"60px"})
- $(".vajda-window .consumMotivation").css({"width":"70px"})
- $(".vajda-window .consumHealth").css({"width":"60px"})
- $(".vajda-window .consumBuffs").css({"width": "150px"})
- $(".vajda-window .row").css({"height":"80px"})
- $('.vajda-window').find('.tw2gui_scrollpane').css('height', '250px')
- }
-
- Vajda.addJobTableCss = function() {
- $(".vajda-window .jobIcon").css({"width":"80px"})
- $(".vajda-window .jobName").css({"width":"150px"})
- $(".vajda-window .jobXp").css({"width":"40px"})
- $(".vajda-window .jobMoney").css({"width":"40px"})
- $(".vajda-window .jobMotivation").css({"width":"40px"})
- $(".vajda-window .jobDistance").css({"width":"100px"})
- $(".vajda-window .row").css({"height":"60px"})
- $('.vajda-window').find('.tw2gui_scrollpane').css('height', '250px')
- }
-
- Vajda.addAddedJobsTableCss = function() {
- $(".vajda-window .jobIcon").css({"width":"80px"})
- $(".vajda-window .jobName").css({"width":"130px"})
- $(".vajda-window .jobStopMotivation").css({"width":"110px"})
- $(".vajda-window .jobRemove").css({"width":"105px"})
- $(".vajda-window .jobSet").css({"width":"100px"})
- $(".vajda-window .row").css({"height":"60px"})
- $('.vajda-window').find('.tw2gui_scrollpane').css('height', '250px')
- }
-
- Vajda.createJobsTab = function() {
- const htmlSkel = $(`<div id='jobs_overview'></div>`)
- const html = $(`
- <div class='jobs_search' style='position: relative'>
- <div id='jobFilter' style='position: absolute; top: 10px; left: 15px'></div>
- <div id='job_only_silver' style='position: absolute; top:10px; left: 200px;'></div>
- <div id='job_no_silver' style='position: absolute; top: 10px; left: 270px;'></div>
- <div id='job_center' style='position: absolute; top: 10px; left: 350px;'></div>
- <div id='button_filter_jobs' style='position: absolute; top: 5px; left: 450px;'></div>
- </div>
- `)
-
- const table = new west.gui.Table()
- const xpIcon = '<img src="/images/icons/star.png">'
- const dollarIcon = '<img src="/images/icons/dollar.png">'
- const motivationIcon = '<img src="/images/icons/motivation.png">'
- const arrow_desc = ' <img src="../images/window/jobs/sortarrow_desc.png"/>'
- const arrow_asc = ' <img src="../images/window/jobs/sortarrow_asc.png"/>'
- const uniqueJobs = Vajda.getAllUniqueJobs()
- table
- .addColumn("jobIcon","jobIcon")
- .addColumn("jobName","jobName")
- .addColumn("jobXp","jobXp")
- .addColumn("jobMoney","jobMoney")
- .addColumn("jobMotivation","jobMotivation")
- .addColumn("jobDistance","jobDistance")
- .addColumn("jobAdd","jobAdd")
- table.appendToCell("head","jobIcon","Job icon").appendToCell("head","jobName","Job name").appendToCell("head","jobXp",xpIcon + (Vajda.sortJobTableXp == 1 ? arrow_asc : Vajda.sortJobTableXp == -1 ? arrow_desc : "")).appendToCell("head","jobMoney",dollarIcon).appendToCell("head","jobMotivation",motivationIcon).appendToCell("head","jobDistance","Distance " + (Vajda.sortJobTableDistance == 1 ? arrow_asc : Vajda.sortJobTableDistance == -1 ? arrow_desc : "")).appendToCell("head","jobAdd","")
- for ( let job = 0; job < uniqueJobs.length; job++ ) {
- table
- .appendRow()
- .appendToCell(-1,"jobIcon",Vajda.getJobIcon(uniqueJobs[job].isSilver,uniqueJobs[job].id,uniqueJobs[job].x,uniqueJobs[job].y))
- .appendToCell(-1,"jobName",Vajda.getJobName(uniqueJobs[job].id))
- .appendToCell(-1,"jobXp",uniqueJobs[job].experience)
- .appendToCell(-1,"jobMoney",uniqueJobs[job].money)
- .appendToCell(-1,"jobMotivation",uniqueJobs[job].motivation)
- .appendToCell(-1,"jobDistance",uniqueJobs[job].distance.formatDuration())
- .appendToCell(-1,"jobAdd", Vajda.createAddJobButton(uniqueJobs[job].x,uniqueJobs[job].y,uniqueJobs[job].id))
- }
- const textfield = new west.gui.Textfield("jobsearch").setPlaceholder("Select job name")
- if ( Vajda.jobFilter.filterJob !== "" ) {
- textfield.setValue(Vajda.jobFilter.filterJob)
- }
-
- const checkboxOnlySilver = new west.gui.Checkbox()
- checkboxOnlySilver.setLabel("Silvers")
- checkboxOnlySilver.setSelected(Vajda.jobFilter.filterOnlySilver)
- checkboxOnlySilver.setCallback(function() {
- if ( this.isSelected() ) {
- Vajda.jobFilter.filterOnlySilver = true
- }else {
- Vajda.jobFilter.filterOnlySilver = false
- }
- })
- const checkboxNoSilver = new west.gui.Checkbox()
- checkboxNoSilver.setLabel("No silvers")
- checkboxNoSilver.setSelected(Vajda.jobFilter.filterNoSilver)
- checkboxNoSilver.setCallback(function() {
- if ( this.isSelected() ) {
- Vajda.jobFilter.filterNoSilver = true
- } else {
- Vajda.jobFilter.filterNoSilver = false
- }
- })
- const checkboxCenterJobs = new west.gui.Checkbox()
- checkboxCenterJobs.setLabel("Center jobs")
- checkboxCenterJobs.setSelected(Vajda.jobFilter.filterCenterJobs)
- checkboxCenterJobs.setCallback(function() {
- if ( this.isSelected() ) {
- Vajda.jobFilter.filterCenterJobs = true
- } else {
- Vajda.jobFilter.filterCenterJobs = false
- }
- })
- const buttonFilter = new west.gui.Button("Filter", function() {
- Vajda.jobFilter.filterJob = textfield.getValue()
- Vajda.jobTablePosition.content = "0px"
- Vajda.jobTablePosition.scrollbar = "0px"
- Vajda.selectTab("jobs")
- })
- htmlSkel.append(table.getMainDiv())
- $('#jobFilter', html).append(textfield.getMainDiv())
- $("#job_only_silver",html).append(checkboxOnlySilver.getMainDiv())
- $("#job_no_silver",html).append(checkboxNoSilver.getMainDiv())
- $("#job_center",html).append(checkboxCenterJobs.getMainDiv())
- $("#button_filter_jobs",html).append(buttonFilter.getMainDiv())
- htmlSkel.append(html)
- return htmlSkel
- }
-
- Vajda.createAddJobButton = function(x, y, id) {
- const buttonAdd = new west.gui.Button("Add new job", function() {
- Vajda.addJob(x, y, id)
- Vajda.jobTablePosition.content = $(".vajda-window .tw2gui_scrollpane_clipper_contentpane").css("top")
- Vajda.jobTablePosition.scrollbar = $(".vajda-window .tw2gui_scrollbar_pulley").css("top")
- Vajda.selectTab("jobs")
- })
- buttonAdd.setWidth(100)
- return buttonAdd.getMainDiv()
- }
-
- Vajda.createMinMotivationTextfield = function(x, y, id, placeholder) {
- const componentId = `x-${x}y-${y}id-${id}`
- const textfield = new west.gui.Textfield()
- textfield.setId(componentId)
- textfield.setWidth(40)
- textfield.setValue(placeholder)
- return textfield.getMainDiv()
- }
-
- Vajda.createRemoveJobButton = function(x, y, id) {
- const buttonRemove = new west.gui.Button("Remove job", function() {
- Vajda.removeJob(x, y, id)
- Vajda.addedJobTablePosition.content = $(".vajda-window .tw2gui_scrollpane_clipper_contentpane").css("top")
- Vajda.addedJobTablePosition.scrollbar = $(".vajda-window .tw2gui_scrollbar_pulley").css("top")
- Vajda.selectTab("chosenJobs")
- })
- buttonRemove.setWidth(100)
- return buttonRemove.getMainDiv()
- }
-
-
- $(document).ready(() => {
- try {
- Vajda.loadLanguage()
- Vajda.loadSets()
- Vajda.createMenuIcon()
- Vajda.getCookies()
- Observer.resumeSession()
- } catch(e) {
- console.log(e)
- console.log("exception occured")
- }
- })
- })()