181 lines
5.5 KiB
TypeScript
181 lines
5.5 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { io, Socket } from 'socket.io-client'
|
|
import type { Asset, Character, Notification, User, WorldSettings } from '@/types'
|
|
import config from '@/config'
|
|
import { useCookies } from '@vueuse/integrations/useCookies'
|
|
|
|
export const useGameStore = defineStore('game', {
|
|
state: () => {
|
|
return {
|
|
loginMessage: null as string | null,
|
|
notifications: [] as Notification[],
|
|
assets: [] as Asset[],
|
|
token: '' as string | null,
|
|
connection: null as Socket | null,
|
|
user: null as User | null,
|
|
character: null as Character | null,
|
|
isPlayerDraggingCamera: false,
|
|
world: {
|
|
date: new Date(),
|
|
isRainEnabled: false,
|
|
isFogEnabled: false,
|
|
fogDensity: 0.5
|
|
} as WorldSettings,
|
|
gameSettings: {
|
|
isCameraFollowingCharacter: false
|
|
},
|
|
uiSettings: {
|
|
isChatOpen: false,
|
|
isUserPanelOpen: false,
|
|
isGmPanelOpen: false
|
|
}
|
|
}
|
|
},
|
|
getters: {
|
|
getNotifications: (state: any) => state.notifications,
|
|
getAssetByKey: (state) => {
|
|
return (key: string) => state.assets.find((asset) => asset.key === key)
|
|
}
|
|
},
|
|
actions: {
|
|
addNotification(notification: Notification) {
|
|
if (!notification.id) {
|
|
notification.id = Math.random().toString(16)
|
|
}
|
|
this.notifications.push(notification)
|
|
},
|
|
removeNotification(id: string) {
|
|
this.notifications = this.notifications.filter((notification: Notification) => notification.id !== id)
|
|
},
|
|
setAssets(assets: Asset[]) {
|
|
this.assets = assets
|
|
},
|
|
addAsset(asset: Asset) {
|
|
this.assets.push(asset)
|
|
},
|
|
addAssets(assets: Asset[]) {
|
|
this.assets = this.assets.concat(assets)
|
|
},
|
|
async fetchSpriteAssets() {
|
|
return fetch(config.server_endpoint + '/assets/sprites')
|
|
.then((response) => response.json())
|
|
.then((assets) => {
|
|
// Only add the sprites that are not already in the store
|
|
this.addAssets(assets.filter((asset: Asset) => !this.getAssetByKey(asset.key)))
|
|
return true
|
|
})
|
|
.catch((error) => {
|
|
console.error('Error fetching assets:', error)
|
|
return false
|
|
})
|
|
},
|
|
async fetchZoneAssets(zoneId: number) {
|
|
return fetch(config.server_endpoint + '/assets/zone/' + zoneId)
|
|
.then((response) => response.json())
|
|
.then((assets) => {
|
|
// Only add the zones that are not already in the store
|
|
this.addAssets(assets.filter((asset: Asset) => !this.getAssetByKey(asset.key)))
|
|
return true
|
|
})
|
|
.catch((error) => {
|
|
console.error('Error fetching assets:', error)
|
|
return false
|
|
})
|
|
},
|
|
async fetchAllZoneAssets() {
|
|
return fetch(config.server_endpoint + '/assets/zone')
|
|
.then((response) => response.json())
|
|
.then((assets) => {
|
|
// Only add the zones that are not already in the store
|
|
this.addAssets(assets.filter((asset: Asset) => !this.getAssetByKey(asset.key)))
|
|
return true
|
|
})
|
|
.catch((error) => {
|
|
console.error('Error fetching assets:', error)
|
|
return false
|
|
})
|
|
},
|
|
setToken(token: string) {
|
|
this.token = token
|
|
},
|
|
setUser(user: User | null) {
|
|
this.user = user
|
|
},
|
|
setCharacter(character: Character | null) {
|
|
this.character = character
|
|
},
|
|
toggleGmPanel() {
|
|
this.uiSettings.isGmPanelOpen = !this.uiSettings.isGmPanelOpen
|
|
},
|
|
togglePlayerDraggingCamera() {
|
|
this.isPlayerDraggingCamera = !this.isPlayerDraggingCamera
|
|
},
|
|
setPlayerDraggingCamera(moving: boolean) {
|
|
this.isPlayerDraggingCamera = moving
|
|
},
|
|
toggleCameraFollowingCharacter() {
|
|
this.gameSettings.isCameraFollowingCharacter = !this.gameSettings.isCameraFollowingCharacter
|
|
},
|
|
setCameraFollowingCharacter(following: boolean) {
|
|
this.gameSettings.isCameraFollowingCharacter = following
|
|
},
|
|
toggleChat() {
|
|
this.uiSettings.isChatOpen = !this.uiSettings.isChatOpen
|
|
},
|
|
toggleUserPanel() {
|
|
this.uiSettings.isUserPanelOpen = !this.uiSettings.isUserPanelOpen
|
|
},
|
|
initConnection() {
|
|
this.connection = io(config.server_endpoint, {
|
|
secure: !config.development,
|
|
withCredentials: true,
|
|
transports: ['websocket'],
|
|
reconnectionAttempts: 5
|
|
})
|
|
|
|
// #99 - If we can't connect, disconnect
|
|
this.connection.on('connect_error', () => {
|
|
this.disconnectSocket()
|
|
})
|
|
|
|
// Let the server know the user is logged in
|
|
this.connection.emit('login')
|
|
|
|
// set user
|
|
this.connection.on('logged_in', (user: User) => {
|
|
this.setUser(user)
|
|
})
|
|
|
|
// When we can't reconnect, disconnect
|
|
this.connection.on('reconnect_failed', () => {
|
|
this.disconnectSocket()
|
|
})
|
|
},
|
|
disconnectSocket() {
|
|
if (this.connection) this.connection.disconnect()
|
|
|
|
useCookies().remove('token', {
|
|
// for whole domain
|
|
// @TODO : #190
|
|
domain: window.location.hostname.split('.').slice(-2).join('.')
|
|
})
|
|
|
|
this.assets = []
|
|
this.connection = null
|
|
this.token = null
|
|
this.user = null
|
|
this.character = null
|
|
this.uiSettings.isGmPanelOpen = false
|
|
this.isPlayerDraggingCamera = false
|
|
this.gameSettings.isCameraFollowingCharacter = false
|
|
this.uiSettings.isChatOpen = false
|
|
this.uiSettings.isUserPanelOpen = false
|
|
|
|
this.world.date = new Date()
|
|
this.world.isRainEnabled = false
|
|
this.world.isFogEnabled = false
|
|
this.world.fogDensity = 0.5
|
|
}
|
|
}
|
|
})
|