mirror of
https://github.com/thepaperpilot/Super-Auto-Coots.git
synced 2024-11-25 01:41:46 +00:00
Implemented merging/levels
This commit is contained in:
parent
17ffc977fb
commit
b0e0f8aeac
5 changed files with 175 additions and 37 deletions
|
@ -10,6 +10,10 @@
|
|||
<link rel="alternate icon" type="image/png" sizes="48x48" href="/favicon.ico">
|
||||
<meta name="theme-color" content="#2E3440">
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Mynerve&display=swap" rel="stylesheet">
|
||||
|
||||
<title>Profectus</title>
|
||||
<meta name="description" content="A project made in Profectus"/>
|
||||
|
||||
|
|
|
@ -1,9 +1,26 @@
|
|||
<template>
|
||||
<Tooltip
|
||||
:display="character ? characters[character.type].nickname : ''"
|
||||
:display="character && selected == null ? characters[character.type].nickname : ''"
|
||||
:direction="Direction.Up"
|
||||
>
|
||||
<div class="character" :class="{ selected, empty: character == null }">
|
||||
<div
|
||||
class="character"
|
||||
:class="{ selected: isSelected, empty: character == null && selected == null }"
|
||||
>
|
||||
<span class="move-indicator" v-if="character == null && selected != null">
|
||||
<span class="material-icons">straight</span></span
|
||||
>
|
||||
<span
|
||||
class="move-indicator"
|
||||
v-if="
|
||||
character != null &&
|
||||
selected != null &&
|
||||
!isSelected &&
|
||||
character.type === selected.type &&
|
||||
character.exp < 6
|
||||
"
|
||||
><span class="material-icons">merge</span></span
|
||||
>
|
||||
<span class="character-display" v-if="character != null">
|
||||
<img :src="characters[character.type].display" />
|
||||
</span>
|
||||
|
@ -15,6 +32,18 @@
|
|||
<span class="material-icons"> extension </span>
|
||||
{{ character?.presence }}
|
||||
</span>
|
||||
<span class="level-display" v-if="character != null">
|
||||
<span class="level">{{ level }}</span>
|
||||
<span class="segments">
|
||||
<span
|
||||
v-for="i in segments"
|
||||
:key="i"
|
||||
class="segment"
|
||||
:class="{ filled: filledSegments >= i }"
|
||||
>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</template>
|
||||
|
@ -22,16 +51,39 @@
|
|||
<script setup lang="ts">
|
||||
import Tooltip from "features/tooltips/Tooltip.vue";
|
||||
import { Direction } from "util/common";
|
||||
import { computed, watch } from "vue";
|
||||
import { characters } from "./projEntry";
|
||||
|
||||
defineProps<{
|
||||
character?: {
|
||||
type: string;
|
||||
relevancy: number;
|
||||
presence: number;
|
||||
} | null;
|
||||
selected?: boolean;
|
||||
const props = defineProps<{
|
||||
character?: Character | null;
|
||||
isSelected?: boolean;
|
||||
selected?: Character | null;
|
||||
}>();
|
||||
|
||||
const level = computed(() => {
|
||||
const exp = props.character?.exp ?? 0;
|
||||
if (exp < 3) {
|
||||
return 1;
|
||||
}
|
||||
if (exp < 6) {
|
||||
return 2;
|
||||
}
|
||||
return 3;
|
||||
});
|
||||
const segments = computed(() => {
|
||||
const exp = props.character?.exp ?? 0;
|
||||
if (exp < 3) {
|
||||
return 2;
|
||||
}
|
||||
return 3;
|
||||
});
|
||||
const filledSegments = computed(() => {
|
||||
const exp = props.character?.exp ?? 0;
|
||||
if (exp < 3) {
|
||||
return exp - 1;
|
||||
}
|
||||
return exp - 3;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
@ -81,6 +133,7 @@ defineProps<{
|
|||
left: 0;
|
||||
right: 0;
|
||||
background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' stroke='%2388C0D0' stroke-width='8' stroke-dasharray='10%25%2c90%25' stroke-dashoffset='5' stroke-linecap='square'/%3e%3c/svg%3e");
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
.relevancy-display {
|
||||
|
@ -116,4 +169,71 @@ defineProps<{
|
|||
font-size: 200%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.level-display {
|
||||
position: absolute;
|
||||
bottom: -10%;
|
||||
right: -20%;
|
||||
color: var(--accent2);
|
||||
font-size: xx-large;
|
||||
text-shadow: -1px 1px 0 var(--outline), 1px 1px 0 var(--outline), 1px -1px 0 var(--outline),
|
||||
-1px -1px 0 var(--outline);
|
||||
}
|
||||
|
||||
.level {
|
||||
background: var(--locked);
|
||||
border-radius: 4px;
|
||||
border-top-left-radius: 50%;
|
||||
border-bottom-left-radius: 0;
|
||||
border: solid 2px var(--raised-background);
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.level,
|
||||
.level::before {
|
||||
font-family: "Mynerve", cursive;
|
||||
}
|
||||
|
||||
.level::before {
|
||||
content: "lv";
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.segments {
|
||||
position: absolute;
|
||||
right: calc(100% - 2px);
|
||||
width: 100%;
|
||||
height: 25%;
|
||||
bottom: -2px;
|
||||
background: var(--locked);
|
||||
border-radius: 20px 0 0 0;
|
||||
border: solid 2px var(--raised-background);
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.segment {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.segment:not(:last-child) {
|
||||
border-right: solid 3px var(--raised-background);
|
||||
}
|
||||
|
||||
.segment.filled {
|
||||
background-color: var(--accent2);
|
||||
}
|
||||
|
||||
.move-indicator {
|
||||
position: absolute;
|
||||
transform: translateX(-50%) rotate(180deg);
|
||||
top: -75%;
|
||||
left: 50%;
|
||||
font-size: xxx-large;
|
||||
}
|
||||
.move-indicator .material-icons {
|
||||
font-size: xxx-large;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -78,7 +78,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
const turn = ref<number>(0);
|
||||
const gold = ref<number>(0);
|
||||
const team = ref<(Character | null)[]>([null, null, null]);
|
||||
const shop = ref<(string | null)[]>([]);
|
||||
const shop = ref<(Character | null)[]>([]);
|
||||
const selectedCharacter = ref<number | null>(null);
|
||||
const selectedShopItem = ref<number | null>(null);
|
||||
|
||||
|
@ -123,37 +123,34 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
<h2>{nickname.value}</h2>
|
||||
<Spacer height="10vh" />
|
||||
<Row>
|
||||
{new Array(3).fill(0).map((_, i) => (
|
||||
<CharacterSlot
|
||||
character={team.value[0]}
|
||||
selected={selectedCharacter.value === 0}
|
||||
onClick={clickCharacter(0)}
|
||||
/>
|
||||
<CharacterSlot
|
||||
character={team.value[1]}
|
||||
selected={selectedCharacter.value === 1}
|
||||
onClick={clickCharacter(1)}
|
||||
/>
|
||||
<CharacterSlot
|
||||
character={team.value[2]}
|
||||
selected={selectedCharacter.value === 2}
|
||||
onClick={clickCharacter(2)}
|
||||
character={team.value[i]}
|
||||
isSelected={selectedCharacter.value === i}
|
||||
selected={
|
||||
selectedCharacter.value == null
|
||||
? selectedShopItem.value == null ||
|
||||
(team.value[i] != null &&
|
||||
shop.value[selectedShopItem.value]?.type !==
|
||||
team.value[i]?.type)
|
||||
? null
|
||||
: shop.value[selectedShopItem.value]
|
||||
: team.value[selectedCharacter.value]
|
||||
}
|
||||
onClick={clickCharacter(i)}
|
||||
/>
|
||||
))}
|
||||
</Row>
|
||||
<Spacer height="10vh" />
|
||||
<Row>
|
||||
{shop.value.map((item, i) => (
|
||||
<CharacterSlot
|
||||
character={
|
||||
item == null
|
||||
? undefined
|
||||
: {
|
||||
type: item,
|
||||
relevancy: characters[item].initialRelevancy,
|
||||
presence: characters[item].initialPresence
|
||||
}
|
||||
}
|
||||
selected={selectedShopItem.value === i}
|
||||
character={item == null ? undefined : item}
|
||||
isSelected={selectedShopItem.value === i}
|
||||
onClick={(e: MouseEvent) => {
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
selectedShopItem.value = selectedShopItem.value === i ? null : i;
|
||||
selectedCharacter.value = null;
|
||||
e.stopPropagation();
|
||||
|
|
|
@ -102,10 +102,20 @@ function setupSocket(socket: Socket<ServerToClientEvents, ClientToServerEvents>)
|
|||
socket.on("newTurn", shop => {
|
||||
main.gold.value = 10;
|
||||
main.turn.value++;
|
||||
main.shop.value = shop;
|
||||
main.shop.value = shop.map(item => ({
|
||||
type: item,
|
||||
relevancy: characters[item].initialRelevancy,
|
||||
presence: characters[item].initialPresence,
|
||||
exp: 1
|
||||
}));
|
||||
});
|
||||
socket.on("reroll", shop => {
|
||||
main.shop.value = shop;
|
||||
main.shop.value = shop.map(item => ({
|
||||
type: item,
|
||||
relevancy: characters[item].initialRelevancy,
|
||||
presence: characters[item].initialPresence,
|
||||
exp: 1
|
||||
}));
|
||||
});
|
||||
socket.on("buy", (shopIndex, teamIndex, char) => {
|
||||
main.team.value[teamIndex] = char;
|
||||
|
@ -117,6 +127,10 @@ function setupSocket(socket: Socket<ServerToClientEvents, ClientToServerEvents>)
|
|||
main.team.value[index] = main.team.value[otherIndex];
|
||||
main.team.value[otherIndex] = temp;
|
||||
});
|
||||
socket.on("merge", (index, otherIndex, char) => {
|
||||
main.team.value[index] = null;
|
||||
main.team.value[otherIndex] = char;
|
||||
});
|
||||
}
|
||||
|
||||
declare module "game/settings" {
|
||||
|
|
3
src/data/types.d.ts
vendored
3
src/data/types.d.ts
vendored
|
@ -7,6 +7,7 @@ interface CharacterInfo {
|
|||
|
||||
interface Character {
|
||||
type: string;
|
||||
exp: number;
|
||||
relevancy: number;
|
||||
presence: number;
|
||||
}
|
||||
|
@ -19,9 +20,11 @@ interface ServerToClientEvents {
|
|||
reroll: (shop: string[]) => void;
|
||||
buy: (shopIndex: number, teamIndex: number, char: Character) => void;
|
||||
move: (index: number, otherIndex: number) => void;
|
||||
merge: (shopIndex: number, teamIndex: number, char: Character) => void;
|
||||
}
|
||||
|
||||
interface ClientToServerEvents {
|
||||
buy: (shopIndex: number, teamIndex: number) => void;
|
||||
move: (index: number, otherIndex: number) => void;
|
||||
merge: (index: number, otherIndex: number) => void;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue