Merge remote-tracking branch 'origin/main' into feature/map-refactor
This commit is contained in:
commit
f83e2bf8c8
753
package-lock.json
generated
753
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -18,10 +18,12 @@
|
||||
"@vueuse/integrations": "^10.5.0",
|
||||
"axios": "^1.7.7",
|
||||
"dexie": "^4.0.8",
|
||||
"phaser": "^3.86.0",
|
||||
"phaser": "3.87.0",
|
||||
"pinia": "^2.1.6",
|
||||
"sharp": "^0.33.5",
|
||||
"socket.io-client": "^4.8.0",
|
||||
"universal-cookie": "^6.1.3",
|
||||
"vite-plugin-image-optimizer": "^1.1.8",
|
||||
"vue": "^3.5.12",
|
||||
"zod": "^3.22.2"
|
||||
},
|
||||
|
@ -3,3 +3,59 @@ export enum Direction {
|
||||
NEGATIVE,
|
||||
UNCHANGED
|
||||
}
|
||||
|
||||
export enum SocketEvent {
|
||||
CLOSE = '52',
|
||||
DATA = '51',
|
||||
CHARACTER_CONNECT = '50',
|
||||
CHARACTER_CREATE = '49',
|
||||
CHARACTER_DELETE = '48',
|
||||
CHARACTER_LIST = '47',
|
||||
GM_CHARACTERHAIR_CREATE = '46',
|
||||
GM_CHARACTERHAIR_REMOVE = '45',
|
||||
GM_CHARACTERHAIR_LIST = '44',
|
||||
GM_CHARACTERHAIR_UPDATE = '43',
|
||||
GM_CHARACTERTYPE_CREATE = '42',
|
||||
GM_CHARACTERTYPE_REMOVE = '41',
|
||||
GM_CHARACTERTYPE_LIST = '40',
|
||||
GM_CHARACTERTYPE_UPDATE = '39',
|
||||
GM_ITEM_CREATE = '38',
|
||||
GM_ITEM_REMOVE = '37',
|
||||
GM_ITEM_LIST = '36',
|
||||
GM_ITEM_UPDATE = '35',
|
||||
GM_MAPOBJECT_LIST = '34',
|
||||
GM_MAPOBJECT_REMOVE = '33',
|
||||
GM_MAPOBJECT_UPDATE = '32',
|
||||
GM_MAPOBJECT_UPLOAD = '31',
|
||||
GM_SPRITE_COPY = '30',
|
||||
GM_SPRITE_CREATE = '29',
|
||||
GM_SPRITE_DELETE = '28',
|
||||
GM_SPRITE_LIST = '27',
|
||||
GM_SPRITE_UPDATE = '26',
|
||||
GM_TILE_DELETE = '25',
|
||||
GM_TILE_LIST = '24',
|
||||
GM_TILE_UPDATE = '23',
|
||||
GM_TILE_UPLOAD = '22',
|
||||
GM_MAP_CREATE = '21',
|
||||
GM_MAP_DELETE = '20',
|
||||
GM_MAP_REQUEST = '19',
|
||||
GM_MAP_UPDATE = '18',
|
||||
MAP_CHARACTER_MOVEERROR = '17',
|
||||
DISCONNECT = '16',
|
||||
USER_DISCONNECT = '15',
|
||||
LOGIN = '14',
|
||||
LOGGED_IN = '13',
|
||||
NOTIFICATION = '12',
|
||||
DATE = '11',
|
||||
FAILED = '10',
|
||||
COMPLETED = '9',
|
||||
CONNECTION = '8',
|
||||
WEATHER = '7',
|
||||
CHARACTER_DISCONNECT = '6',
|
||||
MAP_CHARACTER_ATTACK = '5',
|
||||
MAP_CHARACTER_TELEPORT = '4',
|
||||
MAP_CHARACTER_JOIN = '3',
|
||||
MAP_CHARACTER_LEAVE = '2',
|
||||
MAP_CHARACTER_MOVE = '1',
|
||||
CHAT_MESSAGE = '0'
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ const gameStore = useGameStore()
|
||||
const mapStore = useMapStore()
|
||||
const scene = useScene()
|
||||
|
||||
const { characterContainer, characterSprite, currentPositionX, currentPositionY, isometricDepth, isFlippedX, updatePosition, playAnimation, calcDirection, updateSprite, initializeSprite, cleanup } = useCharacterSpriteComposable(scene, props.tileMap, props.mapCharacter)
|
||||
const { characterContainer, characterSprite, currentPositionX, currentPositionY, isometricDepth, isFlippedX, updatePosition, playAnimation, updateSprite, initializeSprite, cleanup } = useCharacterSpriteComposable(scene, props.tileMap, props.mapCharacter)
|
||||
const { playSound, stopSound } = useSoundComposable()
|
||||
|
||||
const handlePositionUpdate = (newValues: any, oldValues: any) => {
|
||||
@ -92,7 +92,6 @@ watch(
|
||||
onMounted(async () => {
|
||||
await initializeSprite()
|
||||
if (props.mapCharacter.character.id === gameStore.character!.id) {
|
||||
mapStore.setCharacterLoaded(true)
|
||||
scene.cameras.main.startFollow(characterContainer.value as Phaser.GameObjects.Container)
|
||||
}
|
||||
})
|
||||
|
@ -1,51 +0,0 @@
|
||||
<template>
|
||||
<Image v-bind="imageProps" v-if="gameStore.getLoadedAsset(texture)" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { MapCharacter, Sprite as SpriteT } from '@/application/types'
|
||||
import { loadSpriteTextures } from '@/services/textureService'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { Image, useScene } from 'phavuer'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
mapCharacter: MapCharacter
|
||||
currentX: number
|
||||
currentY: number
|
||||
}>()
|
||||
|
||||
const gameStore = useGameStore()
|
||||
const scene = useScene()
|
||||
|
||||
const texture = computed(() => {
|
||||
const { rotation, characterHair } = props.mapCharacter.character
|
||||
const spriteId = characterHair?.sprite?.id
|
||||
const direction = [0, 6].includes(rotation) ? 'back' : 'front'
|
||||
|
||||
return `${spriteId}-${direction}`
|
||||
})
|
||||
|
||||
const isFlippedX = computed(() => [6, 4].includes(props.mapCharacter.character.rotation ?? 0))
|
||||
|
||||
const imageProps = computed(() => {
|
||||
// Get the current sprite action based on direction
|
||||
const direction = [0, 6].includes(props.mapCharacter.character.rotation ?? 0) ? 'back' : 'front'
|
||||
const spriteAction = props.mapCharacter.character.characterHair?.sprite?.spriteActions?.find((spriteAction) => spriteAction.action === direction)
|
||||
|
||||
return {
|
||||
depth: 1,
|
||||
originX: Number(spriteAction?.originX) ?? 0,
|
||||
originY: Number(spriteAction?.originY) ?? 0,
|
||||
flipX: isFlippedX.value,
|
||||
texture: texture.value
|
||||
// y: props.mapCharacter.isMoving ? Math.floor(Date.now() / 250) % 2 : 0
|
||||
}
|
||||
})
|
||||
|
||||
loadSpriteTextures(scene, props.mapCharacter.character.characterHair?.sprite as SpriteT)
|
||||
.then(() => {})
|
||||
.catch((error) => {
|
||||
console.error('Error loading texture:', error)
|
||||
})
|
||||
</script>
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Container ref="characterChatContainer" :depth="999">
|
||||
<Container ref="characterChatContainer">
|
||||
<RoundRectangle @create="createChatBubble" :origin-x="0.5" :origin-y="7.5" :fillColor="0xffffff" :width="194" :height="21" :radius="20" />
|
||||
<Text @create="createChatText" :style="{ fontSize: 13, fontFamily: 'Arial', color: '#000' }" />
|
||||
</Container>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="w-full md:min-w-[350px] max-w-[750px] flex flex-col absolute left-1/2 -translate-x-1/2 bottom-5">
|
||||
<div ref="chatWindow" class="w-full overflow-auto h-32 mb-5 bg-gray rounded-md border-2 border-solid border-gray-500 text-gray-300" v-show="gameStore.uiSettings.isChatOpen">
|
||||
<div v-for="message in chats" class="flex-col py-2 items-center p-3">
|
||||
<span class="text-ellipsis overflow-hidden whitespace-nowrap text-sm" :class="{ 'text-cyan-300': gameStore.character?.role == 'gm' }">{{ message.character.name }}</span>
|
||||
<span class="text-ellipsis overflow-hidden whitespace-nowrap text-sm" :class="{ 'text-cyan-300': gameStore.character?.role == 'gm' }">{{ message.character }}</span>
|
||||
<p class="text-gray-50 m-0">{{ message.message }}</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -21,7 +21,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Chat } from '@/application/types'
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useMapStore } from '@/stores/mapStore'
|
||||
import { onClickOutside, useFocus } from '@vueuse/core'
|
||||
@ -33,7 +33,7 @@ const gameStore = useGameStore()
|
||||
const mapStore = useMapStore()
|
||||
|
||||
const message = ref('')
|
||||
const chats = ref([] as Chat[])
|
||||
const chats = ref<{ character: string; message: string }[]>([])
|
||||
const chatWindow = ref<HTMLElement | null>(null)
|
||||
const chatInput = ref<HTMLElement | null>(null)
|
||||
|
||||
@ -55,7 +55,7 @@ function unfocusChat(event: Event, targetElement: HTMLElement) {
|
||||
|
||||
const sendMessage = () => {
|
||||
if (!message.value.trim()) return
|
||||
gameStore.connection?.emit('chat:message', { message: message.value }, (response: boolean) => {})
|
||||
gameStore.connection?.emit(SocketEvent.CHAT_MESSAGE, { message: message.value }, (response: boolean) => {})
|
||||
message.value = ''
|
||||
}
|
||||
|
||||
@ -79,21 +79,31 @@ const scrollToBottom = () => {
|
||||
})
|
||||
}
|
||||
|
||||
gameStore.connection?.on('chat:message', (data: Chat) => {
|
||||
chats.value.push(data)
|
||||
gameStore.connection?.on(SocketEvent.CHAT_MESSAGE, (data: { character: string; message: string }) => {
|
||||
if (!data.character || !data.message) return
|
||||
|
||||
|
||||
chats.value.push({ character: data.character, message: data.message })
|
||||
scrollToBottom()
|
||||
|
||||
if (!mapStore.characterLoaded) return
|
||||
const characterContainer = scene.children.getByName(data.character) as Phaser.GameObjects.Container
|
||||
if (!characterContainer) {
|
||||
console.log('No character container found')
|
||||
return
|
||||
}
|
||||
|
||||
const characterContainer = scene.children.getByName(data.character.name) as Phaser.GameObjects.Container
|
||||
if (!characterContainer) return
|
||||
const characterChatContainer = characterContainer.getByName(data.character + '_chatContainer') as Phaser.GameObjects.Container
|
||||
if (!characterChatContainer) {
|
||||
console.log('No character chat container found')
|
||||
return
|
||||
}
|
||||
|
||||
const characterChatContainer = characterContainer.getByName(data.character.name + '_chatContainer') as Phaser.GameObjects.Container
|
||||
if (!characterChatContainer) return
|
||||
|
||||
const chatBubble = characterChatContainer.getByName(data.character.name + '_chatBubble') as Phaser.GameObjects.Container
|
||||
const chatText = characterChatContainer.getByName(data.character.name + '_chatText') as Phaser.GameObjects.Text
|
||||
if (!chatText || !chatBubble) return
|
||||
const chatBubble = characterChatContainer.getByName(data.character + '_chatBubble') as Phaser.GameObjects.Container
|
||||
const chatText = characterChatContainer.getByName(data.character + '_chatText') as Phaser.GameObjects.Text
|
||||
if (!chatText || !chatBubble) {
|
||||
console.log('No chat text or bubble found')
|
||||
return
|
||||
}
|
||||
|
||||
function calculateTextWidth(text: string, font: string, fontSize: number): number {
|
||||
// Create a canvas element
|
||||
@ -144,7 +154,7 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
gameStore.connection?.off('chat:message')
|
||||
gameStore.connection?.off(SocketEvent.CHAT_MESSAGE)
|
||||
removeEventListener('keydown', focusChat)
|
||||
})
|
||||
</script>
|
||||
|
@ -7,6 +7,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useDateFormat } from '@vueuse/core'
|
||||
import { onUnmounted } from 'vue'
|
||||
@ -14,6 +15,6 @@ import { onUnmounted } from 'vue'
|
||||
const gameStore = useGameStore()
|
||||
|
||||
onUnmounted(() => {
|
||||
gameStore.connection?.off('date')
|
||||
gameStore.connection?.off(SocketEvent.DATE)
|
||||
})
|
||||
</script>
|
||||
|
@ -3,6 +3,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { MapCharacter, UUID } from '@/application/types'
|
||||
import Character from '@/components/game/character/Character.vue'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
@ -16,15 +17,15 @@ const props = defineProps<{
|
||||
tileMap: Phaser.Tilemaps.Tilemap
|
||||
}>()
|
||||
|
||||
gameStore.connection?.on('map:character:join', async (data: MapCharacter) => {
|
||||
gameStore.connection?.on(SocketEvent.MAP_CHARACTER_JOIN, (data: MapCharacter) => {
|
||||
mapStore.addCharacter(data)
|
||||
})
|
||||
|
||||
gameStore.connection?.on('map:character:leave', (characterId: UUID) => {
|
||||
gameStore.connection?.on(SocketEvent.MAP_CHARACTER_LEAVE, (characterId: UUID) => {
|
||||
mapStore.removeCharacter(characterId)
|
||||
})
|
||||
|
||||
gameStore.connection?.on('map:character:move', (data: { characterId: UUID; positionX: number; positionY: number; rotation: number; isMoving: boolean }) => {
|
||||
gameStore.connection?.on(SocketEvent.MAP_CHARACTER_MOVE, (data: { characterId: UUID; positionX: number; positionY: number; rotation: number; isMoving: boolean }) => {
|
||||
mapStore.updateCharacterPosition(data)
|
||||
// @TODO: Replace with universal class, composable or store
|
||||
if (data.characterId === gameStore.character?.id) {
|
||||
@ -34,13 +35,14 @@ gameStore.connection?.on('map:character:move', (data: { characterId: UUID; posit
|
||||
}
|
||||
})
|
||||
|
||||
gameStore.connection?.on('map:character:attack', (characterId: UUID) => {
|
||||
gameStore.connection?.on(SocketEvent.MAP_CHARACTER_ATTACK, (characterId: UUID) => {
|
||||
mapStore.updateCharacterProperty(characterId, 'isAttacking', true)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
gameStore.connection?.off('map:character:join')
|
||||
gameStore.connection?.off('map:character:leave')
|
||||
gameStore.connection?.off('map:character:move')
|
||||
gameStore.connection?.off(SocketEvent.MAP_CHARACTER_ATTACK)
|
||||
gameStore.connection?.off(SocketEvent.MAP_CHARACTER_MOVE)
|
||||
gameStore.connection?.off(SocketEvent.MAP_CHARACTER_JOIN)
|
||||
gameStore.connection?.off(SocketEvent.MAP_CHARACTER_LEAVE)
|
||||
})
|
||||
</script>
|
||||
|
@ -5,6 +5,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { mapLoadData } from '@/application/types'
|
||||
import { unduplicateArray } from '@/application/utilities'
|
||||
import Characters from '@/components/game/map/Characters.vue'
|
||||
@ -28,7 +29,7 @@ const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
||||
const tileMapLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>()
|
||||
|
||||
// Event listeners
|
||||
gameStore.connection?.on('map:character:teleport', async (data: mapLoadData) => {
|
||||
gameStore.connection?.on(SocketEvent.MAP_CHARACTER_TELEPORT, (data: mapLoadData) => {
|
||||
mapStore.setMapId(data.mapId)
|
||||
mapStore.setCharacters(data.characters)
|
||||
})
|
||||
@ -64,6 +65,6 @@ onUnmounted(() => {
|
||||
tileMap.value.destroy()
|
||||
}
|
||||
|
||||
gameStore.connection?.off('map:character:teleport')
|
||||
gameStore.connection?.off(SocketEvent.MAP_CHARACTER_TELEPORT)
|
||||
})
|
||||
</script>
|
||||
|
@ -61,7 +61,7 @@ function calculateObjectPlacement(mapObj: PlacedMapObject): { x: number; y: numb
|
||||
const imageProps = computed(() => ({
|
||||
alpha: mapEditor.movingPlacedObject.value?.id == props.placedMapObject.id || mapEditor.selectedMapObject.value?.id == props.placedMapObject.id ? 0.5 : 1,
|
||||
tint: mapEditor.selectedPlacedObject.value?.id == props.placedMapObject.id ? 0x00ff00 : 0xffffff,
|
||||
depth: calculateIsometricDepth(props.placedMapObject.positionX, props.placedMapObject.positionY, mapObject.value!.frameWidth, mapObject.value!.frameHeight),
|
||||
depth: calculateIsometricDepth(props.placedMapObject.positionX, props.placedMapObject.positionY, mapObject.value!.frameWidth, mapObject.value!.frameHeight, mapObject.value!.originX, mapObject.value!.originY),
|
||||
...calculateObjectPlacement(props.placedMapObject),
|
||||
flipX: props.placedMapObject.isRotated,
|
||||
texture: mapObject.value!.id,
|
||||
|
@ -34,6 +34,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { CharacterGender, CharacterHair, Sprite } from '@/application/types'
|
||||
import { useAssetManagerStore } from '@/stores/assetManagerStore'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
@ -65,7 +66,7 @@ if (selectedCharacterHair.value) {
|
||||
function removeCharacterHair() {
|
||||
if (!selectedCharacterHair.value) return
|
||||
|
||||
gameStore.connection?.emit('gm:characterHair:remove', { id: selectedCharacterHair.value.id }, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_CHARACTERHAIR_REMOVE, { id: selectedCharacterHair.value.id }, (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to remove character hair')
|
||||
return
|
||||
@ -75,7 +76,7 @@ function removeCharacterHair() {
|
||||
}
|
||||
|
||||
function refreshCharacterHairList(unsetSelectedCharacterHair = true) {
|
||||
gameStore.connection?.emit('gm:characterHair:list', {}, (response: CharacterHair[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_CHARACTERHAIR_LIST, {}, (response: CharacterHair[]) => {
|
||||
assetManagerStore.setCharacterHairList(response)
|
||||
|
||||
if (unsetSelectedCharacterHair) {
|
||||
@ -93,7 +94,7 @@ function saveCharacterHair() {
|
||||
spriteId: characterSpriteId.value
|
||||
}
|
||||
|
||||
gameStore.connection?.emit('gm:characterHair:update', characterHairData, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_CHARACTERHAIR_UPDATE, characterHairData, (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to save character type')
|
||||
return
|
||||
@ -113,7 +114,7 @@ watch(selectedCharacterHair, (characterHair: CharacterHair | null) => {
|
||||
onMounted(() => {
|
||||
if (!selectedCharacterHair.value) return
|
||||
|
||||
gameStore.connection?.emit('gm:sprite:list', {}, (response: Sprite[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_SPRITE_LIST, {}, (response: Sprite[]) => {
|
||||
assetManagerStore.setSpriteList(response)
|
||||
})
|
||||
})
|
||||
|
@ -32,6 +32,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { CharacterHair } from '@/application/types'
|
||||
import { useAssetManagerStore } from '@/stores/assetManagerStore'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
@ -52,13 +53,13 @@ const handleSearch = () => {
|
||||
}
|
||||
|
||||
const createNewCharacterHair = () => {
|
||||
gameStore.connection?.emit('gm:characterHair:create', {}, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_CHARACTERHAIR_CREATE, {}, (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to create new character type')
|
||||
return
|
||||
}
|
||||
|
||||
gameStore.connection?.emit('gm:characterHair:list', {}, (response: CharacterHair[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_CHARACTERHAIR_LIST, {}, (response: CharacterHair[]) => {
|
||||
assetManagerStore.setCharacterHairList(response)
|
||||
})
|
||||
})
|
||||
@ -92,7 +93,7 @@ function toTop() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
gameStore.connection?.emit('gm:characterHair:list', {}, (response: CharacterHair[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_CHARACTERHAIR_LIST, {}, (response: CharacterHair[]) => {
|
||||
assetManagerStore.setCharacterHairList(response)
|
||||
})
|
||||
})
|
||||
|
@ -40,6 +40,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { CharacterGender, CharacterRace, CharacterType, Sprite } from '@/application/types'
|
||||
import { useAssetManagerStore } from '@/stores/assetManagerStore'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
@ -74,7 +75,7 @@ if (selectedCharacterType.value) {
|
||||
function removeCharacterType() {
|
||||
if (!selectedCharacterType.value) return
|
||||
|
||||
gameStore.connection?.emit('gm:characterType:remove', { id: selectedCharacterType.value.id }, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_CHARACTERTYPE_REMOVE, { id: selectedCharacterType.value.id }, (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to remove character type')
|
||||
return
|
||||
@ -84,7 +85,7 @@ function removeCharacterType() {
|
||||
}
|
||||
|
||||
function refreshCharacterTypeList(unsetSelectedCharacterType = true) {
|
||||
gameStore.connection?.emit('gm:characterType:list', {}, (response: CharacterType[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_CHARACTERTYPE_LIST, {}, (response: CharacterType[]) => {
|
||||
assetManagerStore.setCharacterTypeList(response)
|
||||
|
||||
if (unsetSelectedCharacterType) {
|
||||
@ -103,7 +104,7 @@ function saveCharacterType() {
|
||||
spriteId: characterSpriteId.value
|
||||
}
|
||||
|
||||
gameStore.connection?.emit('gm:characterType:update', characterTypeData, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_CHARACTERTYPE_UPDATE, characterTypeData, (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to save character type')
|
||||
return
|
||||
@ -124,7 +125,7 @@ watch(selectedCharacterType, (characterType: CharacterType | null) => {
|
||||
onMounted(() => {
|
||||
if (!selectedCharacterType.value) return
|
||||
|
||||
gameStore.connection?.emit('gm:sprite:list', {}, (response: Sprite[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_SPRITE_LIST, {}, (response: Sprite[]) => {
|
||||
assetManagerStore.setSpriteList(response)
|
||||
})
|
||||
})
|
||||
|
@ -32,6 +32,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { CharacterType } from '@/application/types'
|
||||
import { useAssetManagerStore } from '@/stores/assetManagerStore'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
@ -52,13 +53,13 @@ const handleSearch = () => {
|
||||
}
|
||||
|
||||
const createNewCharacterType = () => {
|
||||
gameStore.connection?.emit('gm:characterType:create', {}, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_CHARACTERTYPE_CREATE, {}, (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to create new character type')
|
||||
return
|
||||
}
|
||||
|
||||
gameStore.connection?.emit('gm:characterType:list', {}, (response: CharacterType[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_CHARACTERTYPE_LIST, {}, (response: CharacterType[]) => {
|
||||
assetManagerStore.setCharacterTypeList(response)
|
||||
})
|
||||
})
|
||||
@ -92,7 +93,7 @@ function toTop() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
gameStore.connection?.emit('gm:characterType:list', {}, (response: CharacterType[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_CHARACTERTYPE_LIST, {}, (response: CharacterType[]) => {
|
||||
assetManagerStore.setCharacterTypeList(response)
|
||||
})
|
||||
})
|
||||
|
@ -44,6 +44,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { Item, ItemRarity, ItemType, Sprite } from '@/application/types'
|
||||
import { useAssetManagerStore } from '@/stores/assetManagerStore'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
@ -80,7 +81,7 @@ if (selectedItem.value) {
|
||||
function removeItem() {
|
||||
if (!selectedItem.value) return
|
||||
|
||||
gameStore.connection?.emit('gm:item:remove', { id: selectedItem.value.id }, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_ITEM_REMOVE, { id: selectedItem.value.id }, (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to remove item')
|
||||
return
|
||||
@ -90,7 +91,7 @@ function removeItem() {
|
||||
}
|
||||
|
||||
function refreshItemList(unsetSelectedItem = true) {
|
||||
gameStore.connection?.emit('gm:item:list', {}, (response: Item[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_ITEM_LIST, {}, (response: Item[]) => {
|
||||
assetManagerStore.setItemList(response)
|
||||
|
||||
if (unsetSelectedItem) {
|
||||
@ -110,7 +111,7 @@ function saveItem() {
|
||||
spriteId: itemSpriteId.value
|
||||
}
|
||||
|
||||
gameStore.connection?.emit('gm:item:update', itemData, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_ITEM_UPDATE, itemData, (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to save item')
|
||||
return
|
||||
@ -132,7 +133,7 @@ watch(selectedItem, (item: Item | null) => {
|
||||
onMounted(() => {
|
||||
if (!selectedItem.value) return
|
||||
|
||||
gameStore.connection?.emit('gm:sprite:list', {}, (response: Sprite[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_SPRITE_LIST, {}, (response: Sprite[]) => {
|
||||
assetManagerStore.setSpriteList(response)
|
||||
})
|
||||
})
|
||||
|
@ -29,6 +29,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { Item } from '@/application/types'
|
||||
import { useAssetManagerStore } from '@/stores/assetManagerStore'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
@ -48,13 +49,13 @@ const handleSearch = () => {
|
||||
}
|
||||
|
||||
const createNewItem = () => {
|
||||
gameStore.connection?.emit('gm:item:create', {}, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_ITEM_CREATE, {}, (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to create new item')
|
||||
return
|
||||
}
|
||||
|
||||
gameStore.connection?.emit('gm:item:list', {}, (response: Item[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_ITEM_LIST, {}, (response: Item[]) => {
|
||||
assetManagerStore.setItemList(response)
|
||||
})
|
||||
})
|
||||
@ -88,7 +89,7 @@ function toTop() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
gameStore.connection?.emit('gm:item:list', {}, (response: Item[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_ITEM_LIST, {}, (response: Item[]) => {
|
||||
assetManagerStore.setItemList(response)
|
||||
})
|
||||
})
|
||||
|
@ -44,6 +44,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import config from '@/application/config'
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { MapObject } from '@/application/types'
|
||||
import ChipsInput from '@/components/forms/ChipsInput.vue'
|
||||
import { useAssetManagerStore } from '@/stores/assetManagerStore'
|
||||
@ -78,7 +79,7 @@ if (selectedMapObject.value) {
|
||||
}
|
||||
|
||||
function removeObject() {
|
||||
gameStore.connection?.emit('gm:mapObject:remove', { mapObject: selectedMapObject.value?.id }, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_MAPOBJECT_REMOVE, { mapObject: selectedMapObject.value?.id }, (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to remove mapObject')
|
||||
return
|
||||
@ -88,7 +89,7 @@ function removeObject() {
|
||||
}
|
||||
|
||||
function refreshObjectList(unsetSelectedMapObject = true) {
|
||||
gameStore.connection?.emit('gm:mapObject:list', {}, (response: MapObject[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_MAPOBJECT_LIST, {}, (response: MapObject[]) => {
|
||||
assetManagerStore.setMapObjectList(response)
|
||||
|
||||
if (unsetSelectedMapObject) {
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import config from '@/application/config'
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { MapObject } from '@/application/types'
|
||||
import { useAssetManagerStore } from '@/stores/assetManagerStore'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
@ -47,13 +48,13 @@ const elementToScroll = ref()
|
||||
const handleFileUpload = (e: Event) => {
|
||||
const files = (e.target as HTMLInputElement).files
|
||||
if (!files) return
|
||||
gameStore.connection?.emit('gm:mapObject:upload', files, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_MAPOBJECT_UPLOAD, files, (response: boolean) => {
|
||||
if (!response) {
|
||||
if (config.environment === 'development') console.error('Failed to upload map object')
|
||||
return
|
||||
}
|
||||
|
||||
gameStore.connection?.emit('gm:mapObject:list', {}, (response: MapObject[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_MAPOBJECT_LIST, {}, (response: MapObject[]) => {
|
||||
assetManagerStore.setMapObjectList(response)
|
||||
})
|
||||
})
|
||||
@ -92,7 +93,7 @@ function toTop() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
gameStore.connection?.emit('gm:mapObject:list', {}, (response: MapObject[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_MAPOBJECT_LIST, {}, (response: MapObject[]) => {
|
||||
assetManagerStore.setMapObjectList(response)
|
||||
})
|
||||
})
|
||||
|
@ -68,6 +68,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { Sprite, SpriteAction, UUID } from '@/application/types'
|
||||
import { uuidv4 } from '@/application/utilities'
|
||||
import SpriteActionsInput from '@/components/gameMaster/assetManager/partials/sprite/partials/SpriteImagesInput.vue'
|
||||
@ -97,7 +98,7 @@ if (selectedSprite.value) {
|
||||
}
|
||||
|
||||
function deleteSprite() {
|
||||
gameStore.connection?.emit('gm:sprite:delete', { id: selectedSprite.value?.id }, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_SPRITE_DELETE, { id: selectedSprite.value?.id }, (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to delete sprite')
|
||||
return
|
||||
@ -107,7 +108,7 @@ function deleteSprite() {
|
||||
}
|
||||
|
||||
function copySprite() {
|
||||
gameStore.connection?.emit('gm:sprite:copy', { id: selectedSprite.value?.id }, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_SPRITE_COPY, { id: selectedSprite.value?.id }, (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to copy sprite')
|
||||
return
|
||||
@ -117,7 +118,7 @@ function copySprite() {
|
||||
}
|
||||
|
||||
function refreshSpriteList(unsetSelectedSprite = true) {
|
||||
gameStore.connection?.emit('gm:sprite:list', {}, (response: Sprite[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_SPRITE_LIST, {}, (response: Sprite[]) => {
|
||||
assetManagerStore.setSpriteList(response)
|
||||
|
||||
if (unsetSelectedSprite) {
|
||||
@ -149,7 +150,7 @@ function saveSprite() {
|
||||
}) ?? []
|
||||
}
|
||||
|
||||
gameStore.connection?.emit('gm:sprite:update', updatedSprite, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_SPRITE_UPDATE, updatedSprite, (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to save sprite')
|
||||
return
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import config from '@/application/config'
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { Sprite } from '@/application/types'
|
||||
import { useAssetManagerStore } from '@/stores/assetManagerStore'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
@ -40,13 +41,13 @@ const hasScrolled = ref(false)
|
||||
const elementToScroll = ref()
|
||||
|
||||
function newButtonClickHandler() {
|
||||
gameStore.connection?.emit('gm:sprite:create', {}, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_SPRITE_CREATE, {}, (response: boolean) => {
|
||||
if (!response) {
|
||||
if (config.environment === 'development') console.error('Failed to create new sprite')
|
||||
return
|
||||
}
|
||||
|
||||
gameStore.connection?.emit('gm:sprite:list', {}, (response: Sprite[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_SPRITE_LIST, {}, (response: Sprite[]) => {
|
||||
assetManagerStore.setSpriteList(response)
|
||||
})
|
||||
})
|
||||
@ -85,7 +86,7 @@ function toTop() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
gameStore.connection?.emit('gm:sprite:list', {}, (response: Sprite[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_SPRITE_LIST, {}, (response: Sprite[]) => {
|
||||
assetManagerStore.setSpriteList(response)
|
||||
})
|
||||
})
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import config from '@/application/config'
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { Tile } from '@/application/types'
|
||||
import ChipsInput from '@/components/forms/ChipsInput.vue'
|
||||
import { TileStorage } from '@/storage/storages'
|
||||
@ -56,7 +57,7 @@ watch(selectedTile, (tile: Tile | null) => {
|
||||
})
|
||||
|
||||
async function deleteTile() {
|
||||
gameStore.connection?.emit('gm:tile:delete', { id: selectedTile.value?.id }, async (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_TILE_DELETE, { id: selectedTile.value?.id }, async (response: boolean) => {
|
||||
if (!response) {
|
||||
console.error('Failed to delete tile')
|
||||
return
|
||||
@ -67,7 +68,7 @@ async function deleteTile() {
|
||||
}
|
||||
|
||||
function refreshTileList(unsetSelectedTile = true) {
|
||||
gameStore.connection?.emit('gm:tile:list', {}, (response: Tile[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_TILE_LIST, {}, (response: Tile[]) => {
|
||||
assetManagerStore.setTileList(response)
|
||||
|
||||
if (unsetSelectedTile) {
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import config from '@/application/config'
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { Tile } from '@/application/types'
|
||||
import { useAssetManagerStore } from '@/stores/assetManagerStore'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
@ -47,13 +48,13 @@ const elementToScroll = ref()
|
||||
const handleFileUpload = (e: Event) => {
|
||||
const files = (e.target as HTMLInputElement).files
|
||||
if (!files) return
|
||||
gameStore.connection?.emit('gm:tile:upload', files, (response: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_TILE_UPLOAD, files, (response: boolean) => {
|
||||
if (!response) {
|
||||
if (config.environment === 'development') console.error('Failed to upload tile')
|
||||
return
|
||||
}
|
||||
|
||||
gameStore.connection?.emit('gm:tile:list', {}, (response: Tile[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_TILE_LIST, {}, (response: Tile[]) => {
|
||||
assetManagerStore.setTileList(response)
|
||||
})
|
||||
})
|
||||
@ -92,7 +93,7 @@ function toTop() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
gameStore.connection?.emit('gm:tile:list', {}, (response: Tile[]) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_TILE_LIST, {}, (response: Tile[]) => {
|
||||
assetManagerStore.setTileList(response)
|
||||
})
|
||||
})
|
||||
|
@ -35,6 +35,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { Map } from '@/application/types'
|
||||
import Modal from '@/components/utilities/Modal.vue'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
@ -56,7 +57,7 @@ const pvp = ref(false)
|
||||
defineExpose({ open: () => modalRef.value?.open() })
|
||||
|
||||
async function submit() {
|
||||
gameStore.connection?.emit('gm:map:create', { name: name.value, width: width.value, height: height.value }, async (response: Map | false) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_MAP_CREATE, { name: name.value, width: width.value, height: height.value }, async (response: Map | false) => {
|
||||
if (!response) {
|
||||
return
|
||||
}
|
||||
|
@ -29,13 +29,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Map, UUID } from '@/application/types'
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { Map } from '@/application/types'
|
||||
import CreateMap from '@/components/gameMaster/mapEditor/partials/CreateMap.vue'
|
||||
import Modal from '@/components/utilities/Modal.vue'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { MapStorage } from '@/storage/storages'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { onMounted, ref, useTemplateRef } from 'vue'
|
||||
|
||||
const gameStore = useGameStore()
|
||||
@ -60,15 +60,15 @@ async function fetchMaps() {
|
||||
mapList.value = await mapStorage.getAll()
|
||||
}
|
||||
|
||||
function loadMap(id: UUID) {
|
||||
gameStore.connection?.emit('gm:map:request', { mapId: id }, (response: Map) => {
|
||||
function loadMap(id: string) {
|
||||
gameStore.connection?.emit(SocketEvent.GM_MAP_REQUEST, { mapId: id }, (response: Map) => {
|
||||
mapEditor.loadMap(response)
|
||||
})
|
||||
modalRef.value?.close()
|
||||
}
|
||||
|
||||
async function deleteMap(id: UUID) {
|
||||
gameStore.connection?.emit('gm:map:delete', { mapId: id }, async (response: boolean) => {
|
||||
async function deleteMap(id: string) {
|
||||
gameStore.connection?.emit(SocketEvent.GM_MAP_DELETE, { mapId: id }, async (response: boolean) => {
|
||||
if (!response) {
|
||||
gameStore.addNotification({
|
||||
title: 'Error',
|
||||
|
@ -47,6 +47,7 @@ import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { MapObjectStorage } from '@/storage/storages'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import {SocketEvent} from "@/application/enums";
|
||||
|
||||
const props = defineProps<{
|
||||
placedMapObject: PlacedMapObject
|
||||
@ -81,7 +82,7 @@ async function handleUpdate() {
|
||||
if (!mapObject.value) return
|
||||
|
||||
gameStore.connection?.emit(
|
||||
'gm:mapObject:update',
|
||||
SocketEvent.GM_MAPOBJECT_UPDATE,
|
||||
{
|
||||
id: props.placedMapObject.mapObject as string,
|
||||
name: mapObjectName.value,
|
||||
|
@ -39,6 +39,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { Map } from '@/application/types'
|
||||
import Modal from '@/components/utilities/Modal.vue'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
@ -58,9 +59,9 @@ defineExpose({
|
||||
onMounted(fetchMaps)
|
||||
|
||||
function fetchMaps() {
|
||||
gameStore.connection?.emit('gm:map:list', {}, (response: Map[]) => {
|
||||
mapList.value = response
|
||||
})
|
||||
// gameStore.connection?.emit(SocketEvent.GM_MAP_LIST, {}, (response: Map[]) => {
|
||||
// mapList.value = response
|
||||
// })
|
||||
}
|
||||
|
||||
const { toPositionX, toPositionY, toRotation, toMap } = useRefTeleportSettings()
|
||||
|
@ -122,6 +122,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import config from '@/application/config'
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import { type CharacterHair, type Character as CharacterT, type Map } from '@/application/types'
|
||||
import Modal from '@/components/utilities/Modal.vue'
|
||||
import { useSoundComposable } from '@/composables/useSoundComposable'
|
||||
@ -141,10 +142,11 @@ const selectedHairId = ref<string | null>(null)
|
||||
|
||||
// Fetch characters
|
||||
setTimeout(() => {
|
||||
gameStore.connection?.emit('character:list')
|
||||
console.log(SocketEvent.CHARACTER_LIST)
|
||||
gameStore.connection?.emit(SocketEvent.CHARACTER_LIST)
|
||||
}, 750)
|
||||
|
||||
gameStore.connection?.on('character:list', (data: any) => {
|
||||
gameStore.connection?.on(SocketEvent.CHARACTER_LIST, (data: any) => {
|
||||
characters.value = data
|
||||
isLoading.value = false
|
||||
})
|
||||
@ -154,7 +156,7 @@ function loginWithCharacter() {
|
||||
if (!selectedCharacterId.value) return
|
||||
|
||||
gameStore.connection?.emit(
|
||||
'character:connect',
|
||||
SocketEvent.CHARACTER_CONNECT,
|
||||
{
|
||||
characterId: selectedCharacterId.value,
|
||||
characterHairId: selectedHairId.value
|
||||
@ -167,7 +169,7 @@ function loginWithCharacter() {
|
||||
|
||||
// Create character logics
|
||||
function createCharacter() {
|
||||
gameStore.connection?.emit('character:create', { name: newCharacterName.value }, (success: boolean) => {
|
||||
gameStore.connection?.emit(SocketEvent.CHARACTER_CREATE, { name: newCharacterName.value }, (success: boolean) => {
|
||||
if (success) return
|
||||
isCreateNewCharacterModalOpen.value = false
|
||||
})
|
||||
@ -176,7 +178,7 @@ function createCharacter() {
|
||||
// Watch changes for selected character and update hairs
|
||||
watch(selectedCharacterId, (characterId) => {
|
||||
if (!characterId) return
|
||||
// selectedHairId.value = characters.value.find((c) => c.id == characterId)?.characterHairId ?? null
|
||||
selectedHairId.value = characters.value.find((c) => c.id == characterId)?.characterHair ?? null
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
@ -186,8 +188,8 @@ onMounted(async () => {
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
gameStore.connection?.off('character:list')
|
||||
gameStore.connection?.off('character:connect')
|
||||
gameStore.connection?.off('character:create:success')
|
||||
gameStore.connection?.off(SocketEvent.CHARACTER_LIST)
|
||||
gameStore.connection?.off(SocketEvent.CHARACTER_CONNECT)
|
||||
gameStore.connection?.off(SocketEvent.CHARACTER_CREATE)
|
||||
})
|
||||
</script>
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import config from '@/application/config'
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import 'phaser'
|
||||
import type { Map as MapT } from '@/application/types'
|
||||
import Map from '@/components/gameMaster/mapEditor/Map.vue'
|
||||
@ -91,7 +92,7 @@ function save() {
|
||||
mapId: currentMap.id
|
||||
}
|
||||
|
||||
gameStore.connection?.emit('gm:map:update', data, (response: MapT) => {
|
||||
gameStore.connection?.emit(SocketEvent.GM_MAP_UPDATE, data, (response: MapT) => {
|
||||
mapStorage.update(response.id, response)
|
||||
})
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import Modal from '@/components/utilities/Modal.vue'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { onBeforeMount, onBeforeUnmount, onMounted, onUnmounted, watch } from 'vue'
|
||||
@ -26,7 +27,7 @@ type Notification = {
|
||||
}
|
||||
|
||||
function setupNotificationListener(connection: any) {
|
||||
connection.on('notification', (data: Notification) => {
|
||||
connection.on(SocketEvent.NOTIFICATION, (data: Notification) => {
|
||||
gameStore.addNotification({
|
||||
title: data.title,
|
||||
message: data.message
|
||||
@ -52,7 +53,7 @@ onMounted(() => {
|
||||
onUnmounted(() => {
|
||||
const connection = gameStore.connection
|
||||
if (connection) {
|
||||
connection.off('notification')
|
||||
connection.off(SocketEvent.NOTIFICATION)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import { getTile } from '@/services/mapService'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import type { Ref } from 'vue'
|
||||
@ -22,7 +23,7 @@ export function useGameControlsComposable(scene: Phaser.Scene, layer: Phaser.Til
|
||||
const pointerTile = getTile(layer, pointer.worldX, pointer.worldY)
|
||||
if (!pointerTile) return
|
||||
|
||||
gameStore.connection?.emit('map:character:move', {
|
||||
gameStore.connection?.emit(SocketEvent.MAP_CHARACTER_MOVE, {
|
||||
positionX: pointerTile.x,
|
||||
positionY: pointerTile.y
|
||||
})
|
||||
@ -37,7 +38,7 @@ export function useGameControlsComposable(scene: Phaser.Scene, layer: Phaser.Til
|
||||
if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.key)) {
|
||||
// Prevent key repeat events
|
||||
if (event.repeat) return
|
||||
|
||||
|
||||
pressedKeys.add(event.key)
|
||||
|
||||
// Start movement loop if not already running
|
||||
@ -49,7 +50,7 @@ export function useGameControlsComposable(scene: Phaser.Scene, layer: Phaser.Til
|
||||
|
||||
// Attack on CTRL
|
||||
if (event.key === 'Control') {
|
||||
gameStore.connection?.emit('map:character:attack')
|
||||
gameStore.connection?.emit(SocketEvent.MAP_CHARACTER_ATTACK)
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,9 +66,6 @@ export function useGameControlsComposable(scene: Phaser.Scene, layer: Phaser.Til
|
||||
|
||||
function moveCharacter() {
|
||||
if (!gameStore.character) return
|
||||
|
||||
// Don't allow movement while attacking
|
||||
if (gameStore.character.isAttacking) return
|
||||
|
||||
const { positionX, positionY } = gameStore.character
|
||||
let newX = positionX
|
||||
@ -81,7 +79,7 @@ export function useGameControlsComposable(scene: Phaser.Scene, layer: Phaser.Til
|
||||
|
||||
// Only emit if position changed
|
||||
if (newX !== positionX || newY !== positionY) {
|
||||
gameStore.connection?.emit('map:character:move', {
|
||||
gameStore.connection?.emit(SocketEvent.MAP_CHARACTER_MOVE, {
|
||||
positionX: newX,
|
||||
positionY: newY
|
||||
})
|
||||
|
@ -18,7 +18,7 @@ export function useCharacterSpriteComposable(scene: Phaser.Scene, tilemap: Phase
|
||||
const tween = ref<Phaser.Tweens.Tween | null>(null)
|
||||
|
||||
const updateIsometricDepth = (positionX: number, positionY: number) => {
|
||||
isometricDepth.value = calculateIsometricDepth(positionX, positionY, 30, 95, true)
|
||||
isometricDepth.value = calculateIsometricDepth(positionX, positionY, 30, 95)
|
||||
}
|
||||
|
||||
const updatePosition = (positionX: number, positionY: number) => {
|
||||
|
@ -62,13 +62,18 @@ export function createTileArray(width: number, height: number, tile: string = 'b
|
||||
return Array.from({ length: height }, () => Array.from({ length: width }, () => tile))
|
||||
}
|
||||
|
||||
export const calculateIsometricDepth = (positionX: number, positionY: number, width: number = 0, height: number = 0, isCharacter: boolean = false) => {
|
||||
const baseDepth = positionX + positionY
|
||||
if (isCharacter) {
|
||||
return baseDepth
|
||||
}
|
||||
return baseDepth + (width + height) / (2 * config.tile_size.width)
|
||||
}
|
||||
export const calculateIsometricDepth = (
|
||||
positionX: number,
|
||||
positionY: number,
|
||||
objectWidth: number = 0,
|
||||
objectHeight: number = 0
|
||||
): number => {
|
||||
const tileWidth = config.tile_size.width;
|
||||
const tileHeight = config.tile_size.height;
|
||||
const tileSize = Math.max(tileWidth, tileHeight);
|
||||
const objectSize = Math.max(objectWidth, objectHeight);
|
||||
return Math.floor(positionY * tileSize + positionX * objectSize);
|
||||
};
|
||||
|
||||
async function loadTileTextures(tiles: TileT[], scene: Phaser.Scene) {
|
||||
// Load each tile into the scene
|
||||
|
@ -1,4 +1,5 @@
|
||||
import config from '@/application/config'
|
||||
import { SocketEvent } from '@/application/enums'
|
||||
import type { Character, Notification, User, WorldSettings } from '@/application/types'
|
||||
import { useCookies } from '@vueuse/integrations/useCookies'
|
||||
import { defineStore } from 'pinia'
|
||||
@ -85,10 +86,10 @@ export const useGameStore = defineStore('game', {
|
||||
})
|
||||
|
||||
// Let the server know the user is logged in
|
||||
this.connection.emit('login')
|
||||
this.connection.emit(SocketEvent.LOGIN)
|
||||
|
||||
// set user
|
||||
this.connection.on('logged_in', (user: User) => {
|
||||
this.connection.on(SocketEvent.LOGGED_IN, (user: User) => {
|
||||
this.setUser(user)
|
||||
})
|
||||
|
||||
@ -98,7 +99,7 @@ export const useGameStore = defineStore('game', {
|
||||
})
|
||||
|
||||
// Listen for new date from socket
|
||||
this.connection.on('date', (data: Date) => {
|
||||
this.connection.on(SocketEvent.DATE, (data: Date) => {
|
||||
this.world.date = new Date(data)
|
||||
})
|
||||
},
|
||||
@ -106,7 +107,7 @@ export const useGameStore = defineStore('game', {
|
||||
// Remove event listeners
|
||||
this.connection?.off('connect_error')
|
||||
this.connection?.off('reconnect_failed')
|
||||
this.connection?.off('date')
|
||||
this.connection?.off(SocketEvent.DATE)
|
||||
this.connection?.disconnect()
|
||||
|
||||
useCookies().remove('token', {
|
||||
|
@ -6,7 +6,6 @@ export const useMapStore = defineStore('map', {
|
||||
return {
|
||||
mapId: '',
|
||||
characters: [] as MapCharacter[],
|
||||
characterLoaded: false
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
@ -36,9 +35,6 @@ export const useMapStore = defineStore('map', {
|
||||
removeCharacter(characterId: UUID) {
|
||||
this.characters = this.characters.filter((char) => char.character.id !== characterId)
|
||||
},
|
||||
setCharacterLoaded(loaded: boolean) {
|
||||
this.characterLoaded = loaded
|
||||
},
|
||||
updateCharacterPosition(data: { characterId: UUID; positionX: number; positionY: number; rotation: number; isMoving: boolean }) {
|
||||
const character = this.characters.find((char) => char.character.id === data.characterId)
|
||||
if (character) {
|
||||
@ -51,7 +47,6 @@ export const useMapStore = defineStore('map', {
|
||||
reset() {
|
||||
this.mapId = ''
|
||||
this.characters = []
|
||||
this.characterLoaded = false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -2,6 +2,7 @@ import { fileURLToPath, URL } from 'node:url'
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import viteCompression from 'vite-plugin-compression';
|
||||
import {ViteImageOptimizer} from "vite-plugin-image-optimizer";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
@ -11,7 +12,8 @@ export default defineConfig({
|
||||
algorithm: 'gzip',
|
||||
ext: '.gz',
|
||||
threshold: 10240 // Only compress files larger than 10KB
|
||||
})
|
||||
}),
|
||||
ViteImageOptimizer()
|
||||
],
|
||||
build: {
|
||||
minify: 'terser', // Better minification
|
||||
|
Loading…
x
Reference in New Issue
Block a user