Основная структура

This commit is contained in:
2023-03-27 15:04:48 +04:00
parent d2ed8eaf58
commit f90f0c542b
13 changed files with 12384 additions and 0 deletions
+88
View File
@@ -0,0 +1,88 @@
import { Joke, JokeSettings } from "./joke";
/**
* Блок обработки перво-апрельских шуток
*
* @author Kozhilya
*/
export class AprilFoolsJokeClass {
/**
* Добавление шутки
*
* @param joke
*/
add(joke: Joke): void {
this.jokes[joke.id] = joke;
}
/**
* Запись новых настроек
*
* @param settings
*/
setSettings(settings: SettingsMap): void {
for (const entry of Object.entries(settings)) {
const id = entry[0];
const jokeSettings = entry[1];
this.jokes[id].settings = { ...this.jokes[id].settings, ...jokeSettings };
}
}
/**
* Проверка вероятности
*
* @param {number} chance Вероятность срабатывания
* @returns {boolean} Флаг срабатывания (true - сработало)
*/
check(chance: number): boolean {
return Math.random() < 0.01 * chance;
}
/**
* Запуск шутки
*
* @param id
* @param {boolean} forced
*/
start(id: string, forced: boolean = false) {
if (!(id in this.jokes))
return;
const joke = this.jokes[id];
if (!forced && !this.check(joke.settings.chance)) {
return;
}
joke.start();
}
/**
* Запуск всех шуток
*/
startAll() {
for (const key of Object.keys(this.jokes)) {
this.start(key);
}
}
/**
* Перечисление всех шуток
*/
jokes: JokeMap = {}
}
/**
* Объект хранения шуток
*/
interface JokeMap {
[key: string]: Joke;
}
/**
* Объект задания настроек
*/
interface SettingsMap {
[key: string]: JokeSettings;
}
+50
View File
@@ -0,0 +1,50 @@
/**
* Объект настроек шутки
*/
export interface JokeSettings {
/**
* Вероятность срабатывания в процентах (0 для отключения)
*/
chance: number;
}
/**
* Объект, описывающий шутку
*/
export abstract class Joke {
/**
* Идентификатор шутки
*/
id: string;
/**
* Настройки шутки
*/
settings: JokeSettings;
/**
* Флаг, указывающий, должна ли шутка быть запущена
*/
enabled: boolean;
/**
* Флаг, указывающий, может ли шутка быть остановлена
*/
is_stopable: boolean;
/**
* Запуск шутки
*/
abstract start(): void;
}
/**
* Объект, описывающий шутку, которая может быть остановлена
*/
export abstract class StopableJoke extends Joke
{
/**
* Остановка шутки, если возможно
*/
abstract stop(): void;
}
+90
View File
@@ -0,0 +1,90 @@
import { Joke, JokeSettings, StopableJoke } from "../joke";
/**
* Форумо-трясение
*
* Страница форума начинает трястись
*
* @author Kozhilya
*/
export class ShakeJoke extends StopableJoke {
settings: ShakeJokeSettings;
private interval_id: NodeJS.Timer;
private items: JQuery;
private data_name: string = 'april-fools-shake';
rand(a: number): number {
return a + this.settings.force * (Math.random() * 2 - 1);
}
start(): void {
this.items = $(this.settings.selector);
this.items.each((_, elem) => {
let data: ShakeJokeMargin = {};
this.settings.directions.forEach(d => {
data[d] = parseInt($(elem).css('margin-' + d));
});
$(elem).data(this.data_name, data);
});
this.interval_id = setInterval(() => {
this.items.each((_, elem) => {
const data: ShakeJokeMargin = $(elem).data(this.data_name);
for (const entry of Object.entries(data)) {
$(elem).css('margin-' + entry[0], this.rand(entry[1]))
}
});
}, this.settings.interval);
}
stop(): void {
clearInterval(this.interval_id);
this.items.each((_, elem) => {
let data: ShakeJokeMargin = {};
this.settings.directions.forEach(d => {
$(elem).css('margin-' + d, data[d]);
});
$(elem).data(this.data_name, data);
});
}
}
export class ShakeJokeSettings implements JokeSettings {
chance: number = 1;
/**
* Направление тряски
*/
directions: string[] = ['top', 'left', 'bottom', 'left'];
/**
* Селектор всех элементов, которые будут трястись
*/
selector: string = '[id^=pun]';
/**
* Частота тряски
*/
interval: number = 100;
/**
* Сила тряски
*/
force: number = 0.5;
}
interface ShakeJokeMargin {
[key: string]: number;
}
+17
View File
@@ -0,0 +1,17 @@
import { AprilFoolsJokeClass } from "./handler";
import { Joke } from "./joke";
import { ShakeJoke } from "./jokes/shake";
(window as any).AprilJokes = ((jokes: JokeClassList): AprilFoolsJokeClass => {
const cl = new AprilFoolsJokeClass();
jokes.forEach(joke => {
cl.add(new joke());
});
return cl;
})([
ShakeJoke,
]);
interface JokeClassList extends Array<new () => Joke> {}