forked from noxious/client
Several fixes, improvements, refactor for authentication
This commit is contained in:
parent
9d0f810ab3
commit
18b07d2f46
6
package-lock.json
generated
6
package-lock.json
generated
@ -3690,9 +3690,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/es-module-lexer": {
|
"node_modules/es-module-lexer": {
|
||||||
"version": "1.5.4",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz",
|
||||||
"integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==",
|
"integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
@ -21,7 +21,7 @@ export type AssetDataT = {
|
|||||||
frameRate?: number
|
frameRate?: number
|
||||||
frameWidth?: number
|
frameWidth?: number
|
||||||
frameHeight?: number
|
frameHeight?: number
|
||||||
frameRate?: number
|
frameCount?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Tile = {
|
export type Tile = {
|
||||||
|
@ -55,20 +55,23 @@ const initializeEffects = (scene: Phaser.Scene) => {
|
|||||||
effects.light.value = scene.add.graphics().setDepth(1000)
|
effects.light.value = scene.add.graphics().setDepth(1000)
|
||||||
|
|
||||||
// Rain
|
// Rain
|
||||||
effects.rain.value = scene.add.particles(0, 0, 'raindrop', {
|
effects.rain.value = scene.add
|
||||||
x: { min: 0, max: window.innerWidth },
|
.particles(0, 0, 'raindrop', {
|
||||||
y: -50,
|
x: { min: 0, max: window.innerWidth },
|
||||||
quantity: 5,
|
y: -50,
|
||||||
lifespan: 2000,
|
quantity: 5,
|
||||||
speedY: { min: 300, max: 500 },
|
lifespan: 2000,
|
||||||
scale: { start: 0.005, end: 0.005 },
|
speedY: { min: 300, max: 500 },
|
||||||
alpha: { start: 0.5, end: 0 },
|
scale: { start: 0.005, end: 0.005 },
|
||||||
blendMode: 'ADD'
|
alpha: { start: 0.5, end: 0 },
|
||||||
}).setDepth(900)
|
blendMode: 'ADD'
|
||||||
|
})
|
||||||
|
.setDepth(900)
|
||||||
effects.rain.value.stop()
|
effects.rain.value.stop()
|
||||||
|
|
||||||
// Fog
|
// Fog
|
||||||
effects.fog.value = scene.add.sprite(window.innerWidth / 2, window.innerHeight / 2, 'fog')
|
effects.fog.value = scene.add
|
||||||
|
.sprite(window.innerWidth / 2, window.innerHeight / 2, 'fog')
|
||||||
.setScale(2)
|
.setScale(2)
|
||||||
.setAlpha(0)
|
.setAlpha(0)
|
||||||
.setDepth(950)
|
.setDepth(950)
|
||||||
@ -77,10 +80,13 @@ const initializeEffects = (scene: Phaser.Scene) => {
|
|||||||
// Effect updates
|
// Effect updates
|
||||||
const updateScene = () => {
|
const updateScene = () => {
|
||||||
const timeBasedLight = calculateLightStrength(gameStore.world.date)
|
const timeBasedLight = calculateLightStrength(gameStore.world.date)
|
||||||
const zoneEffects = zoneStore.zone?.zoneEffects?.reduce((acc, curr) => ({
|
const zoneEffects = zoneStore.zone?.zoneEffects?.reduce(
|
||||||
...acc,
|
(acc, curr) => ({
|
||||||
[curr.effect]: curr.strength
|
...acc,
|
||||||
}), {}) as { [key: string]: number }
|
[curr.effect]: curr.strength
|
||||||
|
}),
|
||||||
|
{}
|
||||||
|
) as { [key: string]: number }
|
||||||
|
|
||||||
// Only update effects once zoneEffects are loaded
|
// Only update effects once zoneEffects are loaded
|
||||||
if (!zoneEffectsReady.value) {
|
if (!zoneEffectsReady.value) {
|
||||||
@ -91,13 +97,14 @@ const updateScene = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const finalEffects = zoneEffects && Object.keys(zoneEffects).length
|
const finalEffects =
|
||||||
? zoneEffects
|
zoneEffects && Object.keys(zoneEffects).length
|
||||||
: {
|
? zoneEffects
|
||||||
light: timeBasedLight,
|
: {
|
||||||
rain: weatherState.value.isRainEnabled ? weatherState.value.rainPercentage : 0,
|
light: timeBasedLight,
|
||||||
fog: weatherState.value.isFogEnabled ? weatherState.value.fogDensity * 100 : 0
|
rain: weatherState.value.isRainEnabled ? weatherState.value.rainPercentage : 0,
|
||||||
}
|
fog: weatherState.value.isFogEnabled ? weatherState.value.fogDensity * 100 : 0
|
||||||
|
}
|
||||||
|
|
||||||
applyEffects(finalEffects)
|
applyEffects(finalEffects)
|
||||||
}
|
}
|
||||||
@ -105,16 +112,12 @@ const updateScene = () => {
|
|||||||
const applyEffects = (effectValues: any) => {
|
const applyEffects = (effectValues: any) => {
|
||||||
if (effects.light.value) {
|
if (effects.light.value) {
|
||||||
const darkness = 1 - (effectValues.light ?? 100) / 100
|
const darkness = 1 - (effectValues.light ?? 100) / 100
|
||||||
effects.light.value.clear()
|
effects.light.value.clear().fillStyle(0x000000, darkness).fillRect(0, 0, window.innerWidth, window.innerHeight)
|
||||||
.fillStyle(0x000000, darkness)
|
|
||||||
.fillRect(0, 0, window.innerWidth, window.innerHeight)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (effects.rain.value) {
|
if (effects.rain.value) {
|
||||||
const strength = effectValues.rain ?? 0
|
const strength = effectValues.rain ?? 0
|
||||||
strength > 0
|
strength > 0 ? effects.rain.value.start().setQuantity(Math.floor((strength / 100) * 10)) : effects.rain.value.stop()
|
||||||
? effects.rain.value.start().setQuantity(Math.floor((strength / 100) * 10))
|
|
||||||
: effects.rain.value.stop()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (effects.fog.value) {
|
if (effects.fog.value) {
|
||||||
@ -126,19 +129,14 @@ const calculateLightStrength = (time: Date): number => {
|
|||||||
const hour = time.getHours()
|
const hour = time.getHours()
|
||||||
const minute = time.getMinutes()
|
const minute = time.getMinutes()
|
||||||
|
|
||||||
if (hour >= LIGHT_CONFIG.SUNSET_HOUR || hour < LIGHT_CONFIG.SUNRISE_HOUR)
|
if (hour >= LIGHT_CONFIG.SUNSET_HOUR || hour < LIGHT_CONFIG.SUNRISE_HOUR) return LIGHT_CONFIG.NIGHT_STRENGTH
|
||||||
return LIGHT_CONFIG.NIGHT_STRENGTH
|
|
||||||
|
|
||||||
if (hour > LIGHT_CONFIG.SUNRISE_HOUR && hour < LIGHT_CONFIG.SUNSET_HOUR - 2)
|
if (hour > LIGHT_CONFIG.SUNRISE_HOUR && hour < LIGHT_CONFIG.SUNSET_HOUR - 2) return LIGHT_CONFIG.DAY_STRENGTH
|
||||||
return LIGHT_CONFIG.DAY_STRENGTH
|
|
||||||
|
|
||||||
if (hour === LIGHT_CONFIG.SUNRISE_HOUR)
|
if (hour === LIGHT_CONFIG.SUNRISE_HOUR) return LIGHT_CONFIG.NIGHT_STRENGTH + ((LIGHT_CONFIG.DAY_STRENGTH - LIGHT_CONFIG.NIGHT_STRENGTH) * minute) / 60
|
||||||
return LIGHT_CONFIG.NIGHT_STRENGTH +
|
|
||||||
((LIGHT_CONFIG.DAY_STRENGTH - LIGHT_CONFIG.NIGHT_STRENGTH) * minute) / 60
|
|
||||||
|
|
||||||
const totalMinutes = (hour - (LIGHT_CONFIG.SUNSET_HOUR - 2)) * 60 + minute
|
const totalMinutes = (hour - (LIGHT_CONFIG.SUNSET_HOUR - 2)) * 60 + minute
|
||||||
return LIGHT_CONFIG.DAY_STRENGTH -
|
return LIGHT_CONFIG.DAY_STRENGTH - (LIGHT_CONFIG.DAY_STRENGTH - LIGHT_CONFIG.NIGHT_STRENGTH) * (totalMinutes / 120)
|
||||||
(LIGHT_CONFIG.DAY_STRENGTH - LIGHT_CONFIG.NIGHT_STRENGTH) * (totalMinutes / 120)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Socket and window handlers
|
// Socket and window handlers
|
||||||
@ -157,17 +155,19 @@ const setupSocketListeners = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleResize = () => {
|
const handleResize = () => {
|
||||||
if (effects.rain.value)
|
if (effects.rain.value) effects.rain.value.updateConfig({ x: { min: 0, max: window.innerWidth } })
|
||||||
effects.rain.value.updateConfig({ x: { min: 0, max: window.innerWidth } })
|
if (effects.fog.value) effects.fog.value.setPosition(window.innerWidth / 2, window.innerHeight / 2)
|
||||||
if (effects.fog.value)
|
|
||||||
effects.fog.value.setPosition(window.innerWidth / 2, window.innerHeight / 2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lifecycle
|
// Lifecycle
|
||||||
watch(() => zoneStore.zone, () => {
|
watch(
|
||||||
zoneEffectsReady.value = false
|
() => zoneStore.zone,
|
||||||
updateScene()
|
() => {
|
||||||
}, { deep: true })
|
zoneEffectsReady.value = false
|
||||||
|
updateScene()
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
onMounted(() => window.addEventListener('resize', handleResize))
|
onMounted(() => window.addEventListener('resize', handleResize))
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<Healthbar :zoneCharacter="props.zoneCharacter" :currentX="currentX" :currentY="currentY" />
|
<Healthbar :zoneCharacter="props.zoneCharacter" :currentX="currentX" :currentY="currentY" />
|
||||||
<Container ref="charContainer" :depth="isometricDepth" :x="currentX" :y="currentY">
|
<Container ref="charContainer" :depth="isometricDepth" :x="currentX" :y="currentY">
|
||||||
<CharacterHair :zoneCharacter="props.zoneCharacter" :currentX="currentX" :currentY="currentY" />
|
<CharacterHair :zoneCharacter="props.zoneCharacter" :currentX="currentX" :currentY="currentY" />
|
||||||
<!-- <CharacterChest :zoneCharacter="props.zoneCharacter" :currentX="currentX" :currentY="currentY" />-->
|
<!-- <CharacterChest :zoneCharacter="props.zoneCharacter" :currentX="currentX" :currentY="currentY" />-->
|
||||||
<Sprite ref="charSprite" :origin-y="1" :flipX="isFlippedX" />
|
<Sprite ref="charSprite" :origin-y="1" :flipX="isFlippedX" />
|
||||||
</Container>
|
</Container>
|
||||||
</template>
|
</template>
|
||||||
|
@ -31,16 +31,14 @@ const isFlippedX = computed(() => [6, 4].includes(props.zoneCharacter.character.
|
|||||||
const imageProps = computed(() => {
|
const imageProps = computed(() => {
|
||||||
// Get the current sprite action based on direction
|
// Get the current sprite action based on direction
|
||||||
const direction = [0, 6].includes(props.zoneCharacter.character.rotation ?? 0) ? 'back' : 'front'
|
const direction = [0, 6].includes(props.zoneCharacter.character.rotation ?? 0) ? 'back' : 'front'
|
||||||
const spriteAction = props.zoneCharacter.character.characterHair?.sprite?.spriteActions?.find(
|
const spriteAction = props.zoneCharacter.character.characterHair?.sprite?.spriteActions?.find((spriteAction) => spriteAction.action === direction)
|
||||||
spriteAction => spriteAction.action === direction
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
depth: 1,
|
depth: 1,
|
||||||
originX: Number(spriteAction?.originX) ?? 0,
|
originX: Number(spriteAction?.originX) ?? 0,
|
||||||
originY: Number(spriteAction?.originY) ?? 0,
|
originY: Number(spriteAction?.originY) ?? 0,
|
||||||
flipX: isFlippedX.value,
|
flipX: isFlippedX.value,
|
||||||
texture: texture.value,
|
texture: texture.value
|
||||||
// y: props.zoneCharacter.isMoving ? Math.floor(Date.now() / 250) % 2 : 0
|
// y: props.zoneCharacter.isMoving ? Math.floor(Date.now() / 250) % 2 : 0
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -31,9 +31,7 @@ const isFlippedX = computed(() => [6, 4].includes(props.zoneCharacter.character.
|
|||||||
const imageProps = computed(() => {
|
const imageProps = computed(() => {
|
||||||
// Get the current sprite action based on direction
|
// Get the current sprite action based on direction
|
||||||
const direction = [0, 6].includes(props.zoneCharacter.character.rotation ?? 0) ? 'back' : 'front'
|
const direction = [0, 6].includes(props.zoneCharacter.character.rotation ?? 0) ? 'back' : 'front'
|
||||||
const spriteAction = props.zoneCharacter.character.characterHair?.sprite?.spriteActions?.find(
|
const spriteAction = props.zoneCharacter.character.characterHair?.sprite?.spriteActions?.find((spriteAction) => spriteAction.action === direction)
|
||||||
spriteAction => spriteAction.action === direction
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
depth: 1,
|
depth: 1,
|
||||||
|
@ -51,7 +51,7 @@ gameStore.connection!.on('zone:character:leave', (characterId: number) => {
|
|||||||
zoneStore.removeCharacter(characterId)
|
zoneStore.removeCharacter(characterId)
|
||||||
})
|
})
|
||||||
|
|
||||||
gameStore.connection!.on('character:move', (data: { id: number, positionX: number, positionY: number, rotation: number, isMoving: boolean }) => {
|
gameStore.connection!.on('character:move', (data: { id: number; positionX: number; positionY: number; rotation: number; isMoving: boolean }) => {
|
||||||
zoneStore.updateCharacterPosition(data)
|
zoneStore.updateCharacterPosition(data)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -11,7 +11,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-bind="containerProps" class="overflow-y-auto relative p-2.5 rounded-md default-border bg-gray" @scroll="onScroll">
|
<div v-bind="containerProps" class="overflow-y-auto relative p-2.5 rounded-md default-border bg-gray" @scroll="onScroll">
|
||||||
<div v-bind="wrapperProps" ref="elementToScroll">
|
<div v-bind="wrapperProps" ref="elementToScroll">
|
||||||
<a v-for="{ data: characterHair } in list" :key="characterHair.id" class="relative p-2.5 cursor-pointer block rounded hover:bg-cyan group" :class="{ 'bg-cyan': assetManagerStore.selectedCharacterHair?.id === characterHair.id }" @click="assetManagerStore.setSelectedCharacterHair(characterHair as CharacterHair)">
|
<a
|
||||||
|
v-for="{ data: characterHair } in list"
|
||||||
|
:key="characterHair.id"
|
||||||
|
class="relative p-2.5 cursor-pointer block rounded hover:bg-cyan group"
|
||||||
|
:class="{ 'bg-cyan': assetManagerStore.selectedCharacterHair?.id === characterHair.id }"
|
||||||
|
@click="assetManagerStore.setSelectedCharacterHair(characterHair as CharacterHair)"
|
||||||
|
>
|
||||||
<div class="flex items-center gap-2.5">
|
<div class="flex items-center gap-2.5">
|
||||||
<span class="group-hover:text-white" :class="{ 'text-white': assetManagerStore.selectedCharacterHair?.id === characterHair.id }">{{ characterHair.name }}</span>
|
<span class="group-hover:text-white" :class="{ 'text-white': assetManagerStore.selectedCharacterHair?.id === characterHair.id }">{{ characterHair.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,7 +11,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-bind="containerProps" class="overflow-y-auto relative p-2.5 rounded-md default-border bg-gray" @scroll="onScroll">
|
<div v-bind="containerProps" class="overflow-y-auto relative p-2.5 rounded-md default-border bg-gray" @scroll="onScroll">
|
||||||
<div v-bind="wrapperProps" ref="elementToScroll">
|
<div v-bind="wrapperProps" ref="elementToScroll">
|
||||||
<a v-for="{ data: characterType } in list" :key="characterType.id" class="relative p-2.5 cursor-pointer block rounded hover:bg-cyan group" :class="{ 'bg-cyan': assetManagerStore.selectedCharacterType?.id === characterType.id }" @click="assetManagerStore.setSelectedCharacterType(characterType as CharacterType)">
|
<a
|
||||||
|
v-for="{ data: characterType } in list"
|
||||||
|
:key="characterType.id"
|
||||||
|
class="relative p-2.5 cursor-pointer block rounded hover:bg-cyan group"
|
||||||
|
:class="{ 'bg-cyan': assetManagerStore.selectedCharacterType?.id === characterType.id }"
|
||||||
|
@click="assetManagerStore.setSelectedCharacterType(characterType as CharacterType)"
|
||||||
|
>
|
||||||
<div class="flex items-center gap-2.5">
|
<div class="flex items-center gap-2.5">
|
||||||
<span class="group-hover:text-white" :class="{ 'text-white': assetManagerStore.selectedCharacterType?.id === characterType.id }">{{ characterType.name }}</span>
|
<span class="group-hover:text-white" :class="{ 'text-white': assetManagerStore.selectedCharacterType?.id === characterType.id }">{{ characterType.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -64,10 +64,7 @@ const filteredItems = computed(() => {
|
|||||||
if (!searchQuery.value) {
|
if (!searchQuery.value) {
|
||||||
return assetManagerStore.itemList
|
return assetManagerStore.itemList
|
||||||
}
|
}
|
||||||
return assetManagerStore.itemList.filter((item) =>
|
return assetManagerStore.itemList.filter((item) => item.name.toLowerCase().includes(searchQuery.value.toLowerCase()) || item.itemType.toLowerCase().includes(searchQuery.value.toLowerCase()))
|
||||||
item.name.toLowerCase().includes(searchQuery.value.toLowerCase()) ||
|
|
||||||
item.itemType.toLowerCase().includes(searchQuery.value.toLowerCase())
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const { list, containerProps, wrapperProps, scrollTo } = useVirtualList(filteredItems, {
|
const { list, containerProps, wrapperProps, scrollTo } = useVirtualList(filteredItems, {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<form @submit.prevent="loginFunc" class="relative px-6 py-11">
|
<form @submit.prevent="submit" class="relative px-6 py-11">
|
||||||
<div class="flex flex-col gap-5 p-2 mb-8 relative">
|
<div class="flex flex-col gap-5 p-2 mb-8 relative">
|
||||||
<div class="w-full grid gap-3 relative">
|
<div class="w-full grid gap-3 relative">
|
||||||
<input class="input-field xs:min-w-[350px] min-w-64" id="username-login" v-model="username" type="text" name="username" placeholder="Username" required autofocus />
|
<input class="input-field xs:min-w-[350px] min-w-64" id="username-login" v-model="username" type="text" name="username" placeholder="Username" required autofocus />
|
||||||
@ -7,7 +7,7 @@
|
|||||||
<input class="input-field xs:min-w-[350px] min-w-64" id="password-login" v-model="password" :type="showPassword ? 'text' : 'password'" name="password" placeholder="Password" required />
|
<input class="input-field xs:min-w-[350px] min-w-64" id="password-login" v-model="password" :type="showPassword ? 'text' : 'password'" name="password" placeholder="Password" required />
|
||||||
<button type="button" @click.prevent="showPassword = !showPassword" :class="{ 'eye-open': showPassword }" class="bg-[url('/assets/icons/eye.svg')] p-0 absolute right-3 w-5 h-4 top-1/2 -translate-y-1/2 bg-no-repeat bg-center"></button>
|
<button type="button" @click.prevent="showPassword = !showPassword" :class="{ 'eye-open': showPassword }" class="bg-[url('/assets/icons/eye.svg')] p-0 absolute right-3 w-5 h-4 top-1/2 -translate-y-1/2 bg-no-repeat bg-center"></button>
|
||||||
</div>
|
</div>
|
||||||
<span v-if="loginError" class="text-red-200 text-xs absolute top-full mt-1">{{ loginError }}</span>
|
<span v-if="formError" class="text-red-200 text-xs absolute top-full mt-1">{{ formError }}</span>
|
||||||
</div>
|
</div>
|
||||||
<button @click.stop="() => emit('openResetPasswordModal')" type="button" class="inline-flex self-end p-0 text-cyan-300 text-base">Forgot password?</button>
|
<button @click.stop="() => emit('openResetPasswordModal')" type="button" class="inline-flex self-end p-0 text-cyan-300 text-base">Forgot password?</button>
|
||||||
<button class="btn-cyan px-0 xs:w-full" type="submit">Play now</button>
|
<button class="btn-cyan px-0 xs:w-full" type="submit">Play now</button>
|
||||||
@ -36,7 +36,7 @@ const emit = defineEmits(['openResetPasswordModal', 'switchToRegister'])
|
|||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore()
|
||||||
const username = ref('')
|
const username = ref('')
|
||||||
const password = ref('')
|
const password = ref('')
|
||||||
const loginError = ref('')
|
const formError = ref('')
|
||||||
const showPassword = ref(false)
|
const showPassword = ref(false)
|
||||||
|
|
||||||
// automatic login because of development
|
// automatic login because of development
|
||||||
@ -48,10 +48,10 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
async function loginFunc() {
|
async function submit() {
|
||||||
// check if username and password are valid
|
// check if username and password are valid
|
||||||
if (username.value === '' || password.value === '') {
|
if (username.value === '' || password.value === '') {
|
||||||
loginError.value = 'Please enter a valid username and password'
|
formError.value = 'Please enter a valid username and password'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ async function loginFunc() {
|
|||||||
const response = await login(username.value, password.value)
|
const response = await login(username.value, password.value)
|
||||||
|
|
||||||
if (response.success === undefined) {
|
if (response.success === undefined) {
|
||||||
loginError.value = response.error
|
formError.value = response.error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gameStore.setToken(response.token)
|
gameStore.setToken(response.token)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<form @submit.prevent="registerFunc" class="relative px-6 py-11">
|
<form @submit.prevent="submit" class="relative px-6 py-11">
|
||||||
<div class="flex flex-col gap-5 p-2 mb-8 relative">
|
<div class="flex flex-col gap-5 p-2 mb-8 relative">
|
||||||
<div class="w-full grid gap-3 relative">
|
<div class="w-full grid gap-3 relative">
|
||||||
<input class="input-field xs:min-w-[350px] min-w-64" id="username-register" v-model="username" type="text" name="username" placeholder="Username" required autofocus />
|
<input class="input-field xs:min-w-[350px] min-w-64" id="username-register" v-model="username" type="text" name="username" placeholder="Username" required autofocus />
|
||||||
@ -8,7 +8,7 @@
|
|||||||
<input class="input-field xs:min-w-[350px] min-w-64" id="password-register" v-model="password" :type="showPassword ? 'text' : 'password'" name="password" placeholder="Password" required />
|
<input class="input-field xs:min-w-[350px] min-w-64" id="password-register" v-model="password" :type="showPassword ? 'text' : 'password'" name="password" placeholder="Password" required />
|
||||||
<button type="button" @click.prevent="showPassword = !showPassword" :class="{ 'eye-open': showPassword }" class="bg-[url('/assets/icons/eye.svg')] p-0 absolute right-3 w-4 h-3 top-1/2 -translate-y-1/2 bg-no-repeat"></button>
|
<button type="button" @click.prevent="showPassword = !showPassword" :class="{ 'eye-open': showPassword }" class="bg-[url('/assets/icons/eye.svg')] p-0 absolute right-3 w-4 h-3 top-1/2 -translate-y-1/2 bg-no-repeat"></button>
|
||||||
</div>
|
</div>
|
||||||
<span v-if="loginError" class="text-red-200 text-xs -mt-2">{{ loginError }}</span>
|
<span v-if="formError" class="text-red-200 text-xs -mt-2">{{ formError }}</span>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn-cyan xs:w-full" type="submit">Register now</button>
|
<button class="btn-cyan xs:w-full" type="submit">Register now</button>
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ const gameStore = useGameStore()
|
|||||||
const username = ref('')
|
const username = ref('')
|
||||||
const password = ref('')
|
const password = ref('')
|
||||||
const email = ref('')
|
const email = ref('')
|
||||||
const loginError = ref('')
|
const formError = ref('')
|
||||||
const showPassword = ref(false)
|
const showPassword = ref(false)
|
||||||
|
|
||||||
// automatic login because of development
|
// automatic login because of development
|
||||||
@ -49,34 +49,15 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
async function loginFunc() {
|
async function submit() {
|
||||||
// check if username and password are valid
|
|
||||||
if (username.value === '' || password.value === '') {
|
|
||||||
loginError.value = 'Please enter a valid username and password'
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// send login event to server
|
|
||||||
const response = await login(username.value, password.value)
|
|
||||||
|
|
||||||
if (response.success === undefined) {
|
|
||||||
loginError.value = response.error
|
|
||||||
return
|
|
||||||
}
|
|
||||||
gameStore.setToken(response.token)
|
|
||||||
gameStore.initConnection()
|
|
||||||
return true // Indicate success
|
|
||||||
}
|
|
||||||
|
|
||||||
async function registerFunc() {
|
|
||||||
// check if username and password are valid
|
// check if username and password are valid
|
||||||
if (username.value === '' || email.value === '' || password.value === '') {
|
if (username.value === '' || email.value === '' || password.value === '') {
|
||||||
loginError.value = 'Please enter a valid username, email, and password'
|
formError.value = 'Please enter a valid username, email, and password'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (email.value === '') {
|
if (email.value === '') {
|
||||||
loginError.value = 'Please enter an email'
|
formError.value = 'Please enter an email'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,14 +65,18 @@ async function registerFunc() {
|
|||||||
const response = await register(username.value, email.value, password.value)
|
const response = await register(username.value, email.value, password.value)
|
||||||
|
|
||||||
if (response.success === undefined) {
|
if (response.success === undefined) {
|
||||||
loginError.value = response.error
|
formError.value = response.error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const loginSuccess = await loginFunc()
|
const loginResponse = await login(username.value, password.value)
|
||||||
if (!loginSuccess) {
|
|
||||||
loginError.value = 'Login after registration failed. Please try logging in manually.'
|
if (!loginResponse) {
|
||||||
|
formError.value = 'Login after registration failed. Please try logging in manually.'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gameStore.setToken(loginResponse.token)
|
||||||
|
gameStore.initConnection()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -16,12 +16,7 @@
|
|||||||
<div class="flex w-full max-lg:flex-col lg:h-[400px] default-border rounded-md rounded-tl-none bg-gray">
|
<div class="flex w-full max-lg:flex-col lg:h-[400px] default-border rounded-md rounded-tl-none bg-gray">
|
||||||
<div class="lg:min-w-[285px] max-lg:min-h-[383px] lg:w-1/3 h-full bg-[url('/assets/ui-texture.png')] bg-no-repeat bg-cover bg-center border-0 max-lg:border-b lg:border-r border-solid border-gray-500 max-lg:rounded-tr-md lg:rounded-bl-md relative">
|
<div class="lg:min-w-[285px] max-lg:min-h-[383px] lg:w-1/3 h-full bg-[url('/assets/ui-texture.png')] bg-no-repeat bg-cover bg-center border-0 max-lg:border-b lg:border-r border-solid border-gray-500 max-lg:rounded-tr-md lg:rounded-bl-md relative">
|
||||||
<div class="absolute right-full -top-px flex gap-1 flex-col">
|
<div class="absolute right-full -top-px flex gap-1 flex-col">
|
||||||
<div
|
<div v-for="character in characters" :key="character.id" class="character relative rounded-l default-border w-9 h-[50px] bg-[url('/assets/ui-texture.png')] after:absolute after:w-full after:h-px after:bg-gray-500" :class="{ active: selectedCharacterId === character.id }">
|
||||||
v-for="character in characters"
|
|
||||||
:key="character.id"
|
|
||||||
class="character relative rounded-l default-border w-9 h-[50px] bg-[url('/assets/ui-texture.png')] after:absolute after:w-full after:h-px after:bg-gray-500"
|
|
||||||
:class="{ active: selectedCharacterId === character.id }"
|
|
||||||
>
|
|
||||||
<img src="/assets/placeholders/head.png" class="w-9 h-9 object-contain absolute top-1/2 -translate-y-1/2" alt="Player head" />
|
<img src="/assets/placeholders/head.png" class="w-9 h-9 object-contain absolute top-1/2 -translate-y-1/2" alt="Player head" />
|
||||||
<input class="h-full w-full absolute m-0 z-10 hover:cursor-pointer focus-visible:outline-offset-0" type="radio" name="character" :value="character.id" v-model="selectedCharacterId" />
|
<input class="h-full w-full absolute m-0 z-10 hover:cursor-pointer focus-visible:outline-offset-0" type="radio" name="character" :value="character.id" v-model="selectedCharacterId" />
|
||||||
</div>
|
</div>
|
||||||
@ -33,13 +28,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="py-6 px-8 h-[calc(100%_-_48px)] flex flex-col items-center gap-6 justify-center" v-if="selectedCharacterId">
|
<div class="py-6 px-8 h-[calc(100%_-_48px)] flex flex-col items-center gap-6 justify-center" v-if="selectedCharacterId">
|
||||||
<input class="input-field w-[158px]" type="text" name="name" :placeholder="characters.find((c) => c.id == selectedCharacterId)?.name" />
|
<input class="input-field w-[158px]" type="text" name="name" :placeholder="characters.find((c) => c.id == selectedCharacterId)?.name" />
|
||||||
<div class="flex flex-col gap-4 items-center">s
|
<div class="flex flex-col gap-4 items-center">
|
||||||
|
s
|
||||||
<div class="flex flex-col gap-3">
|
<div class="flex flex-col gap-3">
|
||||||
<div class="bg-[url('/assets/ui-elements/character-select-ui-shape.svg')] w-[190px] h-52 bg-no-repeat bg-center flex items-center justify-between">
|
<div class="bg-[url('/assets/ui-elements/character-select-ui-shape.svg')] w-[190px] h-52 bg-no-repeat bg-center flex items-center justify-between">
|
||||||
<button class="ml-6 w-4 h-8 p-0">
|
<button class="ml-6 w-4 h-8 p-0">
|
||||||
<img src="/assets/icons/triangle-icon.svg" class="w-3 h-3.5 m-auto" alt="Arrow left" />
|
<img src="/assets/icons/triangle-icon.svg" class="w-3 h-3.5 m-auto" alt="Arrow left" />
|
||||||
</button>
|
</button>
|
||||||
<img class="w-24 object-contain mb-3.5" alt="Player avatar" :src="config.server_endpoint + '/avatar/s/' + characters.find(c => c.id === selectedCharacterId)?.characterType?.id + '/' + (selectedHairId ?? 'default')" />
|
<img class="w-24 object-contain mb-3.5" alt="Player avatar" :src="config.server_endpoint + '/avatar/s/' + characters.find((c) => c.id === selectedCharacterId)?.characterType?.id + '/' + (selectedHairId ?? 'default')" />
|
||||||
<button class="mr-6 w-4 h-8 p-0">
|
<button class="mr-6 w-4 h-8 p-0">
|
||||||
<img src="/assets/icons/triangle-icon.svg" class="w-3 h-3.5 -scale-x-100" alt="Arrow right" />
|
<img src="/assets/icons/triangle-icon.svg" class="w-3 h-3.5 -scale-x-100" alt="Arrow right" />
|
||||||
</button>
|
</button>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<div class="bg-[url('/assets/login/login-bg.png')] w-full lg:w-1/2 h-[35dvh] lg:h-dvh absolute left-0 max-lg:bottom-0 lg:top-0 bg-no-repeat bg-cover bg-center"></div>
|
<div class="bg-[url('/assets/login/login-bg.png')] w-full lg:w-1/2 h-[35dvh] lg:h-dvh absolute left-0 max-lg:bottom-0 lg:top-0 bg-no-repeat bg-cover bg-center"></div>
|
||||||
<div class="bg-gray-900 z-20 w-full lg:w-1/2 h-[65dvh] lg:h-dvh relative">
|
<div class="bg-gray-900 z-20 w-full lg:w-1/2 h-[65dvh] lg:h-dvh relative">
|
||||||
<div class="h-dvh flex items-center lg:justify-center flex-col px-8 max-lg:pt-20">
|
<div class="h-dvh flex items-center lg:justify-center flex-col px-8 max-lg:pt-20">
|
||||||
<!-- <img src="/assets/tlogo.png" class="mb-10 w-52" alt="Noxious logo" />-->
|
<!-- <img src="/assets/tlogo.png" class="mb-10 w-52" alt="Noxious logo" />-->
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<img src="/assets/ui-elements/login-ui-box-outer.svg" class="absolute w-full h-full" alt="UI box outer" />
|
<img src="/assets/ui-elements/login-ui-box-outer.svg" class="absolute w-full h-full" alt="UI box outer" />
|
||||||
<img src="/assets/ui-elements/login-ui-box-inner.svg" class="absolute left-2 top-2 w-[calc(100%_-_16px)] h-[calc(100%_-_16px)] max-lg:hidden" alt="UI box inner" />
|
<img src="/assets/ui-elements/login-ui-box-inner.svg" class="absolute left-2 top-2 w-[calc(100%_-_16px)] h-[calc(100%_-_16px)] max-lg:hidden" alt="UI box inner" />
|
||||||
|
@ -32,21 +32,13 @@ const { setupPointerHandlers, cleanupPointerHandlers } = usePointerHandlers(scen
|
|||||||
function handleScrollZoom(pointer: Phaser.Input.Pointer) {
|
function handleScrollZoom(pointer: Phaser.Input.Pointer) {
|
||||||
if (!(pointer.event instanceof WheelEvent && pointer.event.shiftKey)) return
|
if (!(pointer.event instanceof WheelEvent && pointer.event.shiftKey)) return
|
||||||
|
|
||||||
const zoomLevel = Phaser.Math.Clamp(
|
const zoomLevel = Phaser.Math.Clamp(camera.zoom - pointer.event.deltaY * ZOOM_SETTINGS.WHEEL_FACTOR, ZOOM_SETTINGS.MIN, ZOOM_SETTINGS.MAX)
|
||||||
camera.zoom - pointer.event.deltaY * ZOOM_SETTINGS.WHEEL_FACTOR,
|
|
||||||
ZOOM_SETTINGS.MIN,
|
|
||||||
ZOOM_SETTINGS.MAX
|
|
||||||
)
|
|
||||||
camera.setZoom(zoomLevel)
|
camera.setZoom(zoomLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeyComboZoom(event: { keyCodes: number[] }) {
|
function handleKeyComboZoom(event: { keyCodes: number[] }) {
|
||||||
const deltaY = event.keyCodes[1] === 38 ? 1 : -1 // 38 is Up, 40 is Down
|
const deltaY = event.keyCodes[1] === 38 ? 1 : -1 // 38 is Up, 40 is Down
|
||||||
const zoomLevel = Phaser.Math.Clamp(
|
const zoomLevel = Phaser.Math.Clamp(camera.zoom + deltaY * ZOOM_SETTINGS.KEY_FACTOR, ZOOM_SETTINGS.MIN, ZOOM_SETTINGS.MAX)
|
||||||
camera.zoom + deltaY * ZOOM_SETTINGS.KEY_FACTOR,
|
|
||||||
ZOOM_SETTINGS.MIN,
|
|
||||||
ZOOM_SETTINGS.MAX
|
|
||||||
)
|
|
||||||
camera.setZoom(zoomLevel)
|
camera.setZoom(zoomLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@ export async function loadSpriteTextures(scene: Phaser.Scene, sprite: Sprite) {
|
|||||||
const sprite_actions: HttpResponse<any[]> = await fetch(config.server_endpoint + '/assets/list_sprite_actions/' + sprite?.id).then((response) => response.json())
|
const sprite_actions: HttpResponse<any[]> = await fetch(config.server_endpoint + '/assets/list_sprite_actions/' + sprite?.id).then((response) => response.json())
|
||||||
|
|
||||||
for await (const sprite_action of sprite_actions.data ?? []) {
|
for await (const sprite_action of sprite_actions.data ?? []) {
|
||||||
|
console.log(sprite_action)
|
||||||
await loadTexture(scene, {
|
await loadTexture(scene, {
|
||||||
key: sprite_action.key,
|
key: sprite_action.key,
|
||||||
data: sprite_action.data,
|
data: sprite_action.data,
|
||||||
@ -73,7 +74,7 @@ export async function loadSpriteTextures(scene: Phaser.Scene, sprite: Sprite) {
|
|||||||
isAnimated: sprite_action.isAnimated,
|
isAnimated: sprite_action.isAnimated,
|
||||||
frameWidth: sprite_action.frameWidth,
|
frameWidth: sprite_action.frameWidth,
|
||||||
frameHeight: sprite_action.frameHeight,
|
frameHeight: sprite_action.frameHeight,
|
||||||
frameRate: sprite_action.frameRate,
|
frameRate: sprite_action.frameRate
|
||||||
} as AssetDataT)
|
} as AssetDataT)
|
||||||
|
|
||||||
// If the sprite is not animated, skip
|
// If the sprite is not animated, skip
|
||||||
@ -88,7 +89,7 @@ export async function loadSpriteTextures(scene: Phaser.Scene, sprite: Sprite) {
|
|||||||
scene.anims.create({
|
scene.anims.create({
|
||||||
key: sprite_action.key,
|
key: sprite_action.key,
|
||||||
frameRate: sprite_action.frameRate,
|
frameRate: sprite_action.frameRate,
|
||||||
frames: scene.anims.generateFrameNumbers(sprite_action.key, { start: 0, end: sprite_action.frameRate! - 1 }),
|
frames: scene.anims.generateFrameNumbers(sprite_action.key, { start: 0, end: sprite_action.frameCount! - 1 }),
|
||||||
repeat: -1
|
repeat: -1
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,10 @@ import { getDomain } from '@/application/utilities'
|
|||||||
export async function register(username: string, email: string, password: string) {
|
export async function register(username: string, email: string, password: string) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(`${config.server_endpoint}/register`, { username, email, password })
|
const response = await axios.post(`${config.server_endpoint}/register`, { username, email, password })
|
||||||
useCookies().set('token', response.data.data.token as string)
|
if (response.status === 200) {
|
||||||
return { success: true, token: response.data.data.token }
|
return { success: true }
|
||||||
|
}
|
||||||
|
return { error: response.data.message }
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (typeof error.response?.data === 'undefined') {
|
if (typeof error.response?.data === 'undefined') {
|
||||||
return { error: 'Could not connect to server' }
|
return { error: 'Could not connect to server' }
|
||||||
|
@ -33,9 +33,10 @@ export class AssetStorage {
|
|||||||
originX: asset.originX,
|
originX: asset.originX,
|
||||||
originY: asset.originY,
|
originY: asset.originY,
|
||||||
isAnimated: asset.isAnimated,
|
isAnimated: asset.isAnimated,
|
||||||
|
frameRate: asset.frameRate,
|
||||||
frameWidth: asset.frameWidth,
|
frameWidth: asset.frameWidth,
|
||||||
frameHeight: asset.frameHeight,
|
frameHeight: asset.frameHeight,
|
||||||
frameRate: asset.frameRate
|
frameCount: asset.frameCount
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to add asset ${asset.key}:`, error)
|
console.error(`Failed to add asset ${asset.key}:`, error)
|
||||||
|
@ -40,10 +40,10 @@ export const useZoneStore = defineStore('zone', {
|
|||||||
setCharacterLoaded(loaded: boolean) {
|
setCharacterLoaded(loaded: boolean) {
|
||||||
this.characterLoaded = loaded
|
this.characterLoaded = loaded
|
||||||
},
|
},
|
||||||
updateCharacterPosition(data: { id: number, positionX: number, positionY: number, rotation: number, isMoving: boolean }) {
|
updateCharacterPosition(data: { id: number; positionX: number; positionY: number; rotation: number; isMoving: boolean }) {
|
||||||
const character = this.characters.find(char => char.character.id === data.id)
|
const character = this.characters.find((char) => char.character.id === data.id)
|
||||||
if (character) {
|
if (character) {
|
||||||
character.character.positionX= data.positionX
|
character.character.positionX = data.positionX
|
||||||
character.character.positionY = data.positionY
|
character.character.positionY = data.positionY
|
||||||
character.character.rotation = data.rotation
|
character.character.rotation = data.rotation
|
||||||
character.isMoving = data.isMoving
|
character.isMoving = data.isMoving
|
||||||
|
Loading…
x
Reference in New Issue
Block a user