Initial stuff

This commit is contained in:
thepaperpilot 2023-02-16 22:43:03 -06:00
parent bfd14e6288
commit 15b7d6adbc
10 changed files with 250 additions and 162 deletions

14
package-lock.json generated
View file

@ -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",

View file

@ -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",

View file

@ -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>

View file

@ -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>

View 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>

View file

@ -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;

View file

@ -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.

View file

@ -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
View 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
View 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 {}