aboutsummaryrefslogtreecommitdiff
path: root/webAO/viewport/utils
diff options
context:
space:
mode:
authorstonedDiscord <Tukz@gmx.de>2022-10-12 18:25:14 +0200
committerstonedDiscord <Tukz@gmx.de>2022-10-12 18:25:14 +0200
commit8a7942c0565298c29edbf0b271d5d7c7f9e56fd8 (patch)
tree67b788f40b7a4713904836de05f0e5876c32bd79 /webAO/viewport/utils
parenta83c8962b68f2cc0a0e22d988b8ff030057454e5 (diff)
parent82983e0c38383ec2602b4f41327342d1c8d0a8fd (diff)
Merge branch 'master' into 2fa
Diffstat (limited to 'webAO/viewport/utils')
-rw-r--r--webAO/viewport/utils/createBlipChannels.ts15
-rw-r--r--webAO/viewport/utils/createMusic.ts13
-rw-r--r--webAO/viewport/utils/createSfxAudio.ts9
-rw-r--r--webAO/viewport/utils/createShoutAudio.ts9
-rw-r--r--webAO/viewport/utils/createTestimonyAudio.ts9
-rw-r--r--webAO/viewport/utils/handleICSpeaking.ts312
-rw-r--r--webAO/viewport/utils/initTestimonyUpdater.ts31
-rw-r--r--webAO/viewport/utils/setSide.ts91
8 files changed, 489 insertions, 0 deletions
diff --git a/webAO/viewport/utils/createBlipChannels.ts b/webAO/viewport/utils/createBlipChannels.ts
new file mode 100644
index 0000000..6296b3b
--- /dev/null
+++ b/webAO/viewport/utils/createBlipChannels.ts
@@ -0,0 +1,15 @@
+import { opusCheck } from "../../dom/opusCheck";
+
+export const createBlipsChannels = () => {
+ const blipSelectors = document.getElementsByClassName(
+ "blipSound"
+ ) as HTMLCollectionOf<HTMLAudioElement>;
+
+ const blipChannels = [...blipSelectors];
+ // Allocate multiple blip audio channels to make blips less jittery
+ blipChannels.forEach((channel: HTMLAudioElement) => (channel.volume = 0.5));
+ blipChannels.forEach(
+ (channel: HTMLAudioElement) => (channel.onerror = opusCheck(channel))
+ );
+ return blipChannels;
+}; \ No newline at end of file
diff --git a/webAO/viewport/utils/createMusic.ts b/webAO/viewport/utils/createMusic.ts
new file mode 100644
index 0000000..9bf5240
--- /dev/null
+++ b/webAO/viewport/utils/createMusic.ts
@@ -0,0 +1,13 @@
+import { opusCheck } from '../../dom/opusCheck'
+
+export const createMusic = () => {
+ const audioChannels = document.getElementsByClassName(
+ "audioChannel"
+ ) as HTMLCollectionOf<HTMLAudioElement>;
+ let music = [...audioChannels];
+ music.forEach((channel: HTMLAudioElement) => (channel.volume = 0.5));
+ music.forEach(
+ (channel: HTMLAudioElement) => (channel.onerror = opusCheck(channel))
+ );
+ return music;
+}; \ No newline at end of file
diff --git a/webAO/viewport/utils/createSfxAudio.ts b/webAO/viewport/utils/createSfxAudio.ts
new file mode 100644
index 0000000..7e03563
--- /dev/null
+++ b/webAO/viewport/utils/createSfxAudio.ts
@@ -0,0 +1,9 @@
+import { AO_HOST } from "../../client/aoHost";
+
+export const createSfxAudio = () => {
+ const sfxAudio = document.getElementById(
+ "client_sfxaudio"
+ ) as HTMLAudioElement;
+ sfxAudio.src = `${AO_HOST}sounds/general/sfx-realization.opus`;
+ return sfxAudio;
+}; \ No newline at end of file
diff --git a/webAO/viewport/utils/createShoutAudio.ts b/webAO/viewport/utils/createShoutAudio.ts
new file mode 100644
index 0000000..8211116
--- /dev/null
+++ b/webAO/viewport/utils/createShoutAudio.ts
@@ -0,0 +1,9 @@
+import { AO_HOST } from "../../client/aoHost";
+
+export const createShoutAudio = () => {
+ const shoutAudio = document.getElementById(
+ "client_shoutaudio"
+ ) as HTMLAudioElement;
+ shoutAudio.src = `${AO_HOST}misc/default/objection.opus`;
+ return shoutAudio;
+}; \ No newline at end of file
diff --git a/webAO/viewport/utils/createTestimonyAudio.ts b/webAO/viewport/utils/createTestimonyAudio.ts
new file mode 100644
index 0000000..2ff98f6
--- /dev/null
+++ b/webAO/viewport/utils/createTestimonyAudio.ts
@@ -0,0 +1,9 @@
+import { AO_HOST } from '../../client/aoHost'
+
+export const createTestimonyAudio = () => {
+ const testimonyAudio = document.getElementById(
+ "client_testimonyaudio"
+ ) as HTMLAudioElement;
+ testimonyAudio.src = `${AO_HOST}sounds/general/sfx-guilty.opus`;
+ return testimonyAudio;
+}; \ No newline at end of file
diff --git a/webAO/viewport/utils/handleICSpeaking.ts b/webAO/viewport/utils/handleICSpeaking.ts
new file mode 100644
index 0000000..c396093
--- /dev/null
+++ b/webAO/viewport/utils/handleICSpeaking.ts
@@ -0,0 +1,312 @@
+import { ChatMsg } from "../interfaces/ChatMsg";
+import { client } from "../../client";
+import { appendICLog } from "../../client/appendICLog";
+import { checkCallword } from "../../client/checkCallword";
+import setEmote from "../../client/setEmote";
+import { AO_HOST } from "../../client/aoHost";
+import { SHOUTS } from "../constants/shouts";
+import getAnimLength from "../../utils/getAnimLength";
+import { setChatbox } from "../../dom/setChatbox";
+import { resizeChatbox } from "../../dom/resizeChatbox";
+import transparentPng from "../../constants/transparentPng";
+import { COLORS } from "../constants/colors";
+import mlConfig from "../../utils/aoml";
+
+const attorneyMarkdown = mlConfig(AO_HOST);
+
+export let startFirstTickCheck: boolean;
+export const setStartFirstTickCheck = (val: boolean) => {startFirstTickCheck = val}
+export let startSecondTickCheck: boolean;
+export const setStartSecondTickCheck = (val: boolean) => {startSecondTickCheck = val}
+export let startThirdTickCheck: boolean;
+export const setStartThirdTickCheck = (val: boolean) => {startThirdTickCheck = val}
+/**
+ * Sets a new emote.
+ * This sets up everything before the tick() loops starts
+ * a lot of things can probably be moved here, like starting the shout animation if there is one
+ * TODO: the preanim logic, on the other hand, should probably be moved to tick()
+ * @param {object} chatmsg the new chat message
+ */
+export const handle_ic_speaking = async (playerChatMsg: ChatMsg) => {
+ client.viewport.setChatmsg(playerChatMsg);
+ client.viewport.setTextNow("");
+ client.viewport.setSfxPlayed(0);
+ client.viewport.setTickTimer(0);
+ client.viewport.setAnimating(true);
+
+ startFirstTickCheck = true;
+ startSecondTickCheck = false;
+ startThirdTickCheck = false;
+ let charLayers = document.getElementById("client_char")!;
+ let pairLayers = document.getElementById("client_pair_char")!;
+ // stop updater
+ clearTimeout(client.viewport.updater);
+
+ // stop last sfx from looping any longer
+ client.viewport.getSfxAudio().loop = false;
+
+ const fg = <HTMLImageElement>document.getElementById("client_fg");
+ const gamewindow = document.getElementById("client_gamewindow")!;
+ const waitingBox = document.getElementById("client_chatwaiting")!;
+
+ // Reset CSS animation
+ gamewindow.style.animation = "";
+ waitingBox.style.opacity = "0";
+
+ const eviBox = document.getElementById("client_evi")!;
+
+ if (client.viewport.getLastEvidence() !== client.viewport.getChatmsg().evidence) {
+ eviBox.style.opacity = "0";
+ eviBox.style.height = "0%";
+ }
+ client.viewport.setLastEvidence(client.viewport.getChatmsg().evidence);
+
+ const validSides: string[] = ["def", "pro", "wit"]; // these are for the full view pan, the other positions use 'client_char'
+ if (validSides.includes(client.viewport.getChatmsg().side)) {
+ charLayers = document.getElementById(`client_${client.viewport.getChatmsg().side}_char`);
+ pairLayers = document.getElementById(`client_${client.viewport.getChatmsg().side}_pair_char`);
+ }
+
+ const chatContainerBox = document.getElementById("client_chatcontainer")!;
+ const nameBoxInner = document.getElementById("client_inner_name")!;
+ const chatBoxInner = document.getElementById("client_inner_chat")!;
+
+ const displayname =
+ (<HTMLInputElement>document.getElementById("showname")).checked &&
+ client.viewport.getChatmsg().showname !== ""
+ ? client.viewport.getChatmsg().showname!
+ : client.viewport.getChatmsg().nameplate!;
+
+ // Clear out the last message
+ chatBoxInner.innerText = client.viewport.getTextNow();
+ nameBoxInner.innerText = displayname;
+
+ if (client.viewport.getLastCharacter() !== client.viewport.getChatmsg().name) {
+ charLayers.style.opacity = "0";
+ pairLayers.style.opacity = "0";
+ }
+
+ client.viewport.setLastCharacter(client.viewport.getChatmsg().name);
+
+ appendICLog(client.viewport.getChatmsg().content, client.viewport.getChatmsg().showname, client.viewport.getChatmsg().nameplate);
+
+ checkCallword(client.viewport.getChatmsg().content, client.viewport.getSfxAudio());
+
+ setEmote(
+ AO_HOST,
+ client,
+ client.viewport.getChatmsg().name!.toLowerCase(),
+ client.viewport.getChatmsg().sprite!,
+ "(a)",
+ false,
+ client.viewport.getChatmsg().side
+ );
+
+ if (client.viewport.getChatmsg().other_name) {
+ setEmote(
+ AO_HOST,
+ client,
+ client.viewport.getChatmsg().other_name.toLowerCase(),
+ client.viewport.getChatmsg().other_emote!,
+ "(a)",
+ false,
+ client.viewport.getChatmsg().side
+ );
+ }
+
+ // gets which shout shall played
+ const shoutSprite = <HTMLImageElement>(
+ document.getElementById("client_shout")
+ );
+
+ const shout = SHOUTS[client.viewport.getChatmsg().objection];
+ if (shout) {
+ // Hide message box
+ chatContainerBox.style.opacity = "0";
+ if (client.viewport.getChatmsg().objection === 4) {
+ shoutSprite.src = `${AO_HOST}characters/${encodeURI(
+ client.viewport.getChatmsg().name!.toLowerCase()
+ )}/custom.gif`;
+ } else {
+ shoutSprite.src = client.resources[shout].src;
+ shoutSprite.style.animation = "bubble 700ms steps(10, jump-both)";
+ }
+ shoutSprite.style.opacity = "1";
+
+ client.viewport.shoutaudio.src = `${AO_HOST}characters/${encodeURI(
+ client.viewport.getChatmsg().name.toLowerCase()
+ )}/${shout}.opus`;
+ client.viewport.shoutaudio.play();
+ client.viewport.setShoutTimer(client.resources[shout].duration);
+ } else {
+ client.viewport.setShoutTimer(0);
+ }
+
+ client.viewport.getChatmsg().startpreanim = true;
+ let gifLength = 0;
+
+ if (client.viewport.getChatmsg().type === 1 && client.viewport.getChatmsg().preanim !== "-") {
+ //we have a preanim
+ chatContainerBox.style.opacity = "0";
+
+ gifLength = await getAnimLength(
+ `${AO_HOST}characters/${encodeURI(
+ client.viewport.getChatmsg().name!.toLowerCase()
+ )}/${encodeURI(client.viewport.getChatmsg().preanim)}`
+ );
+ console.debug("preanim is " + gifLength + " long");
+ client.viewport.getChatmsg().startspeaking = false;
+ } else {
+ client.viewport.getChatmsg().startspeaking = true;
+ if (client.viewport.getChatmsg().content !== "") chatContainerBox.style.opacity = "1";
+ }
+ client.viewport.getChatmsg().preanimdelay = gifLength;
+ const setAside = {
+ position: client.viewport.getChatmsg().side,
+ showSpeedLines: false,
+ showDesk: false,
+ };
+ let skipoffset: boolean = false;
+ if (client.viewport.getChatmsg().type === 5) {
+ setAside.showSpeedLines = true;
+ setAside.showDesk = false;
+ client.viewport.set_side(setAside);
+ } else {
+ switch (Number(client.viewport.getChatmsg().deskmod)) {
+ case 0: //desk is hidden
+ setAside.showSpeedLines = false;
+ setAside.showDesk = false;
+ client.viewport.set_side(setAside);
+ break;
+ case 1: //desk is shown
+ setAside.showSpeedLines = false;
+ setAside.showDesk = true;
+ client.viewport.set_side(setAside);
+ break;
+ case 2: //desk is hidden during preanim, but shown during idle/talk
+ setAside.showSpeedLines = false;
+ setAside.showDesk = false;
+ client.viewport.set_side(setAside);
+ break;
+ case 3: //opposite of 2
+ setAside.showSpeedLines = false;
+ setAside.showDesk = false;
+ client.viewport.set_side(setAside);
+ break;
+ case 4: //desk is hidden, character offset is ignored, pair character is hidden during preanim, normal behavior during idle/talk
+ setAside.showSpeedLines = false;
+ setAside.showDesk = false;
+ client.viewport.set_side(setAside);
+ skipoffset = true;
+ break;
+ case 5: //opposite of 4
+ setAside.showSpeedLines = false;
+ setAside.showDesk = true;
+ client.viewport.set_side(setAside);
+ break;
+ default:
+ setAside.showSpeedLines = false;
+ setAside.showDesk = true;
+ client.viewport.set_side(setAside);
+ break;
+ }
+ }
+
+ setChatbox(client.viewport.getChatmsg().chatbox);
+ resizeChatbox();
+
+ if (!skipoffset) {
+ // Flip the character
+ charLayers.style.transform =
+ client.viewport.getChatmsg().flip === 1 ? "scaleX(-1)" : "scaleX(1)";
+ pairLayers.style.transform =
+ client.viewport.getChatmsg().other_flip === 1 ? "scaleX(-1)" : "scaleX(1)";
+
+ // Shift by the horizontal offset
+ switch (client.viewport.getChatmsg().side) {
+ case "wit":
+ pairLayers.style.left = `${200 + Number(client.viewport.getChatmsg().other_offset[0])}%`;
+ charLayers.style.left = `${200 + Number(client.viewport.getChatmsg().self_offset[0])}%`;
+ break;
+ case "pro":
+ pairLayers.style.left = `${400 + Number(client.viewport.getChatmsg().other_offset[0])}%`;
+ charLayers.style.left = `${400 + Number(client.viewport.getChatmsg().self_offset[0])}%`;
+ break;
+ default:
+ pairLayers.style.left = `${Number(client.viewport.getChatmsg().other_offset[0])}%`;
+ charLayers.style.left = `${Number(client.viewport.getChatmsg().self_offset[0])}%`;
+ break;
+ }
+
+ // New vertical offsets
+ pairLayers.style.top = `${Number(client.viewport.getChatmsg().other_offset[1])}%`;
+ charLayers.style.top = `${Number(client.viewport.getChatmsg().self_offset[1])}%`;
+ }
+
+ client.viewport.blipChannels.forEach(
+ (channel: HTMLAudioElement) =>
+ (channel.src = `${AO_HOST}sounds/general/sfx-blip${encodeURI(
+ client.viewport.getChatmsg().blips.toLowerCase()
+ )}.opus`)
+ );
+
+ // process markup
+ if (client.viewport.getChatmsg().content.startsWith("~~")) {
+ chatBoxInner.style.textAlign = "center";
+ client.viewport.getChatmsg().content = client.viewport.getChatmsg().content.substring(2, client.viewport.getChatmsg().content.length);
+ } else {
+ chatBoxInner.style.textAlign = "inherit";
+ }
+
+ // apply effects
+ fg.style.animation = "";
+ const effectName = client.viewport.getChatmsg().effects[0].toLowerCase();
+ const badEffects = ["", "-", "none"];
+ if (effectName.startsWith("rain")) {
+ (<HTMLLinkElement>document.getElementById("effect_css")).href = "styles/effects/rain.css";
+ let intensity = 200;
+ if (effectName.endsWith("weak")) {
+ intensity = 100;
+ } else if (effectName.endsWith("strong")) {
+ intensity = 400;
+ }
+ if (intensity < fg.childElementCount)
+ fg.innerHTML = '';
+ else
+ intensity = intensity - fg.childElementCount;
+
+ for (let i = 0; i < intensity; i++) {
+ let drop = document.createElement("p");
+ drop.style.left = (Math.random() * 100) + "%";
+ drop.style.animationDelay = String(Math.random()) + "s";
+ fg.appendChild(drop)
+ }
+ } else if (
+ client.viewport.getChatmsg().effects[0] &&
+ !badEffects.includes(effectName)
+ ) {
+ (<HTMLLinkElement>document.getElementById("effect_css")).href = "";
+ fg.innerHTML = '';
+ const baseEffectUrl = `${AO_HOST}themes/default/effects/`;
+ fg.src = `${baseEffectUrl}${encodeURI(effectName)}.webp`;
+ } else {
+ fg.innerHTML = '';
+ fg.src = transparentPng;
+ }
+
+
+ charLayers.style.opacity = "1";
+
+ const soundChecks = ["0", "1", "", undefined];
+ if (soundChecks.some((check) => client.viewport.getChatmsg().sound === check)) {
+ client.viewport.getChatmsg().sound = client.viewport.getChatmsg().effects[2];
+ }
+
+ client.viewport.getChatmsg().parsed = await attorneyMarkdown.applyMarkdown(
+ client.viewport.getChatmsg().content,
+
+ COLORS[client.viewport.getChatmsg().color]
+
+ );
+ client.viewport.chat_tick();
+}; \ No newline at end of file
diff --git a/webAO/viewport/utils/initTestimonyUpdater.ts b/webAO/viewport/utils/initTestimonyUpdater.ts
new file mode 100644
index 0000000..e6f6e9d
--- /dev/null
+++ b/webAO/viewport/utils/initTestimonyUpdater.ts
@@ -0,0 +1,31 @@
+import { Testimony } from '../interfaces/Testimony'
+import { client, UPDATE_INTERVAL } from '../../client'
+/**
+ * Intialize testimony updater
+ */
+export const initTestimonyUpdater = () => {
+ const testimonyFilenames: Testimony = {
+ 1: "witnesstestimony",
+ 2: "crossexamination",
+ 3: "notguilty",
+ 4: "guilty",
+ };
+
+ const testimony = testimonyFilenames[client.testimonyID];
+ if (!testimony) {
+ console.warn(`Invalid testimony ID ${client.testimonyID}`);
+ return;
+ }
+
+ client.viewport.testimonyAudio.src = client.resources[testimony].sfx;
+ client.viewport.testimonyAudio.play();
+
+ const testimonyOverlay = <HTMLImageElement>(
+ document.getElementById("client_testimony")
+ );
+ testimonyOverlay.src = client.resources[testimony].src;
+ testimonyOverlay.style.opacity = "1";
+
+ client.viewport.setTestimonyTimer(0);
+ client.viewport.setTestimonyUpdater(setTimeout(() => client.viewport.updateTestimony(), UPDATE_INTERVAL));
+}; \ No newline at end of file
diff --git a/webAO/viewport/utils/setSide.ts b/webAO/viewport/utils/setSide.ts
new file mode 100644
index 0000000..15cb7c6
--- /dev/null
+++ b/webAO/viewport/utils/setSide.ts
@@ -0,0 +1,91 @@
+import { positions } from '../constants/positions'
+import { AO_HOST } from '../../client/aoHost'
+import { client } from '../../client'
+import tryUrls from '../../utils/tryUrls';
+import fileExists from '../../utils/fileExists';
+
+/**
+ * Changes the viewport background based on a given position.
+ *
+ * Valid positions: `def, pro, hld, hlp, wit, jud, jur, sea`
+ * @param {string} position the position to change into
+ */
+export const set_side = async ({
+ position,
+ showSpeedLines,
+ showDesk,
+}: {
+ position: string;
+ showSpeedLines: boolean;
+ showDesk: boolean;
+}) => {
+ const view = document.getElementById("client_fullview")!;
+ console.log(position)
+ let bench: HTMLImageElement;
+ if (['def','pro','wit'].includes(position)) {
+ bench = <HTMLImageElement>(
+ document.getElementById(`client_${position}_bench`)
+ );
+ } else {
+ bench = <HTMLImageElement>document.getElementById("client_bench_classic");
+ }
+
+ let court: HTMLImageElement;
+ if ("def,pro,wit".includes(position)) {
+ court = <HTMLImageElement>(
+ document.getElementById(`client_court_${position}`)
+ );
+ } else {
+ court = <HTMLImageElement>document.getElementById("client_court_classic");
+ }
+
+ let bg;
+ let desk;
+ let speedLines;
+
+ if ("def,pro,hld,hlp,wit,jud,jur,sea".includes(position)) {
+ bg = positions[position].bg;
+ desk = positions[position].desk;
+ speedLines = positions[position].speedLines;
+ } else {
+ bg = `${position}`;
+ desk = { ao2: `${position}_overlay.png`, ao1: "_overlay.png" };
+ speedLines = "defense_speedlines.gif";
+ }
+
+ if (showSpeedLines === true) {
+ court.src = `${AO_HOST}themes/default/${encodeURI(speedLines)}`;
+ } else {
+ court.src = await tryUrls(client.viewport.getBackgroundFolder() + bg);
+ }
+
+
+ if (showDesk === true && desk) {
+ const deskFilename = (await fileExists(client.viewport.getBackgroundFolder() + desk.ao2))
+ ? desk.ao2
+ : desk.ao1;
+ bench.src = client.viewport.getBackgroundFolder() + deskFilename;
+ bench.style.opacity = "1";
+ } else {
+ bench.style.opacity = "0";
+ }
+
+ if ("def,pro,wit".includes(position)) {
+ view.style.display = "";
+ document.getElementById("client_classicview")!.style.display = "none";
+ switch (position) {
+ case "def":
+ view.style.left = "0";
+ break;
+ case "wit":
+ view.style.left = "-200%";
+ break;
+ case "pro":
+ view.style.left = "-400%";
+ break;
+ }
+ } else {
+ view.style.display = "none";
+ document.getElementById("client_classicview").style.display = "";
+ }
+};