Implement stream types (effect NYI)

This commit is contained in:
thepaperpilot 2023-02-25 18:04:21 -06:00
parent 43f52e58aa
commit c57db3384b
15 changed files with 254 additions and 31 deletions

View file

@ -35,7 +35,11 @@
<link rel="prefetch" href="shop_Sell1.png" /> <link rel="prefetch" href="shop_Sell1.png" />
<link rel="prefetch" href="Freeze shop.png" /> <link rel="prefetch" href="Freeze shop.png" />
<link rel="prefetch" href="Kitchen BG.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="game window.png" />
<link rel="prefetch" href="bro vs bro bg.png" />
<link rel="prefetch" href="cat.png" /> <link rel="prefetch" href="cat.png" />
<link rel="prefetch" href="Shadow.png" /> <link rel="prefetch" href="Shadow.png" />
<link rel="prefetch" href="shop window.png" /> <link rel="prefetch" href="shop window.png" />
@ -71,6 +75,7 @@
<link rel="prefetch" href="streamer award coots.png" /> <link rel="prefetch" href="streamer award coots.png" />
<link rel="prefetch" href="aimen coots.png" /> <link rel="prefetch" href="aimen coots.png" />
<link rel="prefetch" href="mogul moves coots.png" /> <link rel="prefetch" href="mogul moves coots.png" />
<link rel="prefetch" href="stream type.png" />
<title>Profectus</title> <title>Profectus</title>
<meta name="description" content="A project made in Profectus"/> <meta name="description" content="A project made in Profectus"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 481 B

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
public/bro vs bro bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 16 KiB

BIN
public/lud's room bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
public/mogul money bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
public/stream type.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
public/the yard bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View file

@ -13,9 +13,10 @@
</template> </template>
<template v-slot:body="{ shown }"> <template v-slot:body="{ shown }">
<div v-if="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> <div>
Made in Profectus, by thepaperpilot Made in Profectus, a game engine by thepaperpilot
</div> </div>
<br /> <br />
<div class="link" @click="openChangelog">Changelog</div> <div class="link" @click="openChangelog">Changelog</div>

View file

@ -179,8 +179,7 @@ watchEffect(() => {
.character-display img { .character-display img {
image-rendering: pixelated; image-rendering: pixelated;
width: 10vmin; max-height: 10vmin;
height: 10vmin;
filter: drop-shadow(2px 4px 6px black); filter: drop-shadow(2px 4px 6px black);
} }
@ -280,6 +279,7 @@ watchEffect(() => {
top: -75%; top: -75%;
left: 50%; left: 50%;
animation: bouncingMoveIndicator 1s infinite; 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 { .move-indicator .material-icons {
font-size: 5vmin; font-size: 5vmin;
@ -289,6 +289,7 @@ watchEffect(() => {
.character:not(.isDragging):hover .move-indicator .material-icons, .character:not(.isDragging):hover .move-indicator .material-icons,
.character.draggingOver .move-indicator .material-icons { .character.draggingOver .move-indicator .material-icons {
color: var(--feature-foreground); 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 { .frozen {

View file

@ -1,14 +1,27 @@
.inner-tab { .stream-bg {
background: url("../../public/Kitchen BG.png"); position: fixed;
top: 50px;
left: 0;
right: 0;
bottom: 0;
background-position: center; background-position: center;
background-size: cover; background-size: cover;
z-index: -10;
}
.stream-container .stream-bg {
position: absolute;
top: 0;
} }
.game-container { .game-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: calc(100% - 5vmin); height: calc(100% - 13vmin + 100px);
padding-top: 5vmin; margin-top: calc(10vmin - 50px);
margin-left: calc(3vmin - 10px);
margin-right: calc(3vmin - 10px);
margin-bottom: calc(3vmin - 50px);
} }
.game-container::before { .game-container::before {
@ -106,6 +119,44 @@
margin-right: 1vmin !important; 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 { .shop {
position: relative; position: relative;
filter: drop-shadow(2px 4px 6px black); filter: drop-shadow(2px 4px 6px black);
@ -119,6 +170,12 @@
width: 54vmin; width: 54vmin;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
margin: 0;
}
.no-margin .row {
margin: 0;
flex-flow: row;
} }
.shop .row::after { .shop .row::after {
@ -140,7 +197,7 @@
} }
.reroll { .reroll {
margin: auto -2vmin; margin: auto -1vmin;
height: 18vmin; height: 18vmin;
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
@ -202,6 +259,7 @@
position: relative; position: relative;
background: var(--background); background: var(--background);
filter: drop-shadow(2px 4px 6px black); 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 { .stream-details {

View file

@ -12,17 +12,31 @@ import settings from "game/settings";
import { formatWhole } from "util/bignum"; import { formatWhole } from "util/bignum";
import { render } from "util/vue"; import { render } from "util/vue";
import { computed, ref, TransitionGroup, watch } from "vue"; import { computed, ref, TransitionGroup, watch } from "vue";
import aimen from "../../public/aimen coots.png";
import autoplay from "../../public/autoplay.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 defeatButton from "../../public/Defeat Button.png";
import defeatFace from "../../public/defeat face.png"; import defeatFace from "../../public/defeat face.png";
import fast from "../../public/fast forward.png"; import fast from "../../public/fast forward.png";
import freezeShop from "../../public/Freeze shop.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 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 ludwig from "../../public/Ludwig Coots.png";
import maid from "../../public/Maid 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 mail from "../../public/Mogul Mail Coots.png";
import gameshow from "../../public/mogul money bg.png";
import money from "../../public/Mogul Money Coots.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 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 coots from "../../public/Normal Coots.png";
import playAgain from "../../public/Play Again.png"; import playAgain from "../../public/Play Again.png";
import play from "../../public/play.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 shopGif from "../../public/shop.gif";
import shopStill from "../../public/shop1.png"; import shopStill from "../../public/shop1.png";
import sellShop from "../../public/shop_Sell1.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 stanz from "../../public/Stanz Coots.png";
import startStream from "../../public/start stream.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 tieButton from "../../public/Tie Button.png";
import vespa from "../../public/Vespa Coots.png"; import vespa from "../../public/Vespa Coots.png";
import victoryButton from "../../public/Victory Button.png"; import victoryButton from "../../public/Victory Button.png";
import victoryFace from "../../public/win face.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 CharacterSlot from "./CharacterSlot.vue";
import "./common.css"; import "./common.css";
import "./socket"; import "./socket";
import { emit, nickname } from "./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"; 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> = { export const characters: Record<string, CharacterInfo> = {
// Tier 1 // Tier 1
coots: { coots: {
@ -177,7 +190,7 @@ export const characters: Record<string, CharacterInfo> = {
<> <>
<i>Sold</i>: Give {char.exp >= 6 ? 3 : char.exp >= 3 ? 2 : 1}{" "} <i>Sold</i>: Give {char.exp >= 6 ? 3 : char.exp >= 3 ? 2 : 1}{" "}
<img src={heart_small} /> <img src={heart_small} />
<span style="color: red">Relevancy</span> to leftmost Coots <span style="color: red">Relevancy</span> to rightmost Coots
</> </>
)), )),
performAbility(char) { performAbility(char) {
@ -698,6 +711,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
>([]); >([]);
const frozen = ref<number[]>([]); const frozen = ref<number[]>([]);
const showRefreshAnim = ref<boolean>(false); const showRefreshAnim = ref<boolean>(false);
const streamType = ref<StreamTypes>("Cooking Stream");
const battle = ref<{ const battle = ref<{
team: Character[]; team: Character[];
@ -708,6 +722,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
enemyLives: number; enemyLives: number;
enemyWins: number; enemyWins: number;
enemyTurn: number; enemyTurn: number;
enemyStreamType: StreamTypes;
ranLivestreamEnded: boolean; ranLivestreamEnded: boolean;
} | null>(null); } | null>(null);
@ -751,6 +766,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
playClicked.value = false; playClicked.value = false;
queue.value = []; queue.value = [];
frozen.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="team-container">
<div class="stream-container"> <div class="stream-container">
<div
class="stream-bg"
style={{
backgroundImage: `url("${
streamTypeToBG[streamType.value]
}")`
}}
/>
<div class="stream-details" style="left: 1vmin"> <div class="stream-details" style="left: 1vmin">
<span>{nickname.value} (YOU)</span> <span>{nickname.value} (YOU)</span>
<div class="stats"> <div class="stats">
@ -991,6 +1015,14 @@ export const main = createLayer("main", function (this: BaseLayer) {
</div> </div>
<div class="team-container"> <div class="team-container">
<div class="stream-container"> <div class="stream-container">
<div
class="stream-bg"
style={{
backgroundImage: `url("${
streamTypeToBG[battle.value.enemyStreamType]
}")`
}}
/>
<div class="stream-details" style="right: 1vmin"> <div class="stream-details" style="right: 1vmin">
<span>{battle.value.enemyNickname}</span> <span>{battle.value.enemyNickname}</span>
<div class="stats" style="margin-right: 0"> <div class="stats" style="margin-right: 0">
@ -1067,6 +1099,10 @@ export const main = createLayer("main", function (this: BaseLayer) {
selectedShopItem.value = null; selectedShopItem.value = null;
}} }}
> >
<div
class="stream-bg"
style={{ backgroundImage: `url("${streamTypeToBG[streamType.value]}")` }}
/>
<h2 class="team-nickname">{nickname.value}</h2> <h2 class="team-nickname">{nickname.value}</h2>
<Row class="manager-header"> <Row class="manager-header">
<div class="resource-box moguls">{gold.value}</div> <div class="resource-box moguls">{gold.value}</div>
@ -1121,7 +1157,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
/> />
))} ))}
</Row> </Row>
<Row style="margin-top: 10vh;"> <Row style="margin-top: 2vh" class="no-margin">
{selectedCharacter.value != null ? ( {selectedCharacter.value != null ? (
<Tooltip display="Sell Coots"> <Tooltip display="Sell Coots">
<div <div
@ -1195,6 +1231,107 @@ export const main = createLayer("main", function (this: BaseLayer) {
))} ))}
</Row> </Row>
</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)} {render(particles)}
</div> </div>
); );
@ -1218,7 +1355,8 @@ export const main = createLayer("main", function (this: BaseLayer) {
particles, particles,
queue, queue,
showRefreshAnim, showRefreshAnim,
hurt hurt,
streamType
}; };
}); });

View file

@ -4,7 +4,7 @@
"title": "Super Auto Coots", "title": "Super Auto Coots",
"description": "A project made in Profectus", "description": "A project made in Profectus",
"id": "superautocoots", "id": "superautocoots",
"author": "thepaperpilot (with love and support from his wife) and crea", "author": "",
"discordName": "", "discordName": "",
"discordLink": "", "discordLink": "",

View file

@ -9,7 +9,13 @@ import { ref, watch } from "vue";
import { useToast } from "vue-toastification"; import { useToast } from "vue-toastification";
import particle from "./particle.json"; import particle from "./particle.json";
import { characters, main } from "./projEntry"; 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 connected = ref<boolean>(false);
export const nickname = ref<string>(""); export const nickname = ref<string>("");
@ -237,8 +243,9 @@ function setupSocket(socket: Socket<ServerToClientEvents, ClientToServerEvents>)
main.frozen.value.push(index); main.frozen.value.push(index);
} }
}); });
socket.on("room", r => { socket.on("room", (r, streamType) => {
main.reset.reset(); main.reset.reset();
main.streamType.value = streamType;
room.value = r; room.value = r;
roomConnectionError.value = ""; roomConnectionError.value = "";
}); });
@ -246,6 +253,12 @@ function setupSocket(socket: Socket<ServerToClientEvents, ClientToServerEvents>)
room.value = ""; room.value = "";
roomConnectionError.value = err; roomConnectionError.value = err;
}); });
socket.on("stream type", (type, charged) => {
main.streamType.value = type;
if (charged) {
main.gold.value -= 3;
}
});
} }
function startStream( function startStream(
@ -255,6 +268,7 @@ function startStream(
lives: number; lives: number;
wins: number; wins: number;
turn: number; turn: number;
streamType: StreamTypes;
}, },
outcome: BattleOutcome outcome: BattleOutcome
) { ) {
@ -268,6 +282,7 @@ function startStream(
enemyLives: enemy.lives, enemyLives: enemy.lives,
enemyWins: enemy.wins, enemyWins: enemy.wins,
enemyTurn: enemy.turn, enemyTurn: enemy.turn,
enemyStreamType: enemy.streamType,
ranLivestreamEnded: false ranLivestreamEnded: false
}; };
main.outcome.value = outcome; main.outcome.value = outcome;

7
src/data/types.d.ts vendored
View file

@ -10,6 +10,8 @@ type AbilityTypes =
| "Hurt" | "Hurt"
| "Faint"; | "Faint";
type StreamTypes = "Game Show" | "Reaction Stream" | "Podcast" | "Cooking Stream" | "Bro vs Bro";
interface CharacterInfo { interface CharacterInfo {
nickname: string; nickname: string;
initialRelevancy: number; initialRelevancy: number;
@ -45,13 +47,15 @@ interface ServerToClientEvents {
lives: number; lives: number;
wins: number; wins: number;
turn: number; turn: number;
streamType: StreamTypes;
}, },
outcome: BattleOutcome outcome: BattleOutcome
) => void; ) => void;
freeze: (index: number) => void; freeze: (index: number) => void;
sell: (index: number) => void; sell: (index: number) => void;
room: (room: string) => void; room: (room: string, streamType: StreamTypes) => void;
"room failed": (err: string) => void; "room failed": (err: string) => void;
"stream type": (type: StreamTypes, charge: boolean) => void;
} }
interface ClientToServerEvents { interface ClientToServerEvents {
@ -64,4 +68,5 @@ interface ClientToServerEvents {
stream: () => void; stream: () => void;
newTurn: () => void; newTurn: () => void;
"change room": (room: string, password: string) => void; "change room": (room: string, password: string) => void;
"change stream type": (type: StreamTypes) => void;
} }