mirror of
https://github.com/thepaperpilot/Super-Auto-Coots.git
synced 2024-11-21 16:13:56 +00:00
Initial stuff
This commit is contained in:
parent
bfd14e6288
commit
15b7d6adbc
10 changed files with 250 additions and 162 deletions
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -25,7 +25,6 @@
|
|||
"nanoevents": "^6.0.2",
|
||||
"semver": "^7.3.8",
|
||||
"socket.io-client": "^4.6.0",
|
||||
"unique-names-generator": "^4.7.1",
|
||||
"vite": "^2.9.12",
|
||||
"vite-plugin-pwa": "^0.12.0",
|
||||
"vite-tsconfig-paths": "^3.5.0",
|
||||
|
@ -7134,14 +7133,6 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/unique-names-generator": {
|
||||
"version": "4.7.1",
|
||||
"resolved": "https://registry.npmjs.org/unique-names-generator/-/unique-names-generator-4.7.1.tgz",
|
||||
"integrity": "sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/unique-string": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
|
||||
|
@ -13131,11 +13122,6 @@
|
|||
"resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz",
|
||||
"integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ=="
|
||||
},
|
||||
"unique-names-generator": {
|
||||
"version": "4.7.1",
|
||||
"resolved": "https://registry.npmjs.org/unique-names-generator/-/unique-names-generator-4.7.1.tgz",
|
||||
"integrity": "sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow=="
|
||||
},
|
||||
"unique-string": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
"nanoevents": "^6.0.2",
|
||||
"semver": "^7.3.8",
|
||||
"socket.io-client": "^4.6.0",
|
||||
"unique-names-generator": "^4.7.1",
|
||||
"vite": "^2.9.12",
|
||||
"vite-plugin-pwa": "^0.12.0",
|
||||
"vite-tsconfig-paths": "^3.5.0",
|
||||
|
|
|
@ -36,11 +36,6 @@
|
|||
<span class="material-icons">info</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div @click="savesManager?.open()">
|
||||
<Tooltip display="Saves" :direction="Direction.Down" xoffset="-20px">
|
||||
<span class="material-icons">library_books</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div @click="options?.open()">
|
||||
<Tooltip display="Settings" :direction="Direction.Down" xoffset="-66px">
|
||||
<span class="material-icons">settings</span>
|
||||
|
@ -53,11 +48,6 @@
|
|||
<span>v{{ versionNumber }}</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div @click="savesManager?.open()">
|
||||
<Tooltip display="Saves" :direction="Direction.Right">
|
||||
<span class="material-icons">library_books</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div @click="options?.open()">
|
||||
<Tooltip display="Settings" :direction="Direction.Right">
|
||||
<span class="material-icons">settings</span>
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
<Toggle :title="offlineProdTitle" v-model="offlineProd" />
|
||||
<Toggle :title="autosaveTitle" v-model="autosave" />
|
||||
<FeedbackButton v-if="!autosave" class="button save-button" @click="save()">Manually save</FeedbackButton>
|
||||
<component :is="settingFieldsComponent" />
|
||||
</div>
|
||||
<div v-if="isTab('appearance')">
|
||||
<Select :title="themeTitle" :options="themes" v-model="theme" />
|
||||
<component :is="settingFieldsComponent" />
|
||||
<Toggle :title="showTPSTitle" v-model="showTPS" />
|
||||
<Toggle :title="alignModifierUnitsTitle" v-model="alignUnits" />
|
||||
</div>
|
||||
|
|
40
src/data/CharacterSlot.vue
Normal file
40
src/data/CharacterSlot.vue
Normal file
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<div class="character">
|
||||
<span class="character-display">{{ character?.type }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
character?: {
|
||||
type: string;
|
||||
relevancy: number;
|
||||
};
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.character {
|
||||
width: 8vw;
|
||||
height: 8vw;
|
||||
position: relative;
|
||||
margin: 50px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.character-display {
|
||||
text-shadow: 3px 3px 5px black;
|
||||
}
|
||||
|
||||
.character::after {
|
||||
content: "";
|
||||
background: grey;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 50%;
|
||||
z-index: -1;
|
||||
}
|
||||
</style>
|
|
@ -1,73 +0,0 @@
|
|||
/**
|
||||
* @module
|
||||
* @hidden
|
||||
*/
|
||||
import { main } from "data/projEntry";
|
||||
import { createCumulativeConversion, createPolynomialScaling } from "features/conversion";
|
||||
import { jsx } from "features/feature";
|
||||
import { createHotkey } from "features/hotkey";
|
||||
import { createReset } from "features/reset";
|
||||
import MainDisplay from "features/resources/MainDisplay.vue";
|
||||
import { createResource } from "features/resources/resource";
|
||||
import { addTooltip } from "features/tooltips/tooltip";
|
||||
import { createResourceTooltip } from "features/trees/tree";
|
||||
import { BaseLayer, createLayer } from "game/layers";
|
||||
import type { DecimalSource } from "util/bignum";
|
||||
import { render } from "util/vue";
|
||||
import { createLayerTreeNode, createResetButton } from "../common";
|
||||
|
||||
const id = "p";
|
||||
const layer = createLayer(id, function (this: BaseLayer) {
|
||||
const name = "Prestige";
|
||||
const color = "#4BDC13";
|
||||
const points = createResource<DecimalSource>(0, "prestige points");
|
||||
|
||||
const conversion = createCumulativeConversion(() => ({
|
||||
scaling: createPolynomialScaling(10, 0.5),
|
||||
baseResource: main.points,
|
||||
gainResource: points,
|
||||
roundUpCost: true
|
||||
}));
|
||||
|
||||
const reset = createReset(() => ({
|
||||
thingsToReset: (): Record<string, unknown>[] => [layer]
|
||||
}));
|
||||
|
||||
const treeNode = createLayerTreeNode(() => ({
|
||||
layerID: id,
|
||||
color,
|
||||
reset
|
||||
}));
|
||||
addTooltip(treeNode, {
|
||||
display: createResourceTooltip(points),
|
||||
pinnable: true
|
||||
});
|
||||
|
||||
const resetButton = createResetButton(() => ({
|
||||
conversion,
|
||||
tree: main.tree,
|
||||
treeNode
|
||||
}));
|
||||
|
||||
const hotkey = createHotkey(() => ({
|
||||
description: "Reset for prestige points",
|
||||
key: "p",
|
||||
onPress: resetButton.onClick
|
||||
}));
|
||||
|
||||
return {
|
||||
name,
|
||||
color,
|
||||
points,
|
||||
display: jsx(() => (
|
||||
<>
|
||||
<MainDisplay resource={points} color={color} />
|
||||
{render(resetButton)}
|
||||
</>
|
||||
)),
|
||||
treeNode,
|
||||
hotkey
|
||||
};
|
||||
});
|
||||
|
||||
export default layer;
|
|
@ -1,75 +1,93 @@
|
|||
import Row from "components/layout/Row.vue";
|
||||
import Spacer from "components/layout/Spacer.vue";
|
||||
import { jsx } from "features/feature";
|
||||
import { createResource, trackBest, trackOOMPS, trackTotal } from "features/resources/resource";
|
||||
import type { GenericTree } from "features/trees/tree";
|
||||
import { branchedResetPropagation, createTree } from "features/trees/tree";
|
||||
import { globalBus } from "game/events";
|
||||
import type { BaseLayer, GenericLayer } from "game/layers";
|
||||
import { createLayer } from "game/layers";
|
||||
import type { Player } from "game/player";
|
||||
import player from "game/player";
|
||||
import type { DecimalSource } from "util/bignum";
|
||||
import Decimal, { format, formatTime } from "util/bignum";
|
||||
import { render } from "util/vue";
|
||||
import { computed, toRaw } from "vue";
|
||||
import prestige from "./layers/prestige";
|
||||
import { computed, ref } from "vue";
|
||||
import CharacterSlot from "./CharacterSlot.vue";
|
||||
import "./socket";
|
||||
import { nickname } from "./socket";
|
||||
|
||||
export const characters: Record<string, CharacterInfo> = {
|
||||
coots: {
|
||||
nickname: "Coots Prime",
|
||||
initialRelevancy: 1
|
||||
},
|
||||
ludwig: {
|
||||
nickname: "Ludwig",
|
||||
initialRelevancy: 1
|
||||
},
|
||||
qt: {
|
||||
nickname: "QtCinderella",
|
||||
initialRelevancy: 1
|
||||
},
|
||||
ders: {
|
||||
nickname: "Ders",
|
||||
initialRelevancy: 1
|
||||
},
|
||||
slime: {
|
||||
nickname: "Slime",
|
||||
initialRelevancy: 1
|
||||
},
|
||||
stanz: {
|
||||
nickname: "Stanz",
|
||||
initialRelevancy: 1
|
||||
},
|
||||
beast: {
|
||||
nickname: "Mr.Beast",
|
||||
initialRelevancy: 1
|
||||
},
|
||||
car: {
|
||||
nickname: "Red Car",
|
||||
initialRelevancy: 1
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
export const main = createLayer("main", function (this: BaseLayer) {
|
||||
const points = createResource<DecimalSource>(10);
|
||||
const best = trackBest(points);
|
||||
const total = trackTotal(points);
|
||||
|
||||
const pointGain = computed(() => {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let gain = new Decimal(1);
|
||||
return gain;
|
||||
});
|
||||
globalBus.on("update", diff => {
|
||||
points.value = Decimal.add(points.value, Decimal.times(pointGain.value, diff));
|
||||
});
|
||||
const oomps = trackOOMPS(points, pointGain);
|
||||
|
||||
const tree = createTree(() => ({
|
||||
nodes: [[prestige.treeNode]],
|
||||
branches: [],
|
||||
onReset() {
|
||||
points.value = toRaw(this.resettingNode.value) === toRaw(prestige.treeNode) ? 0 : 10;
|
||||
best.value = points.value;
|
||||
total.value = points.value;
|
||||
},
|
||||
resetPropagation: branchedResetPropagation
|
||||
})) as GenericTree;
|
||||
const lives = ref<number>(3);
|
||||
const wins = ref<number>(0);
|
||||
const turn = ref<number>(0);
|
||||
const team = ref<Character[]>([]);
|
||||
const shop = ref<string[]>([]);
|
||||
|
||||
return {
|
||||
name: "Tree",
|
||||
links: tree.links,
|
||||
name: "Game",
|
||||
minimizable: false,
|
||||
display: jsx(() => (
|
||||
<>
|
||||
{player.devSpeed === 0 ? <div>Game Paused</div> : null}
|
||||
{player.devSpeed != null && player.devSpeed !== 0 && player.devSpeed !== 1 ? (
|
||||
<div>Dev Speed: {format(player.devSpeed)}x</div>
|
||||
) : null}
|
||||
{player.offlineTime != null && player.offlineTime !== 0 ? (
|
||||
<div>Offline Time: {formatTime(player.offlineTime)}</div>
|
||||
) : null}
|
||||
<div>
|
||||
{Decimal.lt(points.value, "1e1000") ? <span>You have </span> : null}
|
||||
<h2>{format(points.value)}</h2>
|
||||
{Decimal.lt(points.value, "1e1e6") ? <span> points</span> : null}
|
||||
</div>
|
||||
{Decimal.gt(pointGain.value, 0) ? <div>({oomps.value})</div> : null}
|
||||
<div style="display: flex; flex-direction: column">
|
||||
<h2>{nickname.value}</h2>
|
||||
<Spacer height="10vh" />
|
||||
<Row>
|
||||
<CharacterSlot character={team.value[0]} />
|
||||
<CharacterSlot character={team.value[1]} />
|
||||
<CharacterSlot character={team.value[2]} />
|
||||
</Row>
|
||||
<Spacer height="10vh" />
|
||||
<Row>
|
||||
{shop.value.map(item => (
|
||||
<CharacterSlot
|
||||
character={
|
||||
item
|
||||
? { type: item, relevancy: characters[item].initialRelevancy }
|
||||
: undefined
|
||||
}
|
||||
onClick={() => console.log(item)}
|
||||
/>
|
||||
))}
|
||||
</Row>
|
||||
<Spacer />
|
||||
{render(tree)}
|
||||
</>
|
||||
<button onClick={() => console.log("play")}>Start Stream!</button>
|
||||
</div>
|
||||
)),
|
||||
points,
|
||||
best,
|
||||
total,
|
||||
oomps,
|
||||
tree
|
||||
lives,
|
||||
wins,
|
||||
turn,
|
||||
team,
|
||||
shop
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -80,7 +98,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
export const getInitialLayers = (
|
||||
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
|
||||
player: Partial<Player>
|
||||
): Array<GenericLayer> => [main, prestige];
|
||||
): Array<GenericLayer> => [main];
|
||||
|
||||
/**
|
||||
* A computed ref whose value is true whenever the game is over.
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
{
|
||||
"$schema": "./projInfo-schema.json",
|
||||
|
||||
"title": "Profectus",
|
||||
"title": "Super Auto Coots",
|
||||
"description": "A project made in Profectus",
|
||||
"id": "",
|
||||
"author": "",
|
||||
"id": "superautocoots",
|
||||
"author": "thepaperpilot and crea",
|
||||
"discordName": "",
|
||||
"discordLink": "",
|
||||
|
||||
"versionNumber": "0.0",
|
||||
"versionNumber": "0.0.0",
|
||||
"versionTitle": "Initial Commit",
|
||||
|
||||
"allowGoBack": true,
|
||||
"allowGoBack": false,
|
||||
"defaultShowSmall": false,
|
||||
"defaultDecimalsShown": 2,
|
||||
"useHeader": true,
|
||||
|
|
110
src/data/socket.tsx
Normal file
110
src/data/socket.tsx
Normal file
|
@ -0,0 +1,110 @@
|
|||
import Text from "components/fields/Text.vue";
|
||||
import projInfo from "data/projInfo.json";
|
||||
import { jsx, setDefault } from "features/feature";
|
||||
import { globalBus } from "game/events";
|
||||
import { registerSettingField } from "game/settings";
|
||||
import satisfies from "semver/functions/satisfies";
|
||||
import { io, Socket } from "socket.io-client";
|
||||
import { ref, watch } from "vue";
|
||||
import { useToast } from "vue-toastification";
|
||||
import { main } from "./projEntry";
|
||||
|
||||
export const connected = ref<boolean>(false);
|
||||
export const nickname = ref<string>("");
|
||||
|
||||
const toast = useToast();
|
||||
|
||||
const socket = ref<Socket<ServerToClientEvents, ClientToServerEvents> | null>();
|
||||
const connectionError = ref<string>("");
|
||||
|
||||
export function emit<T extends keyof ClientToServerEvents>(
|
||||
event: T,
|
||||
...args: Parameters<ClientToServerEvents[T]>
|
||||
): void {
|
||||
if (!connected.value) {
|
||||
return;
|
||||
}
|
||||
socket.value?.emit(event, ...args);
|
||||
}
|
||||
|
||||
globalBus.on("loadSettings", settings => {
|
||||
setDefault(settings, "server", "https://Super-Auto-Coots.thepaperpilot.repl.co");
|
||||
|
||||
watch(
|
||||
() => settings.server,
|
||||
server => {
|
||||
if (socket.value) {
|
||||
socket.value.close();
|
||||
}
|
||||
|
||||
socket.value = io(server);
|
||||
setupSocket(socket.value);
|
||||
|
||||
connected.value = false;
|
||||
connectionError.value = "";
|
||||
socket.value.connect();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
registerSettingField(
|
||||
jsx(() => (
|
||||
<>
|
||||
<Text
|
||||
title="Server URL"
|
||||
onUpdate:modelValue={value => (settings.server = value)}
|
||||
modelValue={settings.server}
|
||||
/>
|
||||
<div style="font-style: italic; font-size: small; margin-top: -10px;">
|
||||
{connected.value ? (
|
||||
<span>Connected!</span>
|
||||
) : connectionError.value ? (
|
||||
<span style="color: red">{connectionError.value}</span>
|
||||
) : (
|
||||
<span>Connecting...</span>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
))
|
||||
);
|
||||
});
|
||||
|
||||
function setupSocket(socket: Socket<ServerToClientEvents, ClientToServerEvents>) {
|
||||
socket.on("connect", () => {
|
||||
connectionError.value = "";
|
||||
connected.value = true;
|
||||
});
|
||||
socket.on("connect_error", error => {
|
||||
connectionError.value = `${error.name}: ${error.message}`;
|
||||
});
|
||||
socket.on("disconnect", (reason, details) => {
|
||||
connectionError.value =
|
||||
details instanceof Error
|
||||
? `${details.name}: ${details.message}`
|
||||
: details?.description ?? reason;
|
||||
connected.value = false;
|
||||
});
|
||||
socket.on("server version", semver => {
|
||||
if (!satisfies(projInfo.versionNumber, semver)) {
|
||||
toast.info("Server only accepts game versions in range: " + semver);
|
||||
socket.disconnect();
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("info", message => {
|
||||
toast.info(message);
|
||||
});
|
||||
socket.on("nickname", nick => {
|
||||
nickname.value = nick;
|
||||
});
|
||||
|
||||
socket.on("shop", shop => {
|
||||
main.shop.value = shop;
|
||||
});
|
||||
}
|
||||
|
||||
declare module "game/settings" {
|
||||
interface Settings {
|
||||
server: string;
|
||||
}
|
||||
}
|
18
src/data/types.d.ts
vendored
Normal file
18
src/data/types.d.ts
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
interface CharacterInfo {
|
||||
nickname: string;
|
||||
initialRelevancy: number;
|
||||
}
|
||||
|
||||
interface Character {
|
||||
type: string;
|
||||
relevancy: number;
|
||||
}
|
||||
|
||||
interface ServerToClientEvents {
|
||||
"server version": (semver: string) => void;
|
||||
nickname: (nickname: string) => void;
|
||||
info: (message: string) => void;
|
||||
shop: (shop: string[]) => void;
|
||||
}
|
||||
|
||||
interface ClientToServerEvents {}
|
Loading…
Reference in a new issue