More effects

This commit is contained in:
thepaperpilot 2023-02-25 20:58:12 -06:00
parent b3bdad5521
commit c852693b00
6 changed files with 409 additions and 29 deletions

View file

@ -265,7 +265,6 @@
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);
z-index: 1;
overflow: hidden;
}
.stream-details {
@ -357,7 +356,8 @@
transform: translateY(100%);
}
.streamer-transition-leave-to {
transform: translateY(100%);
transform: translateY(50%) rotate(45deg);
opacity: 0;
}
.character-trensition-active,
.streamer-transition-active {

116
src/data/health.json Normal file
View file

@ -0,0 +1,116 @@
{
"lifetime": {
"min": 1.5,
"max": 2.5
},
"ease": [
{
"s": 0,
"cp": 0.329,
"e": 0.548
},
{
"s": 0.548,
"cp": 0.767,
"e": 0.876
},
{
"s": 0.876,
"cp": 0.985,
"e": 1
}
],
"frequency": 0.001,
"emitterLifetime": 0.1,
"maxParticles": 1,
"addAtBack": true,
"pos": {
"x": 0,
"y": 0
},
"emit": false,
"behaviors": [
{
"type": "alpha",
"config": {
"alpha": {
"list": [
{
"time": 0,
"value": 0.74
},
{
"time": 1,
"value": 0
}
]
}
}
},
{
"type": "moveAcceleration",
"config": {
"accel": {
"x": 0,
"y": -200
},
"minStart": 60,
"maxStart": 60,
"rotate": false
}
},
{
"type": "scale",
"config": {
"scale": {
"list": [
{
"time": 0,
"value": 0.5
},
{
"time": 1,
"value": 0.25
}
]
},
"minMult": 1
}
},
{
"type": "rotation",
"config": {
"accel": 0,
"minSpeed": 0,
"maxSpeed": 200,
"minStart": 0,
"maxStart": 360
}
},
{
"type": "textureRandom",
"config": {
"textures": [
"heart_small.png"
]
}
},
{
"type": "spawnShape",
"config": {
"type": "torus",
"data": {
"radius": 100,
"x": 0,
"y": 0
}
}
},
{
"type": "noRotation",
"config": {
"rotation": 0
}
}
]
}

116
src/data/presence.json Normal file
View file

@ -0,0 +1,116 @@
{
"lifetime": {
"min": 1.5,
"max": 2.5
},
"ease": [
{
"s": 0,
"cp": 0.329,
"e": 0.548
},
{
"s": 0.548,
"cp": 0.767,
"e": 0.876
},
{
"s": 0.876,
"cp": 0.985,
"e": 1
}
],
"frequency": 0.001,
"emitterLifetime": 0.1,
"maxParticles": 1,
"addAtBack": true,
"pos": {
"x": 0,
"y": 0
},
"emit": false,
"behaviors": [
{
"type": "alpha",
"config": {
"alpha": {
"list": [
{
"time": 0,
"value": 0.74
},
{
"time": 1,
"value": 0
}
]
}
}
},
{
"type": "moveAcceleration",
"config": {
"accel": {
"x": 0,
"y": -200
},
"minStart": 60,
"maxStart": 60,
"rotate": false
}
},
{
"type": "scale",
"config": {
"scale": {
"list": [
{
"time": 0,
"value": 0.5
},
{
"time": 1,
"value": 0.25
}
]
},
"minMult": 1
}
},
{
"type": "rotation",
"config": {
"accel": 0,
"minSpeed": 0,
"maxSpeed": 200,
"minStart": 0,
"maxStart": 360
}
},
{
"type": "textureRandom",
"config": {
"textures": [
"presence_small.png"
]
}
},
{
"type": "spawnShape",
"config": {
"type": "torus",
"data": {
"radius": 100,
"x": 0,
"y": 0
}
}
},
{
"type": "noRotation",
"config": {
"rotation": 0
}
}
]
}

View file

@ -59,9 +59,11 @@ import victoryFace from "../../public/win face.png";
import CharacterSlot from "./CharacterSlot.vue";
import "./common.css";
import "./socket";
import { emit, nickname } from "./socket";
import { emit, nickname, poof } from "./socket";
import type { AbilityTypes, BattleOutcome, Character, CharacterInfo, StreamTypes } from "./types";
import victoryParticles from "./victory.json";
import healthParticles from "./health.json";
import presenceParticles from "./presence.json";
const streamTypeToBG: Record<StreamTypes, string> = {
"Game Show": gameshow,
@ -71,6 +73,11 @@ const streamTypeToBG: Record<StreamTypes, string> = {
"Bro vs Bro": game
};
let nextCharID = 0;
export function getCharID() {
return nextCharID++;
}
export const characters: Record<string, CharacterInfo> = {
// Tier 1
coots: {
@ -120,8 +127,20 @@ export const characters: Record<string, CharacterInfo> = {
const presenceGain = char.exp >= 6 ? 3 : char.exp >= 3 ? 2 : 1;
if (main.battle.value.streamers.includes(char)) {
char.presence += presenceGain * main.battle.value.streamers.length;
for (let i = 0; i < presenceGain * main.battle.value.streamers.length; i++) {
poof(
`battle-streamer-${main.battle.value.streamers.indexOf(char)}`,
presenceParticles
);
}
} else {
char.presence += presenceGain * main.battle.value.enemyStreamers.length;
for (let i = 0; i < presenceGain * main.battle.value.enemyStreamers.length; i++) {
poof(
`battle-enemy-streamer-${main.battle.value.enemyStreamers.indexOf(char)}`,
presenceParticles
);
}
}
}
},
@ -200,6 +219,9 @@ export const characters: Record<string, CharacterInfo> = {
}
const relevancyGain = char.exp >= 6 ? 3 : char.exp >= 3 ? 2 : 1;
team[team.length - 1]!.relevancy += relevancyGain;
for (let i = 0; i < relevancyGain; i++) {
poof(`team-char-${team.length - 1}`, healthParticles);
}
}
},
nick: {
@ -222,9 +244,19 @@ export const characters: Record<string, CharacterInfo> = {
}
const gain = char.exp >= 6 ? 3 : char.exp >= 3 ? 2 : 1;
if (main.battle.value.streamers.includes(char)) {
main.battle.value.streamers.forEach(s => (s.presence += gain));
main.battle.value.streamers.forEach((s, index) => {
s.presence += gain;
for (let i = 0; i < gain; i++) {
poof(`battle-streamer-${index}`, presenceParticles);
}
});
} else {
main.battle.value.enemyStreamers.forEach(s => (s.presence += gain));
main.battle.value.enemyStreamers.forEach((s, index) => {
s.presence += gain;
for (let i = 0; i < gain; i++) {
poof(`battle-enemy-streamer-${index}`, presenceParticles);
}
});
}
}
},
@ -250,6 +282,10 @@ export const characters: Record<string, CharacterInfo> = {
if (char) {
char.relevancy += statGain;
char.presence += statGain;
for (let i = 0; i < statGain; i++) {
poof(`team-char-${main.team.value.indexOf(char)}`, healthParticles);
poof(`team-char-${main.team.value.indexOf(char)}`, presenceParticles);
}
}
});
}
@ -279,7 +315,8 @@ export const characters: Record<string, CharacterInfo> = {
type: "ludwig",
exp: level === 3 ? 6 : level === 2 ? 3 : 1,
presence: char.presence,
relevancy: char.relevancy
relevancy: char.relevancy,
id: getCharID()
};
main.queue.value.push({ action: "LivestreamJoined", target: newChar });
if (main.battle.value.streamers.includes(char)) {
@ -362,6 +399,9 @@ export const characters: Record<string, CharacterInfo> = {
main.team.value.forEach(m => {
if (m != null) {
m.relevancy += gain;
for (let i = 0; i < gain * main.wins.value; i++) {
poof(`team-char-${main.team.value.indexOf(char)}`, healthParticles);
}
}
});
}
@ -410,7 +450,8 @@ export const characters: Record<string, CharacterInfo> = {
type: "mail",
exp: level === 3 ? 6 : level === 2 ? 3 : 1,
presence: char.presence,
relevancy: char.relevancy
relevancy: char.relevancy,
id: getCharID()
};
main.queue.value.push({ action: "LivestreamJoined", target: newChar });
if (main.battle.value.streamers.includes(char)) {
@ -441,8 +482,20 @@ export const characters: Record<string, CharacterInfo> = {
const gain = char.exp >= 6 ? 3 : char.exp >= 3 ? 2 : 1;
if (main.battle.value.streamers.includes(char)) {
char.relevancy += gain * main.wins.value;
for (let i = 0; i < gain * main.wins.value; i++) {
poof(
`battle-streamer-${main.battle.value.streamers.indexOf(char)}`,
healthParticles
);
}
} else {
char.relevancy += gain * main.battle.value.enemyWins;
for (let i = 0; i < gain * main.wins.value; i++) {
poof(
`battle-enemy-streamer-${main.battle.value.enemyStreamers.indexOf(char)}`,
healthParticles
);
}
}
}
},
@ -467,6 +520,9 @@ export const characters: Record<string, CharacterInfo> = {
if (main.gold.value >= 2) {
const presenceGain = char.exp >= 6 ? 3 : char.exp >= 3 ? 2 : 1;
char.presence += presenceGain;
for (let i = 0; i < presenceGain; i++) {
poof(`team-char-${i}`, presenceParticles);
}
}
}
},
@ -524,6 +580,9 @@ export const characters: Record<string, CharacterInfo> = {
}
const gain = char.exp >= 6 ? 6 : char.exp >= 3 ? 4 : 2;
char.relevancy += gain;
for (let i = 0; i < gain; i++) {
poof(`battle-streamer-${main.team.value.indexOf(char)}`, healthParticles);
}
}
},
connor: {
@ -548,7 +607,8 @@ export const characters: Record<string, CharacterInfo> = {
type: "ironmouse",
exp: level === 3 ? 6 : level === 2 ? 3 : 1,
presence: characters.ironmouse.initialPresence,
relevancy: characters.ironmouse.initialRelevancy
relevancy: characters.ironmouse.initialRelevancy,
id: getCharID()
};
main.queue.value.push({ action: "LivestreamJoined", target: newChar });
if (main.battle.value.streamers.includes(char)) {
@ -628,11 +688,19 @@ export const characters: Record<string, CharacterInfo> = {
if (main.battle.value.streamers.length > 1) {
main.battle.value.streamers[1].relevancy += gain;
main.battle.value.streamers[1].presence += gain;
for (let i = 0; i < gain; i++) {
poof(`battle-streamer-${1}`, healthParticles);
poof(`battle-streamer-${1}`, presenceParticles);
}
}
} else {
if (main.battle.value.enemyStreamers.length > 1) {
main.battle.value.enemyStreamers[1].relevancy += gain;
main.battle.value.enemyStreamers[1].presence += gain;
for (let i = 0; i < gain; i++) {
poof(`battle-enemy-streamer-${1}`, healthParticles);
poof(`battle-enemy-streamer-${1}`, presenceParticles);
}
}
}
}
@ -682,6 +750,20 @@ export const characters: Record<string, CharacterInfo> = {
const gain = char.exp >= 6 ? 6 : char.exp >= 3 ? 4 : 2;
char.relevancy += gain;
char.presence += gain;
for (let i = 0; i < gain; i++) {
poof(
`battle-${
main.battle.value.streamers.includes(char) ? "" : "enemy-"
}streamer-${1}`,
healthParticles
);
poof(
`battle-${
main.battle.value.streamers.includes(char) ? "" : "enemy-"
}streamer-${1}`,
presenceParticles
);
}
}
}
};
@ -948,7 +1030,10 @@ export const main = createLayer("main", function (this: BaseLayer) {
if (battle.value != null) {
return (
<div class={{ ["battle-container"]: true, fast: settings.fast }}>
<div class="battle-controls">
<div
class="battle-controls"
style={showingOutcome.value ? "pointer-events: none;" : ""}
>
<button
class="button"
onClick={() => {
@ -976,10 +1061,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
<img src={fast} />
</button>
</div>
<div
class="teams-container"
style={showingOutcome.value ? "pointer-events: none;" : ""}
>
<div class="teams-container">
<div class="team-container">
<div class="stream-container">
<div
@ -1007,7 +1089,8 @@ export const main = createLayer("main", function (this: BaseLayer) {
.reverse()
.map((streamer, i) => (
<CharacterSlot
key={battle.value!.streamers.length - i}
id={`battle-streamer-${i}`}
key={streamer.id}
character={streamer}
shake={
previewing.value &&
@ -1022,8 +1105,9 @@ export const main = createLayer("main", function (this: BaseLayer) {
<TransitionGroup name="character-transition">
{battle.value.team.map((member, i) => (
<CharacterSlot
id={`battle-member-${i}`}
character={member}
key={i}
key={member.id}
shake={
previewing.value &&
queue.value[0]?.action === "join" &&
@ -1066,8 +1150,8 @@ export const main = createLayer("main", function (this: BaseLayer) {
<TransitionGroup name="streamer-transition">
{battle.value.enemyStreamers.map((streamer, i) => (
<CharacterSlot
key={i}
character={streamer}
id={`battle-enemy-streamer-${i}`}
key={streamer.id}
shake={
previewing.value &&
queue.value[0]?.target === streamer
@ -1081,8 +1165,9 @@ export const main = createLayer("main", function (this: BaseLayer) {
<TransitionGroup name="character-transition">
{battle.value.enemyTeam.map((member, i) => (
<CharacterSlot
id={`battle-enemy-member-${i}`}
character={member}
key={battle.value!.enemyStreamers.length + i}
key={member.id}
shake={
previewing.value &&
queue.value[0]?.action === "join" &&
@ -1112,6 +1197,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
/>
</div>
) : null}
{render(particles)}
</div>
);
}
@ -1293,7 +1379,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
<Tooltip
display={jsx(() => (
<>
<i>Stream started</i>: All Yard Coots gain 1
<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
@ -1314,9 +1400,9 @@ export const main = createLayer("main", function (this: BaseLayer) {
<Tooltip
display={jsx(() => (
<>
<i>Stream started</i>: Give the rightmost Coots 2
<i>Stream started</i>: Give the rightmost Coots 2{" "}
<img src={heart_small} />
<span style="color: red">Relevancy</span> and
<span style="color: red">Relevancy</span> and{" "}
<img src={star_small} />
<span style="color: gold">Presence</span> for the rest of the
battle
@ -1337,8 +1423,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
<Tooltip
display={jsx(() => (
<>
<i>Stream started</i>: Give 1
<img src={heart_small} />
<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

View file

@ -8,7 +8,7 @@ import { io, Socket } from "socket.io-client";
import { ref, watch } from "vue";
import { useToast } from "vue-toastification";
import particle from "./particle.json";
import { characters, main } from "./projEntry";
import { characters, getCharID, main } from "./projEntry";
import {
BattleOutcome,
Character,
@ -16,6 +16,9 @@ import {
ServerToClientEvents,
StreamTypes
} from "./types";
import healthParticles from "./health.json";
import presenceParticles from "./presence.json";
import { EmitterConfigV3 } from "@pixi/particle-emitter";
export const connected = ref<boolean>(false);
export const nickname = ref<string>("");
@ -79,14 +82,14 @@ globalBus.on("loadSettings", settings => {
);
});
function poof(id: string) {
export function poof(id: string, particleConfig?: EmitterConfigV3) {
const boundingRect = main.particles.boundingRect.value;
if (!boundingRect) {
return;
}
const rect = main.nodes.value[id]?.rect;
if (rect) {
main.particles.addEmitter(particle).then(e => {
main.particles.addEmitter(particleConfig ?? particle).then(e => {
e.updateOwnerPos(
rect.x + rect.width / 2 - boundingRect.x,
rect.y + rect.height / 2 - boundingRect.y
@ -146,7 +149,8 @@ function setupSocket(socket: Socket<ServerToClientEvents, ClientToServerEvents>)
type: item,
relevancy: characters[item].initialRelevancy,
presence: characters[item].initialPresence,
exp: 1
exp: 1,
id: getCharID()
}));
main.frozen.value = main.frozen.value.map((_, i) => i);
setTimeout(() => {
@ -168,7 +172,8 @@ function setupSocket(socket: Socket<ServerToClientEvents, ClientToServerEvents>)
type: item,
relevancy: characters[item].initialRelevancy,
presence: characters[item].initialPresence,
exp: 1
exp: 1,
id: getCharID()
}));
main.frozen.value = main.frozen.value.map((_, i) => i);
setTimeout(() => {
@ -209,11 +214,12 @@ function setupSocket(socket: Socket<ServerToClientEvents, ClientToServerEvents>)
socket.on("stream", (enemy, outcome) => {
let needsWait = false;
if (main.streamType.value === "Reaction Stream") {
main.team.value.forEach(m => {
main.team.value.forEach((m, index) => {
if (m == null) {
return;
}
m.relevancy += 1;
poof(`team-char-${index}`, healthParticles);
});
needsWait = true;
}
@ -298,6 +304,10 @@ function startStream(
enemyStreamType: enemy.streamType,
ranLivestreamEnded: false
};
main.battle.value.enemyTeam.forEach(m => {
m.id = getCharID();
});
console.log(enemy.team, main.battle.value.enemyTeam);
main.outcome.value = outcome;
main.showingOutcome.value = false;
main.playClicked.value = false;
@ -314,6 +324,12 @@ function startStream(
);
yards.forEach(m => {
m.relevancy += yards.length;
for (let i = 0; i < yards.length; i++) {
poof(
`battle-enemy-member-${main.battle.value!.enemyTeam.indexOf(m)}`,
healthParticles
);
}
});
setTimeout(main.prepareMove, 1250);
}, 1250);
@ -324,6 +340,22 @@ function startStream(
main.battle.value!.enemyTeam[main.battle.value!.enemyTeam.length - 1];
host.relevancy += 2;
host.presence += 2;
poof(
`battle-enemy-member-${main.battle.value!.enemyTeam.indexOf(host)}`,
healthParticles
);
poof(
`battle-enemy-member-${main.battle.value!.enemyTeam.indexOf(host)}`,
healthParticles
);
poof(
`battle-enemy-member-${main.battle.value!.enemyTeam.indexOf(host)}`,
presenceParticles
);
poof(
`battle-enemy-member-${main.battle.value!.enemyTeam.indexOf(host)}`,
presenceParticles
);
}
setTimeout(main.prepareMove, 1250);
}, 1250);
@ -333,6 +365,10 @@ function startStream(
const host =
main.battle.value!.enemyTeam[main.battle.value!.enemyTeam.length - 1];
host.relevancy++;
poof(
`battle-enemy-member-${main.battle.value!.enemyTeam.indexOf(host)}`,
healthParticles
);
}
if (main.battle.value!.team.length > 0) {
const host = main.battle.value!.team[main.battle.value!.team.length - 1];
@ -357,6 +393,12 @@ function startStream(
);
yards.forEach(m => {
m.relevancy += yards.length;
for (let i = 0; i < yards.length; i++) {
poof(
`battle-member-${main.battle.value!.enemyTeam.indexOf(m)}`,
healthParticles
);
}
});
checkEnemyStreamType();
}, 1250);
@ -366,6 +408,22 @@ function startStream(
const host = main.battle.value!.team[main.battle.value!.team.length - 1];
host.relevancy += 2;
host.presence += 2;
poof(
`battle-member-${main.battle.value!.enemyTeam.indexOf(host)}`,
healthParticles
);
poof(
`battle-member-${main.battle.value!.enemyTeam.indexOf(host)}`,
healthParticles
);
poof(
`battle-member-${main.battle.value!.enemyTeam.indexOf(host)}`,
presenceParticles
);
poof(
`battle-member-${main.battle.value!.enemyTeam.indexOf(host)}`,
presenceParticles
);
}
checkEnemyStreamType();
}, 1250);
@ -374,6 +432,10 @@ function startStream(
if (main.battle.value!.team.length > 0) {
const host = main.battle.value!.team[main.battle.value!.team.length - 1];
host.relevancy++;
poof(
`battle-enemy-member-${main.battle.value!.enemyTeam.indexOf(host)}`,
healthParticles
);
}
if (main.battle.value!.enemyTeam.length > 0) {
const host = main.battle.value!.enemyTeam[main.battle.value!.enemyTeam.length - 1];

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

@ -27,6 +27,7 @@ interface Character {
exp: number;
relevancy: number;
presence: number;
id: number;
}
type BattleOutcome = "Victory" | "Defeat" | "Tie";