Implement stream types (effect NYI)
|
@ -35,7 +35,11 @@
|
|||
<link rel="prefetch" href="shop_Sell1.png" />
|
||||
<link rel="prefetch" href="Freeze shop.png" />
|
||||
<link rel="prefetch" href="Kitchen BG.png" />
|
||||
<link rel="prefetch" href="lud's room bg.png" />
|
||||
<link rel="prefetch" href="the yard bg.png" />
|
||||
<link rel="prefetch" href="mogul money bg.png" />
|
||||
<link rel="prefetch" href="game window.png" />
|
||||
<link rel="prefetch" href="bro vs bro bg.png" />
|
||||
<link rel="prefetch" href="cat.png" />
|
||||
<link rel="prefetch" href="Shadow.png" />
|
||||
<link rel="prefetch" href="shop window.png" />
|
||||
|
@ -71,6 +75,7 @@
|
|||
<link rel="prefetch" href="streamer award coots.png" />
|
||||
<link rel="prefetch" href="aimen coots.png" />
|
||||
<link rel="prefetch" href="mogul moves coots.png" />
|
||||
<link rel="prefetch" href="stream type.png" />
|
||||
|
||||
<title>Profectus</title>
|
||||
<meta name="description" content="A project made in Profectus"/>
|
||||
|
|
Before Width: | Height: | Size: 481 B After Width: | Height: | Size: 3.4 KiB |
BIN
public/bro vs bro bg.png
Normal file
After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 16 KiB |
BIN
public/lud's room bg.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
public/mogul money bg.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
public/stream type.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
public/the yard bg.png
Normal file
After Width: | Height: | Size: 45 KiB |
|
@ -13,9 +13,10 @@
|
|||
</template>
|
||||
<template v-slot:body="{ shown }">
|
||||
<div v-if="shown">
|
||||
<div v-if="author">By {{ author }}</div>
|
||||
<div>Programming by thepaperpilot (with love and support from his wife)</div>
|
||||
<div>Art by crea</div>
|
||||
<div>
|
||||
Made in Profectus, by thepaperpilot
|
||||
Made in Profectus, a game engine by thepaperpilot
|
||||
</div>
|
||||
<br />
|
||||
<div class="link" @click="openChangelog">Changelog</div>
|
||||
|
|
|
@ -179,8 +179,7 @@ watchEffect(() => {
|
|||
|
||||
.character-display img {
|
||||
image-rendering: pixelated;
|
||||
width: 10vmin;
|
||||
height: 10vmin;
|
||||
max-height: 10vmin;
|
||||
filter: drop-shadow(2px 4px 6px black);
|
||||
}
|
||||
|
||||
|
@ -280,6 +279,7 @@ watchEffect(() => {
|
|||
top: -75%;
|
||||
left: 50%;
|
||||
animation: bouncingMoveIndicator 1s infinite;
|
||||
text-shadow: -1px 1px 0 var(--raised-background), 1px 1px 0 var(--raised-background), 1px -1px 0 var(--raised-background), -1px -1px 0 var(--raised-background);
|
||||
}
|
||||
.move-indicator .material-icons {
|
||||
font-size: 5vmin;
|
||||
|
@ -289,6 +289,7 @@ watchEffect(() => {
|
|||
.character:not(.isDragging):hover .move-indicator .material-icons,
|
||||
.character.draggingOver .move-indicator .material-icons {
|
||||
color: var(--feature-foreground);
|
||||
text-shadow: -1px 1px 0 var(--foreground), 1px 1px 0 var(--foreground), 1px -1px 0 var(--foreground), -1px -1px 0 var(--foreground);
|
||||
}
|
||||
|
||||
.frozen {
|
||||
|
|
|
@ -1,14 +1,27 @@
|
|||
.inner-tab {
|
||||
background: url("../../public/Kitchen BG.png");
|
||||
.stream-bg {
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
z-index: -10;
|
||||
}
|
||||
|
||||
.stream-container .stream-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.game-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100% - 5vmin);
|
||||
padding-top: 5vmin;
|
||||
height: calc(100% - 13vmin + 100px);
|
||||
margin-top: calc(10vmin - 50px);
|
||||
margin-left: calc(3vmin - 10px);
|
||||
margin-right: calc(3vmin - 10px);
|
||||
margin-bottom: calc(3vmin - 50px);
|
||||
}
|
||||
|
||||
.game-container::before {
|
||||
|
@ -106,6 +119,44 @@
|
|||
margin-right: 1vmin !important;
|
||||
}
|
||||
|
||||
.stream-types .row {
|
||||
border-image: url("../../public/stream type.png");
|
||||
border-image-slice: 81 54 54 756 fill;
|
||||
border-style: solid;
|
||||
border-width: 3.75vmin 2.5vmin 2.5vmin 35vmin;
|
||||
width: 54vmin;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.stream-types .row > * {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.stream-type {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1vmin 0 0.5vmin 0;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stream-type.active {
|
||||
background-color: var(--raised-background);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
.stream-type img {
|
||||
width: 6vmin;
|
||||
aspect-ratio: 1/1;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
.stream-types > .row > *:first-child {
|
||||
margin-left: -32vmin;
|
||||
}
|
||||
|
||||
.shop {
|
||||
position: relative;
|
||||
filter: drop-shadow(2px 4px 6px black);
|
||||
|
@ -119,6 +170,12 @@
|
|||
width: 54vmin;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.no-margin .row {
|
||||
margin: 0;
|
||||
flex-flow: row;
|
||||
}
|
||||
|
||||
.shop .row::after {
|
||||
|
@ -140,7 +197,7 @@
|
|||
}
|
||||
|
||||
.reroll {
|
||||
margin: auto -2vmin;
|
||||
margin: auto -1vmin;
|
||||
height: 18vmin;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
@ -202,6 +259,7 @@
|
|||
position: relative;
|
||||
background: var(--background);
|
||||
filter: drop-shadow(2px 4px 6px black);
|
||||
text-shadow: -1px 1px 0 var(--raised-background), 1px 1px 0 var(--raised-background), 1px -1px 0 var(--raised-background), -1px -1px 0 var(--raised-background);
|
||||
}
|
||||
|
||||
.stream-details {
|
||||
|
|
|
@ -12,17 +12,31 @@ import settings from "game/settings";
|
|||
import { formatWhole } from "util/bignum";
|
||||
import { render } from "util/vue";
|
||||
import { computed, ref, TransitionGroup, watch } from "vue";
|
||||
import aimen from "../../public/aimen coots.png";
|
||||
import autoplay from "../../public/autoplay.png";
|
||||
import connor from "../../public/cdawg va.png";
|
||||
import chessboxing from "../../public/chessboxing coots.png";
|
||||
import defeatButton from "../../public/Defeat Button.png";
|
||||
import defeatFace from "../../public/defeat face.png";
|
||||
import fast from "../../public/fast forward.png";
|
||||
import freezeShop from "../../public/Freeze shop.png";
|
||||
import frog from "../../public/frog Coots.png";
|
||||
import hasan from "../../public/hasan coots.png";
|
||||
import heart_small from "../../public/heart_small.png";
|
||||
import ironmouse from "../../public/ironmouse coots.png";
|
||||
import kitchen from "../../public/Kitchen BG.png";
|
||||
import reaction from "../../public/lud's room bg.png";
|
||||
import luddy from "../../public/luddy Coots.png";
|
||||
import ludwig from "../../public/Ludwig Coots.png";
|
||||
import maid from "../../public/Maid Coots.png";
|
||||
import mario from "../../public/mario coots.png";
|
||||
import mail from "../../public/Mogul Mail Coots.png";
|
||||
import gameshow from "../../public/mogul money bg.png";
|
||||
import money from "../../public/Mogul Money Coots.png";
|
||||
import moves from "../../public/mogul moves coots.png";
|
||||
import money_small from "../../public/money_small.png";
|
||||
import beast from "../../public/mr beast coots.png";
|
||||
import nick from "../../public/nick coots.png";
|
||||
import coots from "../../public/Normal Coots.png";
|
||||
import playAgain from "../../public/Play Again.png";
|
||||
import play from "../../public/play.png";
|
||||
|
@ -31,33 +45,32 @@ import qt from "../../public/QT Coots.png";
|
|||
import shopGif from "../../public/shop.gif";
|
||||
import shopStill from "../../public/shop1.png";
|
||||
import sellShop from "../../public/shop_Sell1.png";
|
||||
import slime from "../../public/SlimeCoots.png";
|
||||
import smash from "../../public/smash coots.png";
|
||||
import stanz from "../../public/Stanz Coots.png";
|
||||
import startStream from "../../public/start stream.png";
|
||||
import awards from "../../public/streamer award coots.png";
|
||||
import yard from "../../public/the yard bg.png";
|
||||
import game from "../../public/bro vs bro bg.png";
|
||||
import tieButton from "../../public/Tie Button.png";
|
||||
import vespa from "../../public/Vespa Coots.png";
|
||||
import victoryButton from "../../public/Victory Button.png";
|
||||
import victoryFace from "../../public/win face.png";
|
||||
import connor from "../../public/cdawg va.png";
|
||||
import chessboxing from "../../public/chessboxing coots.png";
|
||||
import frog from "../../public/frog Coots.png";
|
||||
import hasan from "../../public/hasan coots.png";
|
||||
import ironmouse from "../../public/ironmouse coots.png";
|
||||
import luddy from "../../public/luddy Coots.png";
|
||||
import mario from "../../public/mario coots.png";
|
||||
import beast from "../../public/mr beast coots.png";
|
||||
import nick from "../../public/nick coots.png";
|
||||
import slime from "../../public/SlimeCoots.png";
|
||||
import smash from "../../public/smash coots.png";
|
||||
import awards from "../../public/streamer award coots.png";
|
||||
import aimen from "../../public/aimen coots.png";
|
||||
import moves from "../../public/mogul moves coots.png";
|
||||
import CharacterSlot from "./CharacterSlot.vue";
|
||||
import "./common.css";
|
||||
import "./socket";
|
||||
import { emit, nickname } from "./socket";
|
||||
import type { AbilityTypes, BattleOutcome, Character, CharacterInfo } from "./types";
|
||||
import type { AbilityTypes, BattleOutcome, Character, CharacterInfo, StreamTypes } from "./types";
|
||||
import victoryParticles from "./victory.json";
|
||||
|
||||
const streamTypeToBG: Record<StreamTypes, string> = {
|
||||
"Game Show": gameshow,
|
||||
"Reaction Stream": reaction,
|
||||
Podcast: yard,
|
||||
"Cooking Stream": kitchen,
|
||||
"Bro vs Bro": game
|
||||
};
|
||||
|
||||
export const characters: Record<string, CharacterInfo> = {
|
||||
// Tier 1
|
||||
coots: {
|
||||
|
@ -177,7 +190,7 @@ export const characters: Record<string, CharacterInfo> = {
|
|||
<>
|
||||
<i>Sold</i>: Give {char.exp >= 6 ? 3 : char.exp >= 3 ? 2 : 1}{" "}
|
||||
<img src={heart_small} />
|
||||
<span style="color: red">Relevancy</span> to leftmost Coots
|
||||
<span style="color: red">Relevancy</span> to rightmost Coots
|
||||
</>
|
||||
)),
|
||||
performAbility(char) {
|
||||
|
@ -698,6 +711,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
>([]);
|
||||
const frozen = ref<number[]>([]);
|
||||
const showRefreshAnim = ref<boolean>(false);
|
||||
const streamType = ref<StreamTypes>("Cooking Stream");
|
||||
|
||||
const battle = ref<{
|
||||
team: Character[];
|
||||
|
@ -708,6 +722,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
enemyLives: number;
|
||||
enemyWins: number;
|
||||
enemyTurn: number;
|
||||
enemyStreamType: StreamTypes;
|
||||
ranLivestreamEnded: boolean;
|
||||
} | null>(null);
|
||||
|
||||
|
@ -751,6 +766,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
playClicked.value = false;
|
||||
queue.value = [];
|
||||
frozen.value = [];
|
||||
streamType.value = "Cooking Stream";
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -942,6 +958,14 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
>
|
||||
<div class="team-container">
|
||||
<div class="stream-container">
|
||||
<div
|
||||
class="stream-bg"
|
||||
style={{
|
||||
backgroundImage: `url("${
|
||||
streamTypeToBG[streamType.value]
|
||||
}")`
|
||||
}}
|
||||
/>
|
||||
<div class="stream-details" style="left: 1vmin">
|
||||
<span>{nickname.value} (YOU)</span>
|
||||
<div class="stats">
|
||||
|
@ -991,6 +1015,14 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
</div>
|
||||
<div class="team-container">
|
||||
<div class="stream-container">
|
||||
<div
|
||||
class="stream-bg"
|
||||
style={{
|
||||
backgroundImage: `url("${
|
||||
streamTypeToBG[battle.value.enemyStreamType]
|
||||
}")`
|
||||
}}
|
||||
/>
|
||||
<div class="stream-details" style="right: 1vmin">
|
||||
<span>{battle.value.enemyNickname}</span>
|
||||
<div class="stats" style="margin-right: 0">
|
||||
|
@ -1067,6 +1099,10 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
selectedShopItem.value = null;
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class="stream-bg"
|
||||
style={{ backgroundImage: `url("${streamTypeToBG[streamType.value]}")` }}
|
||||
/>
|
||||
<h2 class="team-nickname">{nickname.value}</h2>
|
||||
<Row class="manager-header">
|
||||
<div class="resource-box moguls">{gold.value}</div>
|
||||
|
@ -1121,7 +1157,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
/>
|
||||
))}
|
||||
</Row>
|
||||
<Row style="margin-top: 10vh;">
|
||||
<Row style="margin-top: 2vh" class="no-margin">
|
||||
{selectedCharacter.value != null ? (
|
||||
<Tooltip display="Sell Coots">
|
||||
<div
|
||||
|
@ -1195,6 +1231,107 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
))}
|
||||
</Row>
|
||||
</Row>
|
||||
<Row class="stream-types">
|
||||
<Tooltip display="Moguls persist (still gain 10 after battle)">
|
||||
<div
|
||||
class={{
|
||||
"stream-type": true,
|
||||
active: streamType.value === "Game Show"
|
||||
}}
|
||||
onClick={() => emit("change stream type", "Game Show")}
|
||||
>
|
||||
<img src={gameshow} />
|
||||
<span>Game Show</span>
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
display={jsx(() => (
|
||||
<>
|
||||
<i>Stream started</i>: All Coots permanently gain 1
|
||||
<img src={heart_small} />
|
||||
<span style="color: red">Relevancy</span>
|
||||
</>
|
||||
))}
|
||||
>
|
||||
<div
|
||||
class={{
|
||||
"stream-type": true,
|
||||
active: streamType.value === "Reaction Stream"
|
||||
}}
|
||||
onClick={() => emit("change stream type", "Reaction Stream")}
|
||||
>
|
||||
<img src={reaction} />
|
||||
<span>Coots</span>
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
display={jsx(() => (
|
||||
<>
|
||||
<i>Stream started</i>: All Yard Coots gain 1
|
||||
<img src={heart_small} />
|
||||
<span style="color: red">Relevancy</span> for every Yard Coots
|
||||
owned, for the rest of the battle
|
||||
</>
|
||||
))}
|
||||
>
|
||||
<div
|
||||
class={{
|
||||
"stream-type": true,
|
||||
active: streamType.value === "Podcast"
|
||||
}}
|
||||
onClick={() => emit("change stream type", "Podcast")}
|
||||
>
|
||||
<img src={yard} />
|
||||
<span>Podcast</span>
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
display={jsx(() => (
|
||||
<>
|
||||
<i>Stream started</i>: Give the rightmost Coots 2
|
||||
<img src={heart_small} />
|
||||
<span style="color: red">Relevancy</span> and
|
||||
<img src={star_small} />
|
||||
<span style="color: gold">Presence</span> for the rest of the
|
||||
battle
|
||||
</>
|
||||
))}
|
||||
>
|
||||
<div
|
||||
class={{
|
||||
"stream-type": true,
|
||||
active: streamType.value === "Cooking Stream"
|
||||
}}
|
||||
onClick={() => emit("change stream type", "Cooking Stream")}
|
||||
>
|
||||
<img src={kitchen} />
|
||||
<span>Cooking</span>
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
display={jsx(() => (
|
||||
<>
|
||||
<i>Stream started</i>: Give 1
|
||||
<img src={heart_small} />
|
||||
<span style="color: red">Relevancy</span> to the rightmost Coots
|
||||
for the rest of the battle and deal 2 <img src={heart_small} />
|
||||
<span style="color: red">Relevancy</span> damage to the leftmost
|
||||
enemy Coots for the rest of the battle
|
||||
</>
|
||||
))}
|
||||
>
|
||||
<div
|
||||
class={{
|
||||
"stream-type": true,
|
||||
active: streamType.value === "Bro vs Bro"
|
||||
}}
|
||||
onClick={() => emit("change stream type", "Bro vs Bro")}
|
||||
>
|
||||
<img src={game} />
|
||||
<span>Reaction</span>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Row>
|
||||
{render(particles)}
|
||||
</div>
|
||||
);
|
||||
|
@ -1218,7 +1355,8 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
particles,
|
||||
queue,
|
||||
showRefreshAnim,
|
||||
hurt
|
||||
hurt,
|
||||
streamType
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"title": "Super Auto Coots",
|
||||
"description": "A project made in Profectus",
|
||||
"id": "superautocoots",
|
||||
"author": "thepaperpilot (with love and support from his wife) and crea",
|
||||
"author": "",
|
||||
"discordName": "",
|
||||
"discordLink": "",
|
||||
|
||||
|
|
|
@ -9,7 +9,13 @@ import { ref, watch } from "vue";
|
|||
import { useToast } from "vue-toastification";
|
||||
import particle from "./particle.json";
|
||||
import { characters, main } from "./projEntry";
|
||||
import { BattleOutcome, Character, ClientToServerEvents, ServerToClientEvents } from "./types";
|
||||
import {
|
||||
BattleOutcome,
|
||||
Character,
|
||||
ClientToServerEvents,
|
||||
ServerToClientEvents,
|
||||
StreamTypes
|
||||
} from "./types";
|
||||
|
||||
export const connected = ref<boolean>(false);
|
||||
export const nickname = ref<string>("");
|
||||
|
@ -237,8 +243,9 @@ function setupSocket(socket: Socket<ServerToClientEvents, ClientToServerEvents>)
|
|||
main.frozen.value.push(index);
|
||||
}
|
||||
});
|
||||
socket.on("room", r => {
|
||||
socket.on("room", (r, streamType) => {
|
||||
main.reset.reset();
|
||||
main.streamType.value = streamType;
|
||||
room.value = r;
|
||||
roomConnectionError.value = "";
|
||||
});
|
||||
|
@ -246,6 +253,12 @@ function setupSocket(socket: Socket<ServerToClientEvents, ClientToServerEvents>)
|
|||
room.value = "";
|
||||
roomConnectionError.value = err;
|
||||
});
|
||||
socket.on("stream type", (type, charged) => {
|
||||
main.streamType.value = type;
|
||||
if (charged) {
|
||||
main.gold.value -= 3;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function startStream(
|
||||
|
@ -255,6 +268,7 @@ function startStream(
|
|||
lives: number;
|
||||
wins: number;
|
||||
turn: number;
|
||||
streamType: StreamTypes;
|
||||
},
|
||||
outcome: BattleOutcome
|
||||
) {
|
||||
|
@ -268,6 +282,7 @@ function startStream(
|
|||
enemyLives: enemy.lives,
|
||||
enemyWins: enemy.wins,
|
||||
enemyTurn: enemy.turn,
|
||||
enemyStreamType: enemy.streamType,
|
||||
ranLivestreamEnded: false
|
||||
};
|
||||
main.outcome.value = outcome;
|
||||
|
|
7
src/data/types.d.ts
vendored
|
@ -10,6 +10,8 @@ type AbilityTypes =
|
|||
| "Hurt"
|
||||
| "Faint";
|
||||
|
||||
type StreamTypes = "Game Show" | "Reaction Stream" | "Podcast" | "Cooking Stream" | "Bro vs Bro";
|
||||
|
||||
interface CharacterInfo {
|
||||
nickname: string;
|
||||
initialRelevancy: number;
|
||||
|
@ -45,13 +47,15 @@ interface ServerToClientEvents {
|
|||
lives: number;
|
||||
wins: number;
|
||||
turn: number;
|
||||
streamType: StreamTypes;
|
||||
},
|
||||
outcome: BattleOutcome
|
||||
) => void;
|
||||
freeze: (index: number) => void;
|
||||
sell: (index: number) => void;
|
||||
room: (room: string) => void;
|
||||
room: (room: string, streamType: StreamTypes) => void;
|
||||
"room failed": (err: string) => void;
|
||||
"stream type": (type: StreamTypes, charge: boolean) => void;
|
||||
}
|
||||
|
||||
interface ClientToServerEvents {
|
||||
|
@ -64,4 +68,5 @@ interface ClientToServerEvents {
|
|||
stream: () => void;
|
||||
newTurn: () => void;
|
||||
"change room": (room: string, password: string) => void;
|
||||
"change stream type": (type: StreamTypes) => void;
|
||||
}
|
||||
|
|