mirror of
https://github.com/Terncode/pixel.horse.git
synced 2026-09-24 21:55:52 +02:00
Fix/Improve linting
This commit is contained in:
@@ -89,6 +89,8 @@ module.exports = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
'curly': ['warn', 'all'],
|
||||||
|
'brace-style': ['warn', 'stroustrup'],
|
||||||
'eol-last': 'error',
|
'eol-last': 'error',
|
||||||
'eqeqeq': [
|
'eqeqeq': [
|
||||||
'error',
|
'error',
|
||||||
|
|||||||
+5
-3
@@ -1,3 +1,5 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
import 'source-map-support/register.js';
|
import 'source-map-support/register.js';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
@@ -125,7 +127,7 @@ const changelog = cb => {
|
|||||||
.map(x => x.replace(/^\[test\]/, '<span class="badge badge-secondary">test</span>')),
|
.map(x => x.replace(/^\[test\]/, '<span class="badge badge-secondary">test</span>')),
|
||||||
}));
|
}));
|
||||||
const type = `{ version: string; changes: string[]; }[]`;
|
const type = `{ version: string; changes: string[]; }[]`;
|
||||||
const code = `/* tslint:disable */\n\nexport const CHANGELOG: ${type} = ${JSON.stringify(object, null, 2)};\n`;
|
const code = `/* eslint:disable */\n\nexport const CHANGELOG: ${type} = ${JSON.stringify(object, null, 2)};\n`;
|
||||||
fs.writeFile('src/ts/generated/changelog.ts', code, 'utf8', cb);
|
fs.writeFile('src/ts/generated/changelog.ts', code, 'utf8', cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -178,7 +180,7 @@ const shaders = cb => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const dir = path.join('src', 'ts', 'graphics', 'shaders');
|
const dir = path.join('src', 'ts', 'graphics', 'shaders');
|
||||||
const code = '/* tslint:disable */\n\n' + fs.readdirSync(dir)
|
const code = '/* eslint:disable */\n\n' + fs.readdirSync(dir)
|
||||||
.map(file => [_.camelCase(file.replace(/\.glsl$/, '')), path.join(dir, file)])
|
.map(file => [_.camelCase(file.replace(/\.glsl$/, '')), path.join(dir, file)])
|
||||||
.map(([name, filePath]) => `export const ${name}Shader = \`${getShaderCode(filePath)}\`;`)
|
.map(([name, filePath]) => `export const ${name}Shader = \`${getShaderCode(filePath)}\`;`)
|
||||||
.join('\n\n');
|
.join('\n\n');
|
||||||
@@ -200,7 +202,7 @@ const rollbar = cb => {
|
|||||||
const assetsRev = cb => {
|
const assetsRev = cb => {
|
||||||
const json = fs.readFileSync('dist/browser/rev-manifest.json', 'utf8');
|
const json = fs.readFileSync('dist/browser/rev-manifest.json', 'utf8');
|
||||||
const data = _.mapValues(JSON.parse(json), value => value.replace(/^\S+-([a-f0-9]{10})\.\S+$/, '$1'));
|
const data = _.mapValues(JSON.parse(json), value => value.replace(/^\S+-([a-f0-9]{10})\.\S+$/, '$1'));
|
||||||
const code = `export const REV: { [key: string]: string; } = ${JSON.stringify(data, null, 4)};`;
|
const code = `export const REV: { [key: string]: string; } = ${JSON.stringify(data, null, 2)};`;
|
||||||
fs.writeFile('src/ts/generated/rev.ts', lintCode(code), 'utf8', cb);
|
fs.writeFile('src/ts/generated/rev.ts', lintCode(code), 'utf8', cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ export function createSupporterChanges(entries: LogEntry[]): SupporterChange[] {
|
|||||||
if (current.level > prev.level) {
|
if (current.level > prev.level) {
|
||||||
current.icon = faCaretSquareUp;
|
current.icon = faCaretSquareUp;
|
||||||
current.class = 'text-info';
|
current.class = 'text-info';
|
||||||
} else if (current.level < prev.level) {
|
}
|
||||||
|
else if (current.level < prev.level) {
|
||||||
current.icon = faCaretSquareDown;
|
current.icon = faCaretSquareDown;
|
||||||
current.class = 'text-info';
|
current.class = 'text-info';
|
||||||
}
|
}
|
||||||
@@ -49,7 +50,6 @@ function formatChatLine(l: string): HTMLElement {
|
|||||||
// 00:00:01 [merged][dev][Autumn Leafs][ignored] hello world
|
// 00:00:01 [merged][dev][Autumn Leafs][ignored] hello world
|
||||||
// 00:00:01 [merged][dev][main][Autumn Leafs][ignored] hello world
|
// 00:00:01 [merged][dev][main][Autumn Leafs][ignored] hello world
|
||||||
|
|
||||||
/* tslint:disable:max-line-length */
|
|
||||||
const regex = /^([0-9:]+) (\[(?:merged|\d+|\d+:merged|[a-z0-9]{24})\])?\[([a-z0-9_-]+)\](?:\[([a-z0-9_-]+)\])?((?:\[.*?\])?)(?:\[(muted|ignored|ignorepub)\])?\t(.*)$/;
|
const regex = /^([0-9:]+) (\[(?:merged|\d+|\d+:merged|[a-z0-9]{24})\])?\[([a-z0-9_-]+)\](?:\[([a-z0-9_-]+)\])?((?:\[.*?\])?)(?:\[(muted|ignored|ignorepub)\])?\t(.*)$/;
|
||||||
const m = regex.exec(l);
|
const m = regex.exec(l);
|
||||||
|
|
||||||
@@ -69,7 +69,8 @@ function formatChatLine(l: string): HTMLElement {
|
|||||||
textNode(' '),
|
textNode(' '),
|
||||||
element('a', 'chat-translate', [], undefined, { click: translateChat }),
|
element('a', 'chat-translate', [], undefined, { click: translateChat }),
|
||||||
]);
|
]);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return element('div', '', [textNode(highlightWords(l))]);
|
return element('div', '', [textNode(highlightWords(l))]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,13 +105,17 @@ export function formatChat(chat: string): HTMLElement[] {
|
|||||||
function getMessageTag(message: string) {
|
function getMessageTag(message: string) {
|
||||||
if (/^\/p /.test(message)) {
|
if (/^\/p /.test(message)) {
|
||||||
return 'party';
|
return 'party';
|
||||||
} else if (/^\/w /.test(message)) {
|
}
|
||||||
|
else if (/^\/w /.test(message)) {
|
||||||
return 'whisper';
|
return 'whisper';
|
||||||
} else if (/^\/s[s123] /.test(message)) {
|
}
|
||||||
|
else if (/^\/s[s123] /.test(message)) {
|
||||||
return 'supporter';
|
return 'supporter';
|
||||||
} else if (/^\//.test(message)) {
|
}
|
||||||
|
else if (/^\//.test(message)) {
|
||||||
return 'command';
|
return 'command';
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return 'none';
|
return 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,8 +225,11 @@ export function deserializeActions(data: string): ButtonActionSlot[] {
|
|||||||
try {
|
try {
|
||||||
const json = JSON.parse(data);
|
const json = JSON.parse(data);
|
||||||
return json.slice(0, ACTIONS_LIMIT).map(deserializeAction);
|
return json.slice(0, ACTIONS_LIMIT).map(deserializeAction);
|
||||||
} catch (e) {
|
}
|
||||||
DEVELOPMENT && console.error(e);
|
catch (e) {
|
||||||
|
if (DEVELOPMENT) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,10 +246,13 @@ function serializeAction({ action }: ButtonActionSlot): any {
|
|||||||
case 'entity':
|
case 'entity':
|
||||||
return { ent: action.entity };
|
return { ent: action.entity };
|
||||||
default:
|
default:
|
||||||
DEVELOPMENT && console.warn(`Missing serialization for ${JSON.stringify(action)}`);
|
if (DEVELOPMENT) {
|
||||||
|
console.warn(`Missing serialization for ${JSON.stringify(action)}`);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -255,15 +261,21 @@ function deserializeAction(data: any): ButtonActionSlot {
|
|||||||
if (data) {
|
if (data) {
|
||||||
if ('act' in data || 'action' in data) {
|
if ('act' in data || 'action' in data) {
|
||||||
return { action: getActionAction(data.act || data.action) };
|
return { action: getActionAction(data.act || data.action) };
|
||||||
} else if ('cmd' in data || 'command' in data) {
|
}
|
||||||
|
else if ('cmd' in data || 'command' in data) {
|
||||||
return { action: getCommandAction(data.cmd || data.command) };
|
return { action: getCommandAction(data.cmd || data.command) };
|
||||||
} else if ('exp' in data || 'expression' in data) {
|
}
|
||||||
|
else if ('exp' in data || 'expression' in data) {
|
||||||
const expression = decodeExpression(data.exp || data.expression | 0);
|
const expression = decodeExpression(data.exp || data.expression | 0);
|
||||||
return { action: expressionButtonAction(expression) };
|
return { action: expressionButtonAction(expression) };
|
||||||
} else if ('ent' in data || 'entity' in data) {
|
}
|
||||||
|
else if ('ent' in data || 'entity' in data) {
|
||||||
return { action: entityButtonAction(data.ent || data.entity) };
|
return { action: entityButtonAction(data.ent || data.entity) };
|
||||||
} else {
|
}
|
||||||
DEVELOPMENT && console.warn(`Missing deserialization for ${JSON.stringify(data)}`);
|
else {
|
||||||
|
if (DEVELOPMENT) {
|
||||||
|
console.warn(`Missing deserialization for ${JSON.stringify(data)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +293,8 @@ export function useAction(game: PonyTownGame, action: ButtonAction | undefined)
|
|||||||
case 'action':
|
case 'action':
|
||||||
if (action.sendAction) {
|
if (action.sendAction) {
|
||||||
game.send(server => server.action(action.sendAction));
|
game.send(server => server.action(action.sendAction));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
switch (action.action) {
|
switch (action.action) {
|
||||||
case 'boop':
|
case 'boop':
|
||||||
boopAction(game);
|
boopAction(game);
|
||||||
@@ -336,7 +349,8 @@ export function useAction(game: PonyTownGame, action: ButtonAction | undefined)
|
|||||||
function shouldRedrawAction(action: ButtonAction | undefined, state: any, game: PonyTownGame) {
|
function shouldRedrawAction(action: ButtonAction | undefined, state: any, game: PonyTownGame) {
|
||||||
if (action !== state.action) {
|
if (action !== state.action) {
|
||||||
return true;
|
return true;
|
||||||
} else if (action) {
|
}
|
||||||
|
else if (action) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'action': {
|
case 'action': {
|
||||||
switch (action.action) {
|
switch (action.action) {
|
||||||
@@ -353,7 +367,8 @@ function shouldRedrawAction(action: ButtonAction | undefined, state: any, game:
|
|||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,13 +388,15 @@ export function drawAction(canvas: HTMLCanvasElement, action: ButtonAction | und
|
|||||||
state.action = 0;
|
state.action = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!spriteSheetsLoaded || !shouldRedrawAction(action, state, game))
|
if (!spriteSheetsLoaded || !shouldRedrawAction(action, state, game)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const context = canvas.getContext('2d');
|
const context = canvas.getContext('2d');
|
||||||
|
|
||||||
if (!context)
|
if (!context) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
state.action = action;
|
state.action = action;
|
||||||
|
|
||||||
@@ -412,10 +429,12 @@ export function drawAction(canvas: HTMLCanvasElement, action: ButtonAction | und
|
|||||||
|
|
||||||
if (hasFlag(extra, ExpressionExtra.Cry)) {
|
if (hasFlag(extra, ExpressionExtra.Cry)) {
|
||||||
batch.drawSprite(sprites.emote_cry2.frames[4], WHITE, defaultPalette, headX, headY);
|
batch.drawSprite(sprites.emote_cry2.frames[4], WHITE, defaultPalette, headX, headY);
|
||||||
} else if (hasFlag(extra, ExpressionExtra.Tears)) {
|
}
|
||||||
|
else if (hasFlag(extra, ExpressionExtra.Tears)) {
|
||||||
batch.drawSprite(sprites.emote_tears.frames[0], WHITE, defaultPalette, headX, headY);
|
batch.drawSprite(sprites.emote_tears.frames[0], WHITE, defaultPalette, headX, headY);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const color = parseColor(ACTION_EXPRESSION_BG);
|
const color = parseColor(ACTION_EXPRESSION_BG);
|
||||||
batch.drawRect(color, 0, 3, 15, 5);
|
batch.drawRect(color, 0, 3, 15, 5);
|
||||||
batch.drawRect(color, 0, 8, 3, 1);
|
batch.drawRect(color, 0, 8, 3, 1);
|
||||||
@@ -449,9 +468,12 @@ export function drawAction(canvas: HTMLCanvasElement, action: ButtonAction | und
|
|||||||
state.draw = action.action === 'up' ? getUpDrawFunc(game) : getDownDrawFunc(game);
|
state.draw = action.action === 'up' ? getUpDrawFunc(game) : getDownDrawFunc(game);
|
||||||
|
|
||||||
buffer = drawCanvasCached(`action:${action.action}:${state.draw}`, batch => {
|
buffer = drawCanvasCached(`action:${action.action}:${state.draw}`, batch => {
|
||||||
state.draw && getDrawFuncByName(state.draw)(batch);
|
if (state.draw) {
|
||||||
|
getDrawFuncByName(state.draw)(batch);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
buffer = drawCanvasCached(`action:${action.action}`, batch => {
|
buffer = drawCanvasCached(`action:${action.action}`, batch => {
|
||||||
switch (action.action) {
|
switch (action.action) {
|
||||||
case 'boop': {
|
case 'boop': {
|
||||||
@@ -662,9 +684,11 @@ function getUpDrawFunc(game: PonyTownGame) {
|
|||||||
if (player) {
|
if (player) {
|
||||||
if (isPonyLying(player)) {
|
if (isPonyLying(player)) {
|
||||||
return 'sit';
|
return 'sit';
|
||||||
} else if (isPonySitting(player)) {
|
}
|
||||||
|
else if (isPonySitting(player)) {
|
||||||
return 'stand';
|
return 'stand';
|
||||||
} else if (isPonyStanding(player) && canPonyFly(player)) {
|
}
|
||||||
|
else if (isPonyStanding(player) && canPonyFly(player)) {
|
||||||
return 'fly';
|
return 'fly';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -678,9 +702,11 @@ function getDownDrawFunc(game: PonyTownGame) {
|
|||||||
if (player) {
|
if (player) {
|
||||||
if (isPonySitting(player)) {
|
if (isPonySitting(player)) {
|
||||||
return 'lie';
|
return 'lie';
|
||||||
} else if (isPonyStanding(player)) {
|
}
|
||||||
|
else if (isPonyStanding(player)) {
|
||||||
return 'sit';
|
return 'sit';
|
||||||
} else if (isPonyFlying(player)) {
|
}
|
||||||
|
else if (isPonyFlying(player)) {
|
||||||
return 'stand';
|
return 'stand';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ export class ClientActions extends ClientActionsTemplate {
|
|||||||
this.apply(() => this.gameService.disconnected());
|
this.apply(() => this.gameService.disconnected());
|
||||||
}
|
}
|
||||||
invalidVersion() {
|
invalidVersion() {
|
||||||
DEVELOPMENT && !TESTS && console.error('Invalid version');
|
if (DEVELOPMENT && !TESTS) {
|
||||||
|
console.error('Invalid version');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// @Method({ binary: [Bin.U32] })
|
// @Method({ binary: [Bin.U32] })
|
||||||
queue(place: number) {
|
queue(place: number) {
|
||||||
@@ -182,7 +184,9 @@ export class ClientActions extends ClientActionsTemplate {
|
|||||||
this.game.nextFriendsCRC = 0;
|
this.game.nextFriendsCRC = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DEVELOPMENT && !TESTS && console.error(`actionParam: Invalid action: ${action}`);
|
if (DEVELOPMENT && !TESTS) {
|
||||||
|
console.error(`actionParam: Invalid action: ${action}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// @Method({ binary: [Bin.U8] }>)
|
// @Method({ binary: [Bin.U8] }>)
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ export class ClientAdminActions extends ClientAdminActionsTemplate {
|
|||||||
|
|
||||||
if (model) {
|
if (model) {
|
||||||
model.update(id, update);
|
model.update(id, update);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
console.error(`Invalid model type "${type}"`);
|
console.error(`Invalid model type "${type}"`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ function isMultipleMatch(message: string, last: string): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return message === current.substr(0, SAY_MAX_LENGTH);
|
return message === current.substr(0, SAY_MAX_LENGTH);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,9 +54,11 @@ function isTrailingMatch(message: string, last: string) {
|
|||||||
|
|
||||||
if (message.length > last.length && last.length > minMessageLength) {
|
if (message.length > last.length && last.length > minMessageLength) {
|
||||||
return checkTrailing(message, last);
|
return checkTrailing(message, last);
|
||||||
} else if (message.length < last.length && message.length > minMessageLength) {
|
}
|
||||||
|
else if (message.length < last.length && message.length > minMessageLength) {
|
||||||
return checkTrailing(last, message);
|
return checkTrailing(last, message);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,7 +66,8 @@ function isTrailingMatch(message: string, last: string) {
|
|||||||
export function isSpamMessage(message: string, lastMessages: string[]): boolean {
|
export function isSpamMessage(message: string, lastMessages: string[]): boolean {
|
||||||
if (!/^\//.test(message) && lastMessages.length) {
|
if (!/^\//.test(message) && lastMessages.length) {
|
||||||
return lastMessages.some(last => message === last || isMultipleMatch(message, last) || isTrailingMatch(message, last));
|
return lastMessages.some(last => message === last || isMultipleMatch(message, last) || isTrailingMatch(message, last));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,7 +158,8 @@ export function readFileAsText(file: File) {
|
|||||||
export function isFileSaverSupported() {
|
export function isFileSaverSupported() {
|
||||||
try {
|
try {
|
||||||
return !!new Blob;
|
return !!new Blob;
|
||||||
} catch {
|
}
|
||||||
|
catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,13 +172,15 @@ export function setIsIncognitoMode(value: boolean) {
|
|||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
function checkIncognitoMode(wnd: any) {
|
function checkIncognitoMode(wnd: any) {
|
||||||
if (!wnd || !wnd.chrome)
|
if (!wnd || !wnd.chrome) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const fs = wnd.RequestFileSystem || wnd.webkitRequestFileSystem;
|
const fs = wnd.RequestFileSystem || wnd.webkitRequestFileSystem;
|
||||||
|
|
||||||
if (!fs)
|
if (!fs){
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fs(wnd.TEMPORARY, 100, () => { }, () => isInIncognitoMode = true);
|
fs(wnd.TEMPORARY, 100, () => { }, () => isInIncognitoMode = true);
|
||||||
}
|
}
|
||||||
@@ -202,7 +209,8 @@ export function isStandalone() {
|
|||||||
export function supportsLetAndConst() {
|
export function supportsLetAndConst() {
|
||||||
try {
|
try {
|
||||||
return (new Function('let x = true; return x;'))();
|
return (new Function('let x = true; return x;'))();
|
||||||
} catch {
|
}
|
||||||
|
catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,7 +238,8 @@ export function registerServiceWorker(url: string, onUpdate: () => void) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,7 +253,8 @@ export function unregisterServiceWorker() {
|
|||||||
registration.unregister();
|
registration.unregister();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,7 +281,8 @@ export function updateRangeIndicator(range: number | undefined, { player, scale,
|
|||||||
e.style.top = `${-h / 2}px`;
|
e.style.top = `${-h / 2}px`;
|
||||||
e.style.transform = `translate3d(${x}px, ${y}px, 0)`;
|
e.style.transform = `translate3d(${x}px, ${y}px, 0)`;
|
||||||
e.style.display = 'block';
|
e.style.display = 'block';
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
e.style.display = 'none';
|
e.style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,7 +294,8 @@ export function checkIframeKey(iframeId: string, expectedKey: string) {
|
|||||||
const doc = iframe && iframe.contentWindow && iframe.contentWindow.document;
|
const doc = iframe && iframe.contentWindow && iframe.contentWindow.document;
|
||||||
const key = doc && doc.body && doc.body.getAttribute('data-key');
|
const key = doc && doc.body && doc.body.getAttribute('data-key');
|
||||||
return key === expectedKey;
|
return key === expectedKey;
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
if (DEVELOPMENT) {
|
if (DEVELOPMENT) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
@@ -333,9 +345,11 @@ export function isSupporterOrPastSupporter(account: AccountData | undefined) {
|
|||||||
export function supporterTitle(account: AccountData | undefined) {
|
export function supporterTitle(account: AccountData | undefined) {
|
||||||
if (account && account.supporter) {
|
if (account && account.supporter) {
|
||||||
return `Supporter Tier ${account.supporter}`;
|
return `Supporter Tier ${account.supporter}`;
|
||||||
} else if (account && hasFlag(account.flags, AccountDataFlags.PastSupporter)) {
|
}
|
||||||
|
else if (account && hasFlag(account.flags, AccountDataFlags.PastSupporter)) {
|
||||||
return 'Past supporter';
|
return 'Past supporter';
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -343,9 +357,11 @@ export function supporterTitle(account: AccountData | undefined) {
|
|||||||
export function supporterClass(account: AccountData | undefined) {
|
export function supporterClass(account: AccountData | undefined) {
|
||||||
if (account && account.supporter) {
|
if (account && account.supporter) {
|
||||||
return `supporter-${account.supporter}`;
|
return `supporter-${account.supporter}`;
|
||||||
} else if (account && hasFlag(account.flags, AccountDataFlags.PastSupporter)) {
|
}
|
||||||
|
else if (account && hasFlag(account.flags, AccountDataFlags.PastSupporter)) {
|
||||||
return 'supporter-past';
|
return 'supporter-past';
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return 'd-none';
|
return 'd-none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -353,9 +369,11 @@ export function supporterClass(account: AccountData | undefined) {
|
|||||||
export function supporterRewards(account: AccountData | undefined) {
|
export function supporterRewards(account: AccountData | undefined) {
|
||||||
if (account && account.supporter) {
|
if (account && account.supporter) {
|
||||||
return SUPPORTER_REWARDS[account.supporter];
|
return SUPPORTER_REWARDS[account.supporter];
|
||||||
} else if (account && hasFlag(account.flags, AccountDataFlags.PastSupporter)) {
|
}
|
||||||
|
else if (account && hasFlag(account.flags, AccountDataFlags.PastSupporter)) {
|
||||||
return PAST_SUPPORTER_REWARDS;
|
return PAST_SUPPORTER_REWARDS;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return SUPPORTER_REWARDS[0];
|
return SUPPORTER_REWARDS[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ export function socketOptions(): ClientOptions {
|
|||||||
const buffer = toByteArray(options);
|
const buffer = toByteArray(options);
|
||||||
const reader = createBinaryReader(buffer);
|
const reader = createBinaryReader(buffer);
|
||||||
return readObject(reader);
|
return readObject(reader);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw new Error('Missing socket options');
|
throw new Error('Missing socket options');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+58
-24
@@ -31,11 +31,13 @@ function drawEntities(batch: PaletteSpriteBatch, entities: Entity[], camera: Cam
|
|||||||
batch.depth = -batch.depth;
|
batch.depth = -batch.depth;
|
||||||
drawPonyEntity(batch, entity as Pony, options);
|
drawPonyEntity(batch, entity as Pony, options);
|
||||||
entitiesDrawn++;
|
entitiesDrawn++;
|
||||||
} else if (entity.draw !== undefined) {
|
}
|
||||||
|
else if (entity.draw !== undefined) {
|
||||||
entity.draw(batch, options);
|
entity.draw(batch, options);
|
||||||
entitiesDrawn++;
|
entitiesDrawn++;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (entity.type === PONY_TYPE) {
|
if (entity.type === PONY_TYPE) {
|
||||||
const pony = entity as Pony;
|
const pony = entity as Pony;
|
||||||
|
|
||||||
@@ -62,7 +64,8 @@ export function drawEntityLights(batch: SpriteBatch, entities: Entity[], camera:
|
|||||||
if (isBoundsVisible(camera, entity.lightBounds, entity.x, entity.y) && (!isHidden(entity) || drawHidden)) {
|
if (isBoundsVisible(camera, entity.lightBounds, entity.x, entity.y) && (!isHidden(entity) || drawHidden)) {
|
||||||
if (entity.type === PONY_TYPE) {
|
if (entity.type === PONY_TYPE) {
|
||||||
drawPonyEntityLight(batch, entity as Pony, options);
|
drawPonyEntityLight(batch, entity as Pony, options);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
entity.drawLight!(batch, options);
|
entity.drawLight!(batch, options);
|
||||||
}
|
}
|
||||||
++drawn;
|
++drawn;
|
||||||
@@ -85,7 +88,8 @@ export function drawEntityLightSprites(batch: SpriteBatch, entities: Entity[], c
|
|||||||
batch.depth = entity.depth;
|
batch.depth = entity.depth;
|
||||||
if (entity.type === PONY_TYPE) {
|
if (entity.type === PONY_TYPE) {
|
||||||
drawPonyEntityLightSprite(batch, entity as Pony, options);
|
drawPonyEntityLightSprite(batch, entity as Pony, options);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
entity.drawLightSprite!(batch, options);
|
entity.drawLightSprite!(batch, options);
|
||||||
}
|
}
|
||||||
++drawn;
|
++drawn;
|
||||||
@@ -100,7 +104,8 @@ export function hasDrawLight(entity: Entity) {
|
|||||||
const pony = entity as Pony;
|
const pony = entity as Pony;
|
||||||
return (pony.ponyState.holding !== undefined && pony.ponyState.holding.drawLight !== undefined) ||
|
return (pony.ponyState.holding !== undefined && pony.ponyState.holding.drawLight !== undefined) ||
|
||||||
((pony.state & EntityState.Magic) !== 0);
|
((pony.state & EntityState.Magic) !== 0);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return entity.drawLight !== undefined;
|
return entity.drawLight !== undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,7 +114,8 @@ export function hasLightSprite(entity: Entity) {
|
|||||||
if (entity.type === PONY_TYPE) {
|
if (entity.type === PONY_TYPE) {
|
||||||
const pony = entity as Pony;
|
const pony = entity as Pony;
|
||||||
return (pony.ponyState.holding !== undefined && pony.ponyState.holding.drawLightSprite !== undefined);
|
return (pony.ponyState.holding !== undefined && pony.ponyState.holding.drawLightSprite !== undefined);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return entity.drawLightSprite !== undefined;
|
return entity.drawLightSprite !== undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,25 +124,39 @@ export function drawMap(
|
|||||||
batch: PaletteSpriteBatch, map: WorldMap, camera: Camera, player: Pony,
|
batch: PaletteSpriteBatch, map: WorldMap, camera: Camera, player: Pony,
|
||||||
options: DrawOptions, tileSets: TileSets, selectedEntities: Entity[],
|
options: DrawOptions, tileSets: TileSets, selectedEntities: Entity[],
|
||||||
) {
|
) {
|
||||||
TIMING && timeStart('forEachRegion');
|
if (TIMING) {
|
||||||
|
timeStart('forEachRegion');
|
||||||
|
}
|
||||||
batch.depth = 1.0;
|
batch.depth = 1.0;
|
||||||
if (BETA && options.engine === Engine.Whiteness) {
|
if (BETA && options.engine === Engine.Whiteness) {
|
||||||
batch.drawRect(WHITE, 0, 0, toScreenX(map.width), toScreenY(map.height));
|
batch.drawRect(WHITE, 0, 0, toScreenX(map.width), toScreenY(map.height));
|
||||||
} else if (BETA && options.engine === Engine.LayeredTiles) {
|
}
|
||||||
|
else if (BETA && options.engine === Engine.LayeredTiles) {
|
||||||
forEachRegion(map, region => drawTilesNew(batch, region, camera, map, tileSets, options));
|
forEachRegion(map, region => drawTilesNew(batch, region, camera, map, tileSets, options));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
forEachRegion(map, region => drawTiles(batch, region, camera, map, tileSets, options));
|
forEachRegion(map, region => drawTiles(batch, region, camera, map, tileSets, options));
|
||||||
}
|
}
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
TIMING && timeStart('sortEntities');
|
if (TIMING) {
|
||||||
|
timeStart('sortEntities');
|
||||||
|
}
|
||||||
sortEntities(map.entitiesDrawable);
|
sortEntities(map.entitiesDrawable);
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
TIMING && timeStart('drawEntities');
|
if (TIMING) {
|
||||||
|
timeStart('drawEntities');
|
||||||
|
}
|
||||||
const entitiesDrawn = drawEntities(batch, map.entitiesDrawable, camera, options);
|
const entitiesDrawn = drawEntities(batch, map.entitiesDrawable, camera, options);
|
||||||
batch.depth = 1.0;
|
batch.depth = 1.0;
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
if (BETA || TOOLS) {
|
if (BETA || TOOLS) {
|
||||||
forEachRegion(map, region => drawTilesDebugInfo(batch, region, camera, options));
|
forEachRegion(map, region => drawTilesDebugInfo(batch, region, camera, options));
|
||||||
@@ -179,10 +199,18 @@ function drawDebugHelpers(batch: PaletteSpriteBatch, entities: Entity[], options
|
|||||||
|
|
||||||
for (const e of entities) {
|
for (const e of entities) {
|
||||||
batch.globalAlpha = 0.3;
|
batch.globalAlpha = 0.3;
|
||||||
show.bounds && drawBounds(batch, e, e.bounds, ORANGE);
|
if (show.bounds) {
|
||||||
show.cover && drawBounds(batch, e, e.coverBounds, BLUE);
|
drawBounds(batch, e, e.bounds, ORANGE);
|
||||||
show.interact && drawBounds(batch, e, e.interactBounds, PURPLE);
|
}
|
||||||
show.trigger && drawWorldBounds(batch, e, e.triggerBounds, CYAN);
|
if (show.cover) {
|
||||||
|
drawBounds(batch, e, e.coverBounds, BLUE);
|
||||||
|
}
|
||||||
|
if (show.interact) {
|
||||||
|
drawBounds(batch, e, e.interactBounds, PURPLE);
|
||||||
|
}
|
||||||
|
if (show.trigger) {
|
||||||
|
drawWorldBounds(batch, e, e.triggerBounds, CYAN);
|
||||||
|
}
|
||||||
|
|
||||||
if (show.collider) {
|
if (show.collider) {
|
||||||
batch.globalAlpha = 0.5;
|
batch.globalAlpha = 0.5;
|
||||||
@@ -224,16 +252,19 @@ function drawDebugInWater(batch: PaletteSpriteBatch, map: WorldMap, camera: Came
|
|||||||
const cameraTop = camera.actualY;
|
const cameraTop = camera.actualY;
|
||||||
const cameraBottom = camera.actualY + camera.h;
|
const cameraBottom = camera.actualY + camera.h;
|
||||||
|
|
||||||
if (sx > cameraRight || sy > cameraBottom || (sx + w) < cameraLeft || (sy + h) < cameraTop)
|
if (sx > cameraRight || sy > cameraBottom || (sx + w) < cameraLeft || (sy + h) < cameraTop) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (let y = 0; y < h; y++) {
|
for (let y = 0; y < h; y++) {
|
||||||
if ((sy + y + 1) < cameraTop || (sy + y) > cameraBottom)
|
if ((sy + y + 1) < cameraTop || (sy + y) > cameraBottom) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (let x = 0; x < w; x++) {
|
for (let x = 0; x < w; x++) {
|
||||||
if ((sx + x + 1) < cameraLeft || (sx + x) > cameraRight)
|
if ((sx + x + 1) < cameraLeft || (sx + x) > cameraRight) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const tx = x;
|
const tx = x;
|
||||||
|
|
||||||
@@ -263,16 +294,19 @@ function drawDebugCollider(batch: PaletteSpriteBatch, map: WorldMap, camera: Cam
|
|||||||
const cameraTop = camera.actualY;
|
const cameraTop = camera.actualY;
|
||||||
const cameraBottom = camera.actualY + camera.h;
|
const cameraBottom = camera.actualY + camera.h;
|
||||||
|
|
||||||
if (sx > cameraRight || sy > cameraBottom || (sx + w) < cameraLeft || (sy + h) < cameraTop)
|
if (sx > cameraRight || sy > cameraBottom || (sx + w) < cameraLeft || (sy + h) < cameraTop) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (let y = 0; y < h; y++) {
|
for (let y = 0; y < h; y++) {
|
||||||
if ((sy + y + 1) < cameraTop || (sy + y) > cameraBottom)
|
if ((sy + y + 1) < cameraTop || (sy + y) > cameraBottom) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (let x = 0; x < w; x++) {
|
for (let x = 0; x < w; x++) {
|
||||||
if ((sx + x + 1) < cameraLeft || (sx + x) > cameraRight)
|
if ((sx + x + 1) < cameraLeft || (sx + x) > cameraRight) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const tx = x;
|
const tx = x;
|
||||||
|
|
||||||
|
|||||||
+219
-87
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable camelcase */
|
||||||
import { Injectable, NgZone } from '@angular/core';
|
import { Injectable, NgZone } from '@angular/core';
|
||||||
import { Subject, BehaviorSubject } from 'rxjs';
|
import { Subject, BehaviorSubject } from 'rxjs';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
@@ -370,7 +371,8 @@ export class PonyTownGame implements Game {
|
|||||||
send<T>(action: (server: IServerActions) => T) {
|
send<T>(action: (server: IServerActions) => T) {
|
||||||
if (this.socket && this.socket.isConnected) {
|
if (this.socket && this.socket.isConnected) {
|
||||||
return action(this.socket.server);
|
return action(this.socket.server);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -385,11 +387,13 @@ export class PonyTownGame implements Game {
|
|||||||
this.setScale(Math.max(1, this.scale - 1));
|
this.setScale(Math.max(1, this.scale - 1));
|
||||||
}
|
}
|
||||||
select(pony: Pony | undefined) {
|
select(pony: Pony | undefined) {
|
||||||
if (this.selected === pony)
|
if (this.selected === pony) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (pony && isHidden(pony) && !this.mod)
|
if (pony && isHidden(pony) && !this.mod) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.zone.run(() => {
|
this.zone.run(() => {
|
||||||
if (this.selected) {
|
if (this.selected) {
|
||||||
@@ -400,7 +404,8 @@ export class PonyTownGame implements Game {
|
|||||||
|
|
||||||
if (pony && !pony.info && !pony.palettePonyInfo) {
|
if (pony && !pony.info && !pony.palettePonyInfo) {
|
||||||
this.send(server => server.select(pony.id, SelectFlags.FetchEx | SelectFlags.FetchInfo));
|
this.send(server => server.select(pony.id, SelectFlags.FetchEx | SelectFlags.FetchInfo));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.sendSelected();
|
this.sendSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,12 +432,16 @@ export class PonyTownGame implements Game {
|
|||||||
if (!this.initialized) {
|
if (!this.initialized) {
|
||||||
this.canvas.addEventListener('webglcontextlost', e => {
|
this.canvas.addEventListener('webglcontextlost', e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
DEVELOPMENT && console.warn('Context lost');
|
if (DEVELOPMENT) {
|
||||||
|
console.warn('Context lost');
|
||||||
|
}
|
||||||
this.errorReporter.captureEvent({ name: 'Context lost' });
|
this.errorReporter.captureEvent({ name: 'Context lost' });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.canvas.addEventListener('webglcontextrestored', () => {
|
this.canvas.addEventListener('webglcontextrestored', () => {
|
||||||
DEVELOPMENT && console.warn('Context restored');
|
if (DEVELOPMENT) {
|
||||||
|
console.warn('Context restored');
|
||||||
|
}
|
||||||
this.errorReporter.captureEvent({ name: 'Context restored' });
|
this.errorReporter.captureEvent({ name: 'Context restored' });
|
||||||
|
|
||||||
if (this.webgl) {
|
if (this.webgl) {
|
||||||
@@ -573,7 +582,8 @@ export class PonyTownGame implements Game {
|
|||||||
dir = -1;
|
dir = -1;
|
||||||
}
|
}
|
||||||
}, 1000 / 24);
|
}, 1000 / 24);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
let faceDir = 0;
|
let faceDir = 0;
|
||||||
const state = this.player!.ponyState;
|
const state = this.player!.ponyState;
|
||||||
|
|
||||||
@@ -643,7 +653,8 @@ export class PonyTownGame implements Game {
|
|||||||
if (loseContext) {
|
if (loseContext) {
|
||||||
loseContext.restoreContext();
|
loseContext.restoreContext();
|
||||||
loseContext = null;
|
loseContext = null;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
loseContext = this.webgl!.gl.getExtension('WEBGL_lose_context')!;
|
loseContext = this.webgl!.gl.getExtension('WEBGL_lose_context')!;
|
||||||
loseContext.loseContext();
|
loseContext.loseContext();
|
||||||
}
|
}
|
||||||
@@ -661,7 +672,8 @@ export class PonyTownGame implements Game {
|
|||||||
const entity = entities[0];
|
const entity = entities[0];
|
||||||
const typeName = getEntityTypeName(entity.type);
|
const typeName = getEntityTypeName(entity.type);
|
||||||
this.announce(`${typeName}${entities.length > 1 ? ` (1 of ${entities.length})` : ''}`);
|
this.announce(`${typeName}${entities.length > 1 ? ` (1 of ${entities.length})` : ''}`);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.announce('nothing');
|
this.announce('nothing');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -705,7 +717,9 @@ export class PonyTownGame implements Game {
|
|||||||
|
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
this.resized = true;
|
this.resized = true;
|
||||||
DEVELOPMENT && log(`resized ${window.innerHeight} (${window.scrollY})`);
|
if (DEVELOPMENT) {
|
||||||
|
log(`resized ${window.innerHeight} (${window.scrollY})`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.canvas.addEventListener('touchstart', () => this.audio.touch());
|
this.canvas.addEventListener('touchstart', () => this.audio.touch());
|
||||||
@@ -721,7 +735,8 @@ export class PonyTownGame implements Game {
|
|||||||
if (this.socket) {
|
if (this.socket) {
|
||||||
if (this.socket.isConnected) {
|
if (this.socket.isConnected) {
|
||||||
this.socket.server.leave();
|
this.socket.server.leave();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.socket.disconnect();
|
this.socket.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -767,10 +782,13 @@ export class PonyTownGame implements Game {
|
|||||||
this.supporterPony = createPony(0, 0, SUPPORTER_PONY, palettes.defaultPalette, this.paletteManager);
|
this.supporterPony = createPony(0, 0, SUPPORTER_PONY, palettes.defaultPalette, this.paletteManager);
|
||||||
this.discordPony = createPony(0, 0, DISCORD_PONY, palettes.defaultPalette, this.paletteManager);
|
this.discordPony = createPony(0, 0, DISCORD_PONY, palettes.defaultPalette, this.paletteManager);
|
||||||
initializeToys(this.paletteManager);
|
initializeToys(this.paletteManager);
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
this.errorReporter.captureEvent({ name: 'failed game.initWebGL', error: isErrorAlike(e) ? e.message : '', stack: isErrorAlike(e) ? e.stack : '' });
|
this.errorReporter.captureEvent({ name: 'failed game.initWebGL', error: isErrorAlike(e) ? e.message : '', stack: isErrorAlike(e) ? e.stack : '' });
|
||||||
this.releaseWebGL();
|
this.releaseWebGL();
|
||||||
DEVELOPMENT && console.error(e);
|
if (DEVELOPMENT) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
throw new Error(`Failed to initialize graphics device (${isErrorAlike(e) ? e.message : 'Unknown error'})`);
|
throw new Error(`Failed to initialize graphics device (${isErrorAlike(e) ? e.message : 'Unknown error'})`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -781,8 +799,11 @@ export class PonyTownGame implements Game {
|
|||||||
try {
|
try {
|
||||||
this.paletteManager.dispose(this.webgl.gl);
|
this.paletteManager.dispose(this.webgl.gl);
|
||||||
disposeWebGL(this.webgl);
|
disposeWebGL(this.webgl);
|
||||||
} catch (e) {
|
}
|
||||||
DEVELOPMENT && console.error(e);
|
catch (e) {
|
||||||
|
if (DEVELOPMENT) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.webgl = undefined;
|
this.webgl = undefined;
|
||||||
@@ -827,7 +848,8 @@ export class PonyTownGame implements Game {
|
|||||||
startup(socket: ClientSocketService, mod: boolean) {
|
startup(socket: ClientSocketService, mod: boolean) {
|
||||||
if (this.settings.account.actions) {
|
if (this.settings.account.actions) {
|
||||||
this.actions = deserializeActions(this.settings.account.actions);
|
this.actions = deserializeActions(this.settings.account.actions);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.actions = createDefaultButtonActions();
|
this.actions = createDefaultButtonActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -860,21 +882,25 @@ export class PonyTownGame implements Game {
|
|||||||
return this.scale * (integerPixelRatio() / pixelRatio());
|
return this.scale * (integerPixelRatio() / pixelRatio());
|
||||||
}
|
}
|
||||||
update(delta: number, now: number, last: number) {
|
update(delta: number, now: number, last: number) {
|
||||||
TIMING && timeStart('update');
|
if (TIMING) {
|
||||||
|
timeStart('update');
|
||||||
|
}
|
||||||
delta *= this.deltaMultiplier;
|
delta *= this.deltaMultiplier;
|
||||||
|
|
||||||
const shiftSpeed = delta * 10;
|
const shiftSpeed = delta * 10;
|
||||||
|
|
||||||
if (this.cameraShiftOn && this.camera.shiftRatio !== 1) {
|
if (this.cameraShiftOn && this.camera.shiftRatio !== 1) {
|
||||||
this.camera.shiftRatio = Math.min(1, this.camera.shiftRatio + shiftSpeed);
|
this.camera.shiftRatio = Math.min(1, this.camera.shiftRatio + shiftSpeed);
|
||||||
} else if (!this.cameraShiftOn && this.camera.shiftRatio !== 0) {
|
}
|
||||||
|
else if (!this.cameraShiftOn && this.camera.shiftRatio !== 0) {
|
||||||
this.camera.shiftRatio = Math.max(0, this.camera.shiftRatio - shiftSpeed);
|
this.camera.shiftRatio = Math.max(0, this.camera.shiftRatio - shiftSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMap(this.map, delta);
|
updateMap(this.map, delta);
|
||||||
|
|
||||||
if (!this.socket || !this.socket.isConnected || !this.element)
|
if (!this.socket || !this.socket.isConnected || !this.element) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.updateGameTime(delta);
|
this.updateGameTime(delta);
|
||||||
|
|
||||||
@@ -986,7 +1012,8 @@ export class PonyTownGame implements Game {
|
|||||||
if (hasFlag(this.map.flags, MapFlags.EditableEntities)) {
|
if (hasFlag(this.map.flags, MapFlags.EditableEntities)) {
|
||||||
if (player.hold === removeEntitiesTool.type) {
|
if (player.hold === removeEntitiesTool.type) {
|
||||||
this.highlightEntity = pickEntities(this.map, hover, true, false, true)[0];
|
this.highlightEntity = pickEntities(this.map, hover, true, false, true)[0];
|
||||||
} else if (player.hold === placeEntitiesTool.type) {
|
}
|
||||||
|
else if (player.hold === placeEntitiesTool.type) {
|
||||||
if (!isOutsideMap(hover.x, hover.y, this.map)) {
|
if (!isOutsideMap(hover.x, hover.y, this.map)) {
|
||||||
const { type } = placeableEntities[this.placeEntity];
|
const { type } = placeableEntities[this.placeEntity];
|
||||||
let { x, y } = hover;
|
let { x, y } = hover;
|
||||||
@@ -1011,38 +1038,48 @@ export class PonyTownGame implements Game {
|
|||||||
|
|
||||||
if (BETA && this.editor.selectingEntities) {
|
if (BETA && this.editor.selectingEntities) {
|
||||||
editorSelectEntities(this, hover, shift);
|
editorSelectEntities(this, hover, shift);
|
||||||
} else if (pickedEntity && (!holdingTool || !editableMap || hasFlag(pickedEntity.flags, EntityFlags.IgnoreTool))) {
|
}
|
||||||
|
else if (pickedEntity && (!holdingTool || !editableMap || hasFlag(pickedEntity.flags, EntityFlags.IgnoreTool))) {
|
||||||
if (pickedEntity.type === PONY_TYPE) {
|
if (pickedEntity.type === PONY_TYPE) {
|
||||||
this.select(pickedEntity as Pony);
|
this.select(pickedEntity as Pony);
|
||||||
} else if (entityInRange(pickedEntity, player)) {
|
}
|
||||||
|
else if (entityInRange(pickedEntity, player)) {
|
||||||
server.interact(pickedEntity.id);
|
server.interact(pickedEntity.id);
|
||||||
}
|
}
|
||||||
} else if (BETA && this.editor.tile !== -1) {
|
}
|
||||||
|
else if (BETA && this.editor.tile !== -1) {
|
||||||
if (this.editor.brushSize > 1) {
|
if (this.editor.brushSize > 1) {
|
||||||
const x = Math.floor((hover.x - (this.editor.brushSize / 2)));
|
const x = Math.floor((hover.x - (this.editor.brushSize / 2)));
|
||||||
const y = Math.floor((hover.y - (this.editor.brushSize / 2)));
|
const y = Math.floor((hover.y - (this.editor.brushSize / 2)));
|
||||||
server.editorAction({ type: 'tile', x, y, tile: this.editor.tile, size: this.editor.brushSize });
|
server.editorAction({ type: 'tile', x, y, tile: this.editor.tile, size: this.editor.brushSize });
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const x = hover.x | 0;
|
const x = hover.x | 0;
|
||||||
const y = hover.y | 0;
|
const y = hover.y | 0;
|
||||||
const type = this.editor.tile === getTile(this.map, hover.x, hover.y) ? TileType.Dirt : this.editor.tile;
|
const type = this.editor.tile === getTile(this.map, hover.x, hover.y) ? TileType.Dirt : this.editor.tile;
|
||||||
server.changeTile(x, y, type);
|
server.changeTile(x, y, type);
|
||||||
}
|
}
|
||||||
} else if (player.hold === changeTileTool.type && hasFlag(this.map.flags, MapFlags.EditableTiles)) {
|
}
|
||||||
|
else if (player.hold === changeTileTool.type && hasFlag(this.map.flags, MapFlags.EditableTiles)) {
|
||||||
const x = hover.x | 0;
|
const x = hover.x | 0;
|
||||||
const y = hover.y | 0;
|
const y = hover.y | 0;
|
||||||
server.changeTile(x, y, houseTiles[this.placeTile].type);
|
server.changeTile(x, y, houseTiles[this.placeTile].type);
|
||||||
} else if (player.hold === toggleWallsTool.type && hasFlag(this.map.flags, MapFlags.EditableWalls)) {
|
}
|
||||||
|
else if (player.hold === toggleWallsTool.type && hasFlag(this.map.flags, MapFlags.EditableWalls)) {
|
||||||
toggleWall(this, hover);
|
toggleWall(this, hover);
|
||||||
} else if (holdingRemoveTool && this.highlightEntity && editableMap) {
|
}
|
||||||
|
else if (holdingRemoveTool && this.highlightEntity && editableMap) {
|
||||||
const id = this.highlightEntity.id;
|
const id = this.highlightEntity.id;
|
||||||
this.send(server => server.actionParam(Action.RemoveEntity, id));
|
this.send(server => server.actionParam(Action.RemoveEntity, id));
|
||||||
} else if (holdingPlaceTool && this.highlightEntity && editableMap) {
|
}
|
||||||
|
else if (holdingPlaceTool && this.highlightEntity && editableMap) {
|
||||||
const { x, y, type } = this.highlightEntity;
|
const { x, y, type } = this.highlightEntity;
|
||||||
this.send(server => server.actionParam(Action.PlaceEntity, { x, y, type }));
|
this.send(server => server.actionParam(Action.PlaceEntity, { x, y, type }));
|
||||||
} else if (this.selected) {
|
}
|
||||||
|
else if (this.selected) {
|
||||||
this.select(undefined);
|
this.select(undefined);
|
||||||
} else if (hasFlag(this.map.flags, MapFlags.EdibleGrass)) {
|
}
|
||||||
|
else if (hasFlag(this.map.flags, MapFlags.EdibleGrass)) {
|
||||||
const tile = getTile(this.map, hover.x, hover.y);
|
const tile = getTile(this.map, hover.x, hover.y);
|
||||||
|
|
||||||
if (isValidTile(tile) && distanceXY(player.x, player.y, hover.x, hover.y) < TILE_CHANGE_RANGE) {
|
if (isValidTile(tile) && distanceXY(player.x, player.y, hover.x, hover.y) < TILE_CHANGE_RANGE) {
|
||||||
@@ -1051,7 +1088,8 @@ export class PonyTownGame implements Game {
|
|||||||
let type = tile === TileType.Grass ? TileType.Dirt : TileType.Grass;
|
let type = tile === TileType.Grass ? TileType.Dirt : TileType.Grass;
|
||||||
server.changeTile(x, y, type);
|
server.changeTile(x, y, type);
|
||||||
}
|
}
|
||||||
} else if (DEVELOPMENT && this.engine === Engine.LayeredTiles && this.editor.elevation) {
|
}
|
||||||
|
else if (DEVELOPMENT && this.engine === Engine.LayeredTiles && this.editor.elevation) {
|
||||||
const value = getElevation(this.map, hover.x, hover.y);
|
const value = getElevation(this.map, hover.x, hover.y);
|
||||||
setElevation(this.map, hover.x, hover.y, clamp(this.editor.elevation === 'up' ? value + 1 : value - 1, 0, 10));
|
setElevation(this.map, hover.x, hover.y, clamp(this.editor.elevation === 'up' ? value + 1 : value - 1, 0, 10));
|
||||||
}
|
}
|
||||||
@@ -1060,7 +1098,8 @@ export class PonyTownGame implements Game {
|
|||||||
if (BETA && input.wasPressed(Key.MOUSE_BUTTON2)) {
|
if (BETA && input.wasPressed(Key.MOUSE_BUTTON2)) {
|
||||||
if (this.editor.selectingEntities) {
|
if (this.editor.selectingEntities) {
|
||||||
editorMoveEntities(this, hover);
|
editorMoveEntities(this, hover);
|
||||||
} else if (this.mod) {
|
}
|
||||||
|
else if (this.mod) {
|
||||||
toggleWall(this, hover);
|
toggleWall(this, hover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1078,10 +1117,12 @@ export class PonyTownGame implements Game {
|
|||||||
const action = input.wheelY < 0 ? Action.SwitchTool : Action.SwitchToolRev;
|
const action = input.wheelY < 0 ? Action.SwitchTool : Action.SwitchToolRev;
|
||||||
this.send(server => server.action(action));
|
this.send(server => server.action(action));
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (this.player.hold === placeEntitiesTool.type) {
|
if (this.player.hold === placeEntitiesTool.type) {
|
||||||
this.changePlaceEntity(input.wheelY < 0);
|
this.changePlaceEntity(input.wheelY < 0);
|
||||||
} else if (this.player.hold === changeTileTool.type) {
|
}
|
||||||
|
else if (this.player.hold === changeTileTool.type) {
|
||||||
this.changePlaceTile(input.wheelY < 0);
|
this.changePlaceTile(input.wheelY < 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1144,7 +1185,9 @@ export class PonyTownGame implements Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.updateSocketStats(delta);
|
this.updateSocketStats(delta);
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
if (DEVELOPMENT && LOG_POSITION) {
|
if (DEVELOPMENT && LOG_POSITION) {
|
||||||
if (this.player) {
|
if (this.player) {
|
||||||
@@ -1159,7 +1202,8 @@ export class PonyTownGame implements Game {
|
|||||||
|
|
||||||
if (Math.abs(this.targetBaseTime - baseTime) < timeDelta) {
|
if (Math.abs(this.targetBaseTime - baseTime) < timeDelta) {
|
||||||
this.baseTime = this.targetBaseTime;
|
this.baseTime = this.targetBaseTime;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.baseTime = baseTime;
|
this.baseTime = baseTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1188,7 +1232,8 @@ export class PonyTownGame implements Game {
|
|||||||
|
|
||||||
if (initial) {
|
if (initial) {
|
||||||
this.baseTime = this.targetBaseTime = baseTime;
|
this.baseTime = this.targetBaseTime = baseTime;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.targetBaseTime = baseTime;
|
this.targetBaseTime = baseTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1218,11 +1263,14 @@ export class PonyTownGame implements Game {
|
|||||||
redrawActionButtons(this.actionsChanged);
|
redrawActionButtons(this.actionsChanged);
|
||||||
this.actionsChanged = false;
|
this.actionsChanged = false;
|
||||||
|
|
||||||
if (!this.webgl)
|
if (!this.webgl) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.webgl.gl.isContextLost()) {
|
if (this.webgl.gl.isContextLost()) {
|
||||||
DEVELOPMENT && console.warn('Context is lost');
|
if (DEVELOPMENT) {
|
||||||
|
console.warn('Context is lost');
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1247,16 +1295,21 @@ export class PonyTownGame implements Game {
|
|||||||
const { gl, frameBuffer, frameBuffer2, spriteBatch, paletteBatch, palettes, failedFBO,
|
const { gl, frameBuffer, frameBuffer2, spriteBatch, paletteBatch, palettes, failedFBO,
|
||||||
mergeShader, paletteShader, spriteShader, spriteShaderWithColor, lightShader } = this.webgl;
|
mergeShader, paletteShader, spriteShader, spriteShaderWithColor, lightShader } = this.webgl;
|
||||||
|
|
||||||
TIMING && timeStart('draw');
|
if (TIMING) {
|
||||||
|
timeStart('draw');
|
||||||
|
}
|
||||||
|
|
||||||
TIMING && timeStart('draw init');
|
if (TIMING) {
|
||||||
|
timeStart('draw init');
|
||||||
|
}
|
||||||
let lightColor = WHITE;
|
let lightColor = WHITE;
|
||||||
let shadowColor = 0;
|
let shadowColor = 0;
|
||||||
|
|
||||||
if (this.map.type === MapType.Cave) {
|
if (this.map.type === MapType.Cave) {
|
||||||
lightColor = CAVE_LIGHT;
|
lightColor = CAVE_LIGHT;
|
||||||
shadowColor = CAVE_SHADOW;
|
shadowColor = CAVE_SHADOW;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
lightColor = getLightColor(this.lightData, this.time);
|
lightColor = getLightColor(this.lightData, this.time);
|
||||||
shadowColor = getShadowColor(this.lightData, this.time);
|
shadowColor = getShadowColor(this.lightData, this.time);
|
||||||
}
|
}
|
||||||
@@ -1291,17 +1344,27 @@ export class PonyTownGame implements Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ortho(this.fboMatrix, 0, gl.drawingBufferWidth / actualScale, gl.drawingBufferHeight / actualScale, 0, 0, 1000, false);
|
ortho(this.fboMatrix, 0, gl.drawingBufferWidth / actualScale, gl.drawingBufferHeight / actualScale, 0, 0, 1000, false);
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
TIMING && timeStart('ensureAllVisiblePon...');
|
if (TIMING) {
|
||||||
|
timeStart('ensureAllVisiblePon...');
|
||||||
|
}
|
||||||
ensureAllVisiblePoniesAreDecoded(this.map, camera, this.paletteManager);
|
ensureAllVisiblePoniesAreDecoded(this.map, camera, this.paletteManager);
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
TIMING && timeStart('commit+invalidatePalettes');
|
if (TIMING) {
|
||||||
|
timeStart('commit+invalidatePalettes');
|
||||||
|
}
|
||||||
if (this.paletteManager.commit(gl)) {
|
if (this.paletteManager.commit(gl)) {
|
||||||
invalidatePalettes(this.map.entitiesDrawable);
|
invalidatePalettes(this.map.entitiesDrawable);
|
||||||
}
|
}
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
if (this.settings.browser.brightNight) {
|
if (this.settings.browser.brightNight) {
|
||||||
lerpColor(light, white, 0.3);
|
lerpColor(light, white, 0.3);
|
||||||
@@ -1310,9 +1373,13 @@ export class PonyTownGame implements Game {
|
|||||||
// you'd draw directly onto the screen only when there's no framebuffer
|
// you'd draw directly onto the screen only when there's no framebuffer
|
||||||
// or the graphics is low and framebuffer size matches screen size
|
// or the graphics is low and framebuffer size matches screen size
|
||||||
|
|
||||||
TIMING && timeStart('initializeFrameBuffers');
|
if (TIMING) {
|
||||||
|
timeStart('initializeFrameBuffers');
|
||||||
|
}
|
||||||
this.initializeFrameBuffers(this.webgl, width, height, this.settings.browser.graphicsQuality === GraphicsQuality.High);
|
this.initializeFrameBuffers(this.webgl, width, height, this.settings.browser.graphicsQuality === GraphicsQuality.High);
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
const useDepthBuffer =
|
const useDepthBuffer =
|
||||||
!failedFBO && (this.settings.browser.graphicsQuality === GraphicsQuality.High) && !!frameBuffer!.depthStencilRenderbuffer;
|
!failedFBO && (this.settings.browser.graphicsQuality === GraphicsQuality.High) && !!frameBuffer!.depthStencilRenderbuffer;
|
||||||
@@ -1342,12 +1409,16 @@ export class PonyTownGame implements Game {
|
|||||||
gl.depthFunc(gl.ALWAYS);
|
gl.depthFunc(gl.ALWAYS);
|
||||||
|
|
||||||
if (drawSceneDirectlyOntoScreen) {
|
if (drawSceneDirectlyOntoScreen) {
|
||||||
TIMING && timeStart('color -> screen');
|
if (TIMING) {
|
||||||
|
timeStart('color -> screen');
|
||||||
|
}
|
||||||
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||||
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
||||||
this.drawMap(this.webgl, this.map, this.viewMatrix, mapDrawingColor, drawOptions);
|
this.drawMap(this.webgl, this.map, this.viewMatrix, mapDrawingColor, drawOptions);
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// if (!isWebGL2(gl)) {
|
// if (!isWebGL2(gl)) {
|
||||||
@@ -1361,17 +1432,23 @@ export class PonyTownGame implements Game {
|
|||||||
clearMask |= gl.DEPTH_BUFFER_BIT;
|
clearMask |= gl.DEPTH_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIMING && timeStart('color -> framebuffer');
|
if (TIMING) {
|
||||||
|
timeStart('color -> framebuffer');
|
||||||
|
}
|
||||||
bindFrameBuffer(gl, frameBuffer!);
|
bindFrameBuffer(gl, frameBuffer!);
|
||||||
gl.viewport(0, 0, frameBuffer!.width, frameBuffer!.height); // clearing the whole surface is preferable for most GPUs
|
gl.viewport(0, 0, frameBuffer!.width, frameBuffer!.height); // clearing the whole surface is preferable for most GPUs
|
||||||
gl.clear(clearMask);
|
gl.clear(clearMask);
|
||||||
gl.viewport(0, 0, width, height);
|
gl.viewport(0, 0, width, height);
|
||||||
this.drawMap(this.webgl, this.map, this.viewMatrix, mapDrawingColor, drawOptions);
|
this.drawMap(this.webgl, this.map, this.viewMatrix, mapDrawingColor, drawOptions);
|
||||||
gl.depthMask(false);
|
gl.depthMask(false);
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
if (useLighting) {
|
if (useLighting) {
|
||||||
TIMING && timeStart('light -> fbo');
|
if (TIMING) {
|
||||||
|
timeStart('light -> fbo');
|
||||||
|
}
|
||||||
bindFrameBuffer(gl, frameBuffer2!);
|
bindFrameBuffer(gl, frameBuffer2!);
|
||||||
gl.viewport(0, 0, frameBuffer2!.width, frameBuffer2!.height); // clearing the whole surface is preferable for most GPUs
|
gl.viewport(0, 0, frameBuffer2!.width, frameBuffer2!.height); // clearing the whole surface is preferable for most GPUs
|
||||||
gl.clearColor(light[0], light[1], light[2], light[3]);
|
gl.clearColor(light[0], light[1], light[2], light[3]);
|
||||||
@@ -1402,9 +1479,13 @@ export class PonyTownGame implements Game {
|
|||||||
if (isWebGL2(gl)) {
|
if (isWebGL2(gl)) {
|
||||||
(gl as WebGL2RenderingContext).invalidateFramebuffer(gl.FRAMEBUFFER, [gl.DEPTH_ATTACHMENT]);
|
(gl as WebGL2RenderingContext).invalidateFramebuffer(gl.FRAMEBUFFER, [gl.DEPTH_ATTACHMENT]);
|
||||||
}
|
}
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
TIMING && timeStart('color + lights -> screen');
|
if (TIMING) {
|
||||||
|
timeStart('color + lights -> screen');
|
||||||
|
}
|
||||||
unbindFrameBuffer(gl);
|
unbindFrameBuffer(gl);
|
||||||
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
||||||
gl.disable(gl.BLEND);
|
gl.disable(gl.BLEND);
|
||||||
@@ -1417,10 +1498,14 @@ export class PonyTownGame implements Game {
|
|||||||
spriteBatch.begin();
|
spriteBatch.begin();
|
||||||
spriteBatch.drawImage(WHITE, 0, 0, width, height, 0, 0, width, height);
|
spriteBatch.drawImage(WHITE, 0, 0, width, height, 0, 0, width, height);
|
||||||
spriteBatch.end();
|
spriteBatch.end();
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TIMING && timeStart('color framebuffer -> screen');
|
if (TIMING) {
|
||||||
|
timeStart('color framebuffer -> screen');
|
||||||
|
}
|
||||||
unbindFrameBuffer(gl);
|
unbindFrameBuffer(gl);
|
||||||
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
||||||
gl.disable(gl.BLEND);
|
gl.disable(gl.BLEND);
|
||||||
@@ -1433,7 +1518,9 @@ export class PonyTownGame implements Game {
|
|||||||
spriteBatch.begin();
|
spriteBatch.begin();
|
||||||
spriteBatch.drawImage(WHITE, 0, 0, width, height, 0, 0, width, height);
|
spriteBatch.drawImage(WHITE, 0, 0, width, height, 0, 0, width, height);
|
||||||
spriteBatch.end();
|
spriteBatch.end();
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1442,7 +1529,9 @@ export class PonyTownGame implements Game {
|
|||||||
gl.blendEquation(gl.FUNC_ADD);
|
gl.blendEquation(gl.FUNC_ADD);
|
||||||
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
TIMING && timeStart('drawNames+drawChat');
|
if (TIMING) {
|
||||||
|
timeStart('drawNames+drawChat');
|
||||||
|
}
|
||||||
gl.useProgram(paletteShader.program);
|
gl.useProgram(paletteShader.program);
|
||||||
gl.uniformMatrix4fv(paletteShader.uniforms.transform, false, this.fboMatrix);
|
gl.uniformMatrix4fv(paletteShader.uniforms.transform, false, this.fboMatrix);
|
||||||
gl.uniform4fv(paletteShader.uniforms.lighting, white);
|
gl.uniform4fv(paletteShader.uniforms.lighting, white);
|
||||||
@@ -1461,13 +1550,16 @@ export class PonyTownGame implements Game {
|
|||||||
|
|
||||||
if (!this.socket || !this.socket.isConnected) {
|
if (!this.socket || !this.socket.isConnected) {
|
||||||
this.drawMessage(this.webgl, 'Connecting...');
|
this.drawMessage(this.webgl, 'Connecting...');
|
||||||
} else if (!this.loaded) {
|
}
|
||||||
|
else if (!this.loaded) {
|
||||||
if (this.placeInQueue) {
|
if (this.placeInQueue) {
|
||||||
this.drawMessage(this.webgl, `Waiting in queue (${this.placeInQueue})`);
|
this.drawMessage(this.webgl, `Waiting in queue (${this.placeInQueue})`);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.drawMessage(this.webgl, 'Loading...');
|
this.drawMessage(this.webgl, 'Loading...');
|
||||||
}
|
}
|
||||||
} else if ((performance.now() - this.socket.lastPacket) > CONNECTION_ISSUE_TIMEOUT) {
|
}
|
||||||
|
else if ((performance.now() - this.socket.lastPacket) > CONNECTION_ISSUE_TIMEOUT) {
|
||||||
// this.drawMessage('Connection issues...');
|
// this.drawMessage('Connection issues...');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1478,7 +1570,8 @@ export class PonyTownGame implements Game {
|
|||||||
const y = this.input.pointerY / scale;
|
const y = this.input.pointerY / scale;
|
||||||
const height = getMapHeightAt(this.map, this.hover.x, this.hover.y, this.time);
|
const height = getMapHeightAt(this.map, this.hover.x, this.hover.y, this.time);
|
||||||
drawText(paletteBatch, `${height.toFixed(2)}`, fontSmallPal, BLACK, x, y);
|
drawText(paletteBatch, `${height.toFixed(2)}`, fontSmallPal, BLACK, x, y);
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
console.warn(e);
|
console.warn(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1497,13 +1590,16 @@ export class PonyTownGame implements Game {
|
|||||||
if (dx > dy) {
|
if (dx > dy) {
|
||||||
if ((dx + dy) < 1) {
|
if ((dx + dy) < 1) {
|
||||||
paletteBatch.drawSprite(wall_h_placeholder.color, color, palette, screenX, screenY - 15);
|
paletteBatch.drawSprite(wall_h_placeholder.color, color, palette, screenX, screenY - 15);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
paletteBatch.drawSprite(wall_v_placeholder.color, color, palette, screenX + tileWidth - 4, screenY - 12);
|
paletteBatch.drawSprite(wall_v_placeholder.color, color, palette, screenX + tileWidth - 4, screenY - 12);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if ((dx + dy) < 1) {
|
if ((dx + dy) < 1) {
|
||||||
paletteBatch.drawSprite(wall_v_placeholder.color, color, palette, screenX - 4, screenY - 12);
|
paletteBatch.drawSprite(wall_v_placeholder.color, color, palette, screenX - 4, screenY - 12);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
paletteBatch.drawSprite(wall_h_placeholder.color, color, palette, screenX, screenY + tileHeight - 15);
|
paletteBatch.drawSprite(wall_h_placeholder.color, color, palette, screenX, screenY + tileHeight - 15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1511,7 +1607,9 @@ export class PonyTownGame implements Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
paletteBatch.end();
|
paletteBatch.end();
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
gl.useProgram(spriteShaderWithColor.program);
|
gl.useProgram(spriteShaderWithColor.program);
|
||||||
gl.uniformMatrix4fv(spriteShaderWithColor.uniforms.transform, false, this.fboMatrix);
|
gl.uniformMatrix4fv(spriteShaderWithColor.uniforms.transform, false, this.fboMatrix);
|
||||||
@@ -1562,7 +1660,9 @@ export class PonyTownGame implements Game {
|
|||||||
|
|
||||||
if (showFPS || showHelp || showPalette || showAdditionalStats) {
|
if (showFPS || showHelp || showPalette || showAdditionalStats) {
|
||||||
// 1 to 1 pixel scale drawing
|
// 1 to 1 pixel scale drawing
|
||||||
TIMING && timeStart('showFps');
|
if (TIMING) {
|
||||||
|
timeStart('showFps');
|
||||||
|
}
|
||||||
const scale = 2;
|
const scale = 2;
|
||||||
ortho(this.fboMatrix, 0, gl.drawingBufferWidth / ratio, gl.drawingBufferHeight / ratio, 0, 0, 1000, false);
|
ortho(this.fboMatrix, 0, gl.drawingBufferWidth / ratio, gl.drawingBufferHeight / ratio, 0, 0, 1000, false);
|
||||||
gl.uniformMatrix4fv(spriteShaderWithColor.uniforms.transform, false, this.fboMatrix);
|
gl.uniformMatrix4fv(spriteShaderWithColor.uniforms.transform, false, this.fboMatrix);
|
||||||
@@ -1626,25 +1726,37 @@ export class PonyTownGame implements Game {
|
|||||||
spriteBatch.end();
|
spriteBatch.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bindTexture(gl, 0, undefined);
|
bindTexture(gl, 0, undefined);
|
||||||
bindTexture(gl, 1, undefined);
|
bindTexture(gl, 1, undefined);
|
||||||
gl.useProgram(null);
|
gl.useProgram(null);
|
||||||
|
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
this.updateStatsText();
|
this.updateStatsText();
|
||||||
|
|
||||||
TIMING && timeStart('messageQueue');
|
if (TIMING) {
|
||||||
|
timeStart('messageQueue');
|
||||||
|
}
|
||||||
while (this.messageQueue.length) {
|
while (this.messageQueue.length) {
|
||||||
this.onMessage.next(this.messageQueue.shift()!);
|
this.onMessage.next(this.messageQueue.shift()!);
|
||||||
}
|
}
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
TIMING && timeStart('onFrame');
|
if (TIMING) {
|
||||||
|
timeStart('onFrame');
|
||||||
|
}
|
||||||
this.onFrame.next();
|
this.onFrame.next();
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private drawMessage({ paletteBatch, palettes }: WebGL, message: string) {
|
private drawMessage({ paletteBatch, palettes }: WebGL, message: string) {
|
||||||
drawFullScreenMessage(paletteBatch, this.camera, message, palettes.mainFont.white);
|
drawFullScreenMessage(paletteBatch, this.camera, message, palettes.mainFont.white);
|
||||||
@@ -1654,7 +1766,9 @@ export class PonyTownGame implements Game {
|
|||||||
|
|
||||||
const mapPaletteShader = options.useDepthBuffer ? paletteShaderWithDepth : paletteShader;
|
const mapPaletteShader = options.useDepthBuffer ? paletteShaderWithDepth : paletteShader;
|
||||||
|
|
||||||
TIMING && timeStart('drawMap');
|
if (TIMING) {
|
||||||
|
timeStart('drawMap');
|
||||||
|
}
|
||||||
if (this.tileSets && this.player) {
|
if (this.tileSets && this.player) {
|
||||||
gl.useProgram(mapPaletteShader.program);
|
gl.useProgram(mapPaletteShader.program);
|
||||||
gl.uniformMatrix4fv(mapPaletteShader.uniforms.transform, false, viewMatrix);
|
gl.uniformMatrix4fv(mapPaletteShader.uniforms.transform, false, viewMatrix);
|
||||||
@@ -1675,14 +1789,18 @@ export class PonyTownGame implements Game {
|
|||||||
paletteBatch.end();
|
paletteBatch.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private updateCameraShift() {
|
private updateCameraShift() {
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
const isKeyboardOpen = !!document.activeElement && /input/i.test(document.activeElement.tagName);
|
const isKeyboardOpen = !!document.activeElement && /input/i.test(document.activeElement.tagName);
|
||||||
|
|
||||||
if (this.lastIsKeyboardOpen !== isKeyboardOpen) {
|
if (this.lastIsKeyboardOpen !== isKeyboardOpen) {
|
||||||
DEVELOPMENT && log(`keyboard open ${isKeyboardOpen}`);
|
if (DEVELOPMENT) {
|
||||||
|
log(`keyboard open ${isKeyboardOpen}`);
|
||||||
|
}
|
||||||
this.lastIsKeyboardOpen = isKeyboardOpen;
|
this.lastIsKeyboardOpen = isKeyboardOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1695,10 +1813,13 @@ export class PonyTownGame implements Game {
|
|||||||
log(`shift camera ${this.cameraShiftTarget} (${this.windowHeight} - ${window.innerHeight}, ${window.scrollY})`);
|
log(`shift camera ${this.cameraShiftTarget} (${this.windowHeight} - ${window.innerHeight}, ${window.scrollY})`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (this.cameraShiftOn && window.scrollY < 100) {
|
if (this.cameraShiftOn && window.scrollY < 100) {
|
||||||
this.cameraShiftOn = false;
|
this.cameraShiftOn = false;
|
||||||
DEVELOPMENT && log(`unshift camera`);
|
if (DEVELOPMENT) {
|
||||||
|
log(`unshift camera`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1728,7 +1849,9 @@ export class PonyTownGame implements Game {
|
|||||||
canvas.style.height = `${h / ratio}px`;
|
canvas.style.height = `${h / ratio}px`;
|
||||||
this.lastCanvasRatio = ratio;
|
this.lastCanvasRatio = ratio;
|
||||||
this.resized = false;
|
this.resized = false;
|
||||||
DEVELOPMENT && log(`scrollY: ${window.scrollY}`);
|
if (DEVELOPMENT) {
|
||||||
|
log(`scrollY: ${window.scrollY}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private initializeFrameBuffers(
|
private initializeFrameBuffers(
|
||||||
@@ -1748,8 +1871,11 @@ export class PonyTownGame implements Game {
|
|||||||
|
|
||||||
if (isSizeTooBig) {
|
if (isSizeTooBig) {
|
||||||
this.setScale(this.scale + 1); // should not happen, useDepthBuffer is also ignored if it does
|
this.setScale(this.scale + 1); // should not happen, useDepthBuffer is also ignored if it does
|
||||||
DEVELOPMENT && console.warn('Cannot resize framebuffer');
|
if (DEVELOPMENT) {
|
||||||
} else {
|
console.warn('Cannot resize framebuffer');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
disposeFrameBuffer(gl, frameBuffer);
|
disposeFrameBuffer(gl, frameBuffer);
|
||||||
disposeFrameBuffer(gl, frameBuffer2);
|
disposeFrameBuffer(gl, frameBuffer2);
|
||||||
createFrameBuffer(gl, frameBuffer, width, height, useDepthBuffer, null);
|
createFrameBuffer(gl, frameBuffer, width, height, useDepthBuffer, null);
|
||||||
@@ -1763,7 +1889,8 @@ export class PonyTownGame implements Game {
|
|||||||
changePlaceEntity(reverse: boolean) {
|
changePlaceEntity(reverse: boolean) {
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
this.placeEntity = this.placeEntity === 0 ? (placeableEntities.length - 1) : (this.placeEntity - 1);
|
this.placeEntity = this.placeEntity === 0 ? (placeableEntities.length - 1) : (this.placeEntity - 1);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.placeEntity = (this.placeEntity + 1) % placeableEntities.length;
|
this.placeEntity = (this.placeEntity + 1) % placeableEntities.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1774,7 +1901,8 @@ export class PonyTownGame implements Game {
|
|||||||
changePlaceTile(reverse: boolean) {
|
changePlaceTile(reverse: boolean) {
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
this.placeTile = this.placeTile === 0 ? (houseTiles.length - 1) : (this.placeTile - 1);
|
this.placeTile = this.placeTile === 0 ? (houseTiles.length - 1) : (this.placeTile - 1);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.placeTile = (this.placeTile + 1) % houseTiles.length;
|
this.placeTile = (this.placeTile + 1) % houseTiles.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1789,7 +1917,9 @@ export class PonyTownGame implements Game {
|
|||||||
const { gl, spriteBatch, paletteBatch } = this.webgl!;
|
const { gl, spriteBatch, paletteBatch } = this.webgl!;
|
||||||
|
|
||||||
if ((performance.now() - this.lastStats) > SECOND) {
|
if ((performance.now() - this.lastStats) > SECOND) {
|
||||||
TIMING && timingCollate();
|
if (TIMING) {
|
||||||
|
timingCollate();
|
||||||
|
}
|
||||||
|
|
||||||
if (TIMING) {
|
if (TIMING) {
|
||||||
const timings = timingCollate();
|
const timings = timingCollate();
|
||||||
@@ -1834,7 +1964,9 @@ export class PonyTownGame implements Game {
|
|||||||
this.onClock.next(formatHourMinutes(this.time));
|
this.onClock.next(formatHourMinutes(this.time));
|
||||||
}
|
}
|
||||||
|
|
||||||
TIMING && timeReset();
|
if (TIMING) {
|
||||||
|
timeReset();
|
||||||
|
}
|
||||||
|
|
||||||
spriteBatch!.drawnTrisStats = 0;
|
spriteBatch!.drawnTrisStats = 0;
|
||||||
spriteBatch!.flushes = 0;
|
spriteBatch!.flushes = 0;
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ export function startGameLoop(game: Game, onError = (e: Error) => console.error(
|
|||||||
if (draw) {
|
if (draw) {
|
||||||
game.draw();
|
game.draw();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
if (isError(e)) {
|
if (isError(e)) {
|
||||||
onError(e);
|
onError(e);
|
||||||
}
|
}
|
||||||
@@ -80,7 +81,8 @@ export function startGameLoop(game: Game, onError = (e: Error) => console.error(
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
if (cancelled) {
|
if (cancelled) {
|
||||||
throw new Error('Cancelled (loop)');
|
throw new Error('Cancelled (loop)');
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
game.init();
|
game.init();
|
||||||
handle = requestAnimationFrame(onFrame);
|
handle = requestAnimationFrame(onFrame);
|
||||||
backup = setTimeout(onTimer, 1000 / 10);
|
backup = setTimeout(onTimer, 1000 / 10);
|
||||||
|
|||||||
+73
-35
@@ -130,7 +130,8 @@ export function handleUpdateEntity(game: PonyTownGame, update: DecodedUpdate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (distanceXY(entity.x, entity.y, x, y) > 8) {
|
}
|
||||||
|
else if (distanceXY(entity.x, entity.y, x, y) > 8) {
|
||||||
log(`Fixing player position (${entity.x}, ${entity.y}) => (${x}, ${y})`);
|
log(`Fixing player position (${entity.x}, ${entity.y}) => (${x}, ${y})`);
|
||||||
entity.x = x;
|
entity.x = x;
|
||||||
entity.y = y;
|
entity.y = y;
|
||||||
@@ -163,7 +164,8 @@ export function handleUpdateEntity(game: PonyTownGame, update: DecodedUpdate) {
|
|||||||
|
|
||||||
if (entity.fake) {
|
if (entity.fake) {
|
||||||
(entity as Pony).palettePonyInfo = decodePonyInfo(ponyInfo, mockPaletteManager);
|
(entity as Pony).palettePonyInfo = decodePonyInfo(ponyInfo, mockPaletteManager);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
updatePonyInfoWithPoof(game, entity, ponyInfo, crc);
|
updatePonyInfoWithPoof(game, entity, ponyInfo, crc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -173,7 +175,8 @@ export function handleUpdateEntity(game: PonyTownGame, update: DecodedUpdate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
applyIfSelected(game, id);
|
applyIfSelected(game, id);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log(`handleUpdateEntity: missing entity: ${id}`);
|
log(`handleUpdateEntity: missing entity: ${id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,7 +318,8 @@ export function handleUpdates(game: PonyTownGame, updates: Uint8Array) {
|
|||||||
|
|
||||||
if (region) {
|
if (region) {
|
||||||
handleAddEntity(game, region, update, false);
|
handleAddEntity(game, region, update, false);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log(`handleUpdates (add): missing region at ${x} ${y}`);
|
log(`handleUpdates (add): missing region at ${x} ${y}`);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -353,7 +357,8 @@ export function updatePonyInfoWithPoof(game: PonyTownGame, entity: Entity, info:
|
|||||||
if (entity && isPony(entity)) {
|
if (entity && isPony(entity)) {
|
||||||
if (isHidden(entity)) {
|
if (isHidden(entity)) {
|
||||||
update(entity);
|
update(entity);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
playEffect(game, entity, poof2.type);
|
playEffect(game, entity, poof2.type);
|
||||||
setTimeout(() => update(entity), 100);
|
setTimeout(() => update(entity), 100);
|
||||||
}
|
}
|
||||||
@@ -365,7 +370,8 @@ export function handleRemoveEntity(game: PonyTownGame, id: number) {
|
|||||||
|
|
||||||
if (entity) {
|
if (entity) {
|
||||||
removeEntity(game.map, entity);
|
removeEntity(game.map, entity);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log(`handleRemoveEntity: Missing entity: ${id}`);
|
log(`handleRemoveEntity: Missing entity: ${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,21 +447,26 @@ export function handleAction(game: PonyTownGame, id: number, action: Action) {
|
|||||||
default:
|
default:
|
||||||
log(`handleAction: Invalid action: ${action}`);
|
log(`handleAction: Invalid action: ${action}`);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log(`handleAction: Missing entity: ${id}`);
|
log(`handleAction: Missing entity: ${id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function playEffect(game: PonyTownGame, target: Entity, type: number) {
|
export function playEffect(game: PonyTownGame, target: Entity, type: number) {
|
||||||
if (isHidden(target))
|
if (isHidden(target)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const entity = createAnEntity(type, 0, target.x, target.y, {}, game.paletteManager, game);
|
const entity = createAnEntity(type, 0, target.x, target.y, {}, game.paletteManager, game);
|
||||||
addEntity(game.map, entity);
|
addEntity(game.map, entity);
|
||||||
setTimeout(() => removeEntityDirectly(game.map, entity), 1000);
|
setTimeout(() => removeEntityDirectly(game.map, entity), 1000);
|
||||||
} catch (e) {
|
}
|
||||||
DEVELOPMENT && console.error(e);
|
catch (e) {
|
||||||
|
if (DEVELOPMENT) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,7 +565,8 @@ export function containsFilteredWords(message: string, filter: string | undefine
|
|||||||
if (filter) {
|
if (filter) {
|
||||||
const words = compact(filter.replace(/[,]/g, ' ').split(/[\r\n\t ]+/g).map(x => x.trim()));
|
const words = compact(filter.replace(/[,]/g, ' ').split(/[\r\n\t ]+/g).map(x => x.trim()));
|
||||||
cachedRegex = new RegExp(`(^| )(${words.map(escapeRegExp).join('|')})($| )`, 'i');
|
cachedRegex = new RegExp(`(^| )(${words.map(escapeRegExp).join('|')})($| )`, 'i');
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
cachedRegex = undefined;
|
cachedRegex = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,8 +581,11 @@ export function handleSays(game: PonyTownGame, id: number, message: string, type
|
|||||||
|
|
||||||
if (entity) {
|
if (entity) {
|
||||||
handleSay(game, entity, message, type);
|
handleSay(game, entity, message, type);
|
||||||
} else {
|
}
|
||||||
DEVELOPMENT && console.warn('incomplete say');
|
else {
|
||||||
|
if (DEVELOPMENT) {
|
||||||
|
console.warn('incomplete say');
|
||||||
|
}
|
||||||
game.incompleteSays.push({ id, message, type, time: Date.now() });
|
game.incompleteSays.push({ id, message, type, time: Date.now() });
|
||||||
game.send(server => server.actionParam2(Action.RequestEntityInfo, id));
|
game.send(server => server.actionParam2(Action.RequestEntityInfo, id));
|
||||||
}
|
}
|
||||||
@@ -589,32 +604,41 @@ function isFriendEntityId(game: PonyTownGame, id: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function shouldShowChatMessage(game: PonyTownGame, entity: Entity | FakeEntity, message: string, type: MessageType): boolean {
|
function shouldShowChatMessage(game: PonyTownGame, entity: Entity | FakeEntity, message: string, type: MessageType): boolean {
|
||||||
if (entity === game.player)
|
if (entity === game.player) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (isWhisperTo(type))
|
if (isWhisperTo(type)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (isWhisper(type) && isFriendEntityId(game, entity.id))
|
if (isWhisper(type) && isFriendEntityId(game, entity.id)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (isPublicMessage(type) && !entity.fake && !isChatVisible(game.camera, entity))
|
if (isPublicMessage(type) && !entity.fake && !isChatVisible(game.camera, entity)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (isNonIgnorableMessage(type))
|
if (isNonIgnorableMessage(type)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (game.settings.account.filterCyrillic && containsCyrillic(message))
|
if (game.settings.account.filterCyrillic && containsCyrillic(message)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (game.settings.account.ignorePublicChat && isPublicMessage(type))
|
if (game.settings.account.ignorePublicChat && isPublicMessage(type)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (isWhisper(type) && game.settings.account.ignoreNonFriendWhispers)
|
if (isWhisper(type) && game.settings.account.ignoreNonFriendWhispers) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (containsFilteredWords(message, game.settings.account.filterWords))
|
if (containsFilteredWords(message, game.settings.account.filterWords)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -624,30 +648,36 @@ function isChatInRange(entity: Entity, player: Entity | undefined, range: number
|
|||||||
}
|
}
|
||||||
|
|
||||||
function shouldShowChatMessageInChatlog(game: PonyTownGame, entity: Entity | FakeEntity, type: MessageType) {
|
function shouldShowChatMessageInChatlog(game: PonyTownGame, entity: Entity | FakeEntity, type: MessageType) {
|
||||||
if (entity.type !== PONY_TYPE)
|
if (entity.type !== PONY_TYPE) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (entity.fake)
|
if (entity.fake) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isPublicMessage(type))
|
if (!isPublicMessage(type)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isChatInRange(entity, game.player, game.settings.account.chatlogRange))
|
if (!isChatInRange(entity, game.player, game.settings.account.chatlogRange)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function handleSay(game: PonyTownGame, entity: Entity | FakeEntity, message: string, type: MessageType) {
|
export function handleSay(game: PonyTownGame, entity: Entity | FakeEntity, message: string, type: MessageType) {
|
||||||
if (!shouldShowChatMessage(game, entity, message, type))
|
if (!shouldShowChatMessage(game, entity, message, type)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (type === MessageType.Dismiss || message === '.') {
|
if (type === MessageType.Dismiss || message === '.') {
|
||||||
if (!entity.fake && entity.says) {
|
if (!entity.fake && entity.says) {
|
||||||
dismissSays(entity.says);
|
dismissSays(entity.says);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const bubbleEntity = isWhisperTo(type) ? game.player : entity;
|
const bubbleEntity = isWhisperTo(type) ? game.player : entity;
|
||||||
|
|
||||||
if (bubbleEntity && !bubbleEntity.fake && game.map.entitiesById.has(bubbleEntity.id)) {
|
if (bubbleEntity && !bubbleEntity.fake && game.map.entitiesById.has(bubbleEntity.id)) {
|
||||||
@@ -677,7 +707,8 @@ export function handleEntityInfo(game: PonyTownGame, id: number, name: string, c
|
|||||||
game.incompleteSays.splice(i, 1);
|
game.incompleteSays.splice(i, 1);
|
||||||
const entity: FakeEntity = { fake: true, type: PONY_TYPE, id, name, crc };
|
const entity: FakeEntity = { fake: true, type: PONY_TYPE, id, name, crc };
|
||||||
handleSay(game, entity, say.message, say.type);
|
handleSay(game, entity, say.message, say.type);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -697,9 +728,11 @@ export function subscribeRegion(game: PonyTownGame, data: Uint8Array) {
|
|||||||
export function filterEntityName({ settings, worldFlags }: PonyTownGame, name: string | undefined, nameBad: boolean) {
|
export function filterEntityName({ settings, worldFlags }: PonyTownGame, name: string | undefined, nameBad: boolean) {
|
||||||
if (name && nameBad && (settings.account.filterSwearWords || hasFlag(worldFlags, WorldStateFlags.Safe))) {
|
if (name && nameBad && (settings.account.filterSwearWords || hasFlag(worldFlags, WorldStateFlags.Safe))) {
|
||||||
return repeat('*', name.length);
|
return repeat('*', name.length);
|
||||||
} else if (name && containsFilteredWords(name, settings.account.filterWords)) {
|
}
|
||||||
|
else if (name && containsFilteredWords(name, settings.account.filterWords)) {
|
||||||
return repeat('?', name.length);
|
return repeat('?', name.length);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -722,7 +755,8 @@ function createEntityOrPony(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const entity = createAnEntity(type, id, x, y, options, game.paletteManager, game);
|
const entity = createAnEntity(type, id, x, y, options, game.paletteManager, game);
|
||||||
|
|
||||||
entity.state = state;
|
entity.state = state;
|
||||||
@@ -744,8 +778,9 @@ function updateEntityOptionsInternal(entity: Entity, options: Partial<EntityOrPo
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handleUpdateFriends(game: PonyTownGame, friends: FriendStatusData[], removeMissing: boolean) {
|
export function handleUpdateFriends(game: PonyTownGame, friends: FriendStatusData[], removeMissing: boolean) {
|
||||||
if (!game.model.friends)
|
if (!game.model.friends) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (const { accountId, accountName, status, entityId, name, info, crc, nameBad = false } of friends) {
|
for (const { accountId, accountName, status, entityId, name, info, crc, nameBad = false } of friends) {
|
||||||
let friend = game.model.friends.find(f => f.accountId === accountId);
|
let friend = game.model.friends.find(f => f.accountId === accountId);
|
||||||
@@ -754,7 +789,8 @@ export function handleUpdateFriends(game: PonyTownGame, friends: FriendStatusDat
|
|||||||
if (friend) {
|
if (friend) {
|
||||||
removeItem(game.model.friends, friend);
|
removeItem(game.model.friends, friend);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (!friend) {
|
if (!friend) {
|
||||||
friend = {
|
friend = {
|
||||||
accountId,
|
accountId,
|
||||||
@@ -817,7 +853,9 @@ export function handleUpdateFriends(game: PonyTownGame, friends: FriendStatusDat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEVELOPMENT && console.log('Refreshing friend list');
|
if (DEVELOPMENT) {
|
||||||
|
console.log('Refreshing friend list');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
game.model.friends.sort(compareFriends);
|
game.model.friends.sort(compareFriends);
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ export function createHtmlNodes(value: string | undefined, scale: number): Node[
|
|||||||
});
|
});
|
||||||
|
|
||||||
return img;
|
return img;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return document.createTextNode(x);
|
return document.createTextNode(x);
|
||||||
}
|
}
|
||||||
}) : [];
|
}) : [];
|
||||||
@@ -88,7 +89,9 @@ export function removeFirstChild(element: HTMLElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function removeElement(element: HTMLElement) {
|
export function removeElement(element: HTMLElement) {
|
||||||
element.parentElement && element.parentElement.removeChild(element);
|
if (element.parentElement) {
|
||||||
|
element.parentElement.removeChild(element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function replaceNodes(element: HTMLElement, text: string) {
|
export function replaceNodes(element: HTMLElement, text: string) {
|
||||||
@@ -105,7 +108,8 @@ export function replaceNodes(element: HTMLElement, text: string) {
|
|||||||
if (hasEmojis(text)) {
|
if (hasEmojis(text)) {
|
||||||
firstChild.nodeValue = '';
|
firstChild.nodeValue = '';
|
||||||
appendAllNodes(element, createHtmlNodes(text, 2));
|
appendAllNodes(element, createHtmlNodes(text, 2));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
firstChild.nodeValue = text;
|
firstChild.nodeValue = text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ function button({ mapping, gamepad }: GamepadInstance, name: GamepadButtons) {
|
|||||||
if (button.axis !== undefined) {
|
if (button.axis !== undefined) {
|
||||||
if (button.direction < 0) {
|
if (button.direction < 0) {
|
||||||
return gamepad.axes[button.axis] < -0.75;
|
return gamepad.axes[button.axis] < -0.75;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return gamepad.axes[button.axis] > 0.75;
|
return gamepad.axes[button.axis] > 0.75;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,8 +85,9 @@ export class GamePadController implements InputController {
|
|||||||
window.removeEventListener('gamepaddisconnected', this.gamepaddisconnected);
|
window.removeEventListener('gamepaddisconnected', this.gamepaddisconnected);
|
||||||
}
|
}
|
||||||
update() {
|
update() {
|
||||||
if (this.manager.disabledGamepad || !isFocused() || this.gamepadIndex === -1)
|
if (this.manager.disabledGamepad || !isFocused() || this.gamepadIndex === -1) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const gamepads = navigator.getGamepads();
|
const gamepads = navigator.getGamepads();
|
||||||
const gamepad = gamepads[this.gamepadIndex];
|
const gamepad = gamepads[this.gamepadIndex];
|
||||||
@@ -150,7 +152,8 @@ function readAxis(manager: InputManager, keyX: Key, keyY: Key, axisX: number, ax
|
|||||||
manager.setValue(keyX, Math.cos(theta) * scaledDist);
|
manager.setValue(keyX, Math.cos(theta) * scaledDist);
|
||||||
manager.setValue(keyY, Math.sin(theta) * scaledDist);
|
manager.setValue(keyY, Math.sin(theta) * scaledDist);
|
||||||
return false;
|
return false;
|
||||||
} else if (!zeroed) {
|
}
|
||||||
|
else if (!zeroed) {
|
||||||
manager.setValue(keyX, 0);
|
manager.setValue(keyX, 0);
|
||||||
manager.setValue(keyY, 0);
|
manager.setValue(keyY, 0);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -146,7 +146,8 @@ export class InputManager {
|
|||||||
setValue(input: Key, value: number): boolean {
|
setValue(input: Key, value: number): boolean {
|
||||||
if (input < 0 || input >= KEYS) {
|
if (input < 0 || input >= KEYS) {
|
||||||
console.warn(`Input out of range: ${input}`);
|
console.warn(`Input out of range: ${input}`);
|
||||||
} else if (this.state[input] !== value) {
|
}
|
||||||
|
else if (this.state[input] !== value) {
|
||||||
this.state[input] = value;
|
this.state[input] = value;
|
||||||
|
|
||||||
if (this.actions[input] && this.actions[input].length) {
|
if (this.actions[input] && this.actions[input].length) {
|
||||||
@@ -163,7 +164,8 @@ export class InputManager {
|
|||||||
addValue(input: Key, value: number) {
|
addValue(input: Key, value: number) {
|
||||||
if (input < 0 || input >= KEYS) {
|
if (input < 0 || input >= KEYS) {
|
||||||
console.warn(`Input out of range: ${input}`);
|
console.warn(`Input out of range: ${input}`);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.state[input] += value;
|
this.state[input] += value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,12 @@ function allowKey(key: number) {
|
|||||||
|
|
||||||
function fixKeyCode(key: number) {
|
function fixKeyCode(key: number) {
|
||||||
if (firefox) {
|
if (firefox) {
|
||||||
if (key === 173) return Key.DASH;
|
if (key === 173) {
|
||||||
if (key === 61) return Key.EQUALS;
|
return Key.DASH;
|
||||||
|
}
|
||||||
|
if (key === 61) {
|
||||||
|
return Key.EQUALS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
|
|||||||
@@ -122,13 +122,16 @@ export class TouchController implements InputController {
|
|||||||
this.touchIsDrag = true;
|
this.touchIsDrag = true;
|
||||||
this.manager.setValue(Key.GAMEPAD_AXIS1_X, -Math.cos(theta) * scaledDist);
|
this.manager.setValue(Key.GAMEPAD_AXIS1_X, -Math.cos(theta) * scaledDist);
|
||||||
this.manager.setValue(Key.GAMEPAD_AXIS1_Y, -Math.sin(theta) * scaledDist);
|
this.manager.setValue(Key.GAMEPAD_AXIS1_Y, -Math.sin(theta) * scaledDist);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.manager.setValue(Key.GAMEPAD_AXIS1_X, 0);
|
this.manager.setValue(Key.GAMEPAD_AXIS1_X, 0);
|
||||||
this.manager.setValue(Key.GAMEPAD_AXIS1_Y, 0);
|
this.manager.setValue(Key.GAMEPAD_AXIS1_Y, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private touchstart = (e: any) => {
|
private touchstart = (e: any) => {
|
||||||
e.cancellable && e.preventDefault();
|
if (e.cancellable) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
this.manager.usingTouch = true;
|
this.manager.usingTouch = true;
|
||||||
@@ -144,7 +147,8 @@ export class TouchController implements InputController {
|
|||||||
this.manager.setValue(Key.MOUSE_Y, this.touchStart.y);
|
this.manager.setValue(Key.MOUSE_Y, this.touchStart.y);
|
||||||
this.manager.setValue(Key.TOUCH, 1);
|
this.manager.setValue(Key.TOUCH, 1);
|
||||||
}
|
}
|
||||||
} else if (this.touch2Id === -1) {
|
}
|
||||||
|
else if (this.touch2Id === -1) {
|
||||||
const touch = e.changedTouches.item(0);
|
const touch = e.changedTouches.item(0);
|
||||||
|
|
||||||
if (touch) {
|
if (touch) {
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import { PonyTownGame } from './game';
|
|||||||
export function updateParty(current: PartyInfo | undefined, info: PartyMember[] | undefined): PartyInfo | undefined {
|
export function updateParty(current: PartyInfo | undefined, info: PartyMember[] | undefined): PartyInfo | undefined {
|
||||||
if (!info || !info.length) {
|
if (!info || !info.length) {
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const party = current || {
|
const party = current || {
|
||||||
leaderId: 0,
|
leaderId: 0,
|
||||||
members: [],
|
members: [],
|
||||||
@@ -18,7 +19,8 @@ export function updateParty(current: PartyInfo | undefined, info: PartyMember[]
|
|||||||
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
Object.assign(existing, m);
|
Object.assign(existing, m);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
party.members.push(m);
|
party.members.push(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ export function handleActionCommand(message: string, game: PonyTownGame): boolea
|
|||||||
if (player) {
|
if (player) {
|
||||||
if (isPonyLying(player)) {
|
if (isPonyLying(player)) {
|
||||||
sitAction(player, game);
|
sitAction(player, game);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
lieAction(player, game);
|
lieAction(player, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +47,8 @@ export function handleActionCommand(message: string, game: PonyTownGame): boolea
|
|||||||
if (player) {
|
if (player) {
|
||||||
if (isPonyFlying(player)) {
|
if (isPonyFlying(player)) {
|
||||||
standAction(player, game);
|
standAction(player, game);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
sitAction(player, game);
|
sitAction(player, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,7 +62,8 @@ export function handleActionCommand(message: string, game: PonyTownGame): boolea
|
|||||||
if (player) {
|
if (player) {
|
||||||
if (isPonyFlying(player)) {
|
if (isPonyFlying(player)) {
|
||||||
standAction(player, game);
|
standAction(player, game);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
flyAction(player, game);
|
flyAction(player, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,9 +80,11 @@ export function upAction(game: PonyTownGame) {
|
|||||||
if (player) {
|
if (player) {
|
||||||
if (isPonyLying(player)) {
|
if (isPonyLying(player)) {
|
||||||
sitAction(player, game);
|
sitAction(player, game);
|
||||||
} else if (isPonySitting(player)) {
|
}
|
||||||
|
else if (isPonySitting(player)) {
|
||||||
standAction(player, game);
|
standAction(player, game);
|
||||||
} else if (isPonyStanding(player)) {
|
}
|
||||||
|
else if (isPonyStanding(player)) {
|
||||||
flyAction(player, game);
|
flyAction(player, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,9 +96,11 @@ export function downAction(game: PonyTownGame) {
|
|||||||
if (player) {
|
if (player) {
|
||||||
if (isPonySitting(player)) {
|
if (isPonySitting(player)) {
|
||||||
lieAction(player, game);
|
lieAction(player, game);
|
||||||
} else if (isPonyStanding(player)) {
|
}
|
||||||
|
else if (isPonyStanding(player)) {
|
||||||
sitAction(player, game);
|
sitAction(player, game);
|
||||||
} else if (isPonyFlying(player)) {
|
}
|
||||||
|
else if (isPonyFlying(player)) {
|
||||||
standAction(player, game);
|
standAction(player, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,11 +179,14 @@ export function interact(game: PonyTownGame, shift: boolean) {
|
|||||||
|
|
||||||
if (entity && entityInRange(entity, player)) {
|
if (entity && entityInRange(entity, player)) {
|
||||||
game.send(server => server.interact(entity.id));
|
game.send(server => server.interact(entity.id));
|
||||||
} else if (player.hold === hammer.type) {
|
}
|
||||||
|
else if (player.hold === hammer.type) {
|
||||||
game.changePlaceEntity(shift);
|
game.changePlaceEntity(shift);
|
||||||
} else if (player.hold === shovel.type) {
|
}
|
||||||
|
else if (player.hold === shovel.type) {
|
||||||
game.changePlaceTile(shift);
|
game.changePlaceTile(shift);
|
||||||
} else if (player.ponyState.holding && hasFlag(player.ponyState.holding.flags, EntityFlags.Usable)) {
|
}
|
||||||
|
else if (player.ponyState.holding && hasFlag(player.ponyState.holding.flags, EntityFlags.Usable)) {
|
||||||
game.send(server => server.use());
|
game.send(server => server.use());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -191,13 +201,16 @@ export function toggleWall(game: PonyTownGame, hover: Point) {
|
|||||||
if (dx > dy) {
|
if (dx > dy) {
|
||||||
if ((dx + dy) < 1) {
|
if ((dx + dy) < 1) {
|
||||||
game.send(server => server.changeTile(x, y, TileType.WallH));
|
game.send(server => server.changeTile(x, y, TileType.WallH));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
game.send(server => server.changeTile(x + 1, y, TileType.WallV));
|
game.send(server => server.changeTile(x + 1, y, TileType.WallV));
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if ((dx + dy) < 1) {
|
if ((dx + dy) < 1) {
|
||||||
game.send(server => server.changeTile(x, y, TileType.WallV));
|
game.send(server => server.changeTile(x, y, TileType.WallV));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
game.send(server => server.changeTile(x, y + 1, TileType.WallH));
|
game.send(server => server.changeTile(x, y + 1, TileType.WallH));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,8 +222,11 @@ export function editorSelectEntities(game: PonyTownGame, hover: Point, shift: bo
|
|||||||
|
|
||||||
if (shift) {
|
if (shift) {
|
||||||
const entity = entities.filter(e => !includes(game.editor.selectedEntities, e))[0];
|
const entity = entities.filter(e => !includes(game.editor.selectedEntities, e))[0];
|
||||||
entity && game.editor.selectedEntities.push(entity);
|
if (entity) {
|
||||||
} else {
|
game.editor.selectedEntities.push(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
const index = entities.findIndex(e => includes(game.editor.selectedEntities, e));
|
const index = entities.findIndex(e => includes(game.editor.selectedEntities, e));
|
||||||
const entity = entities[(index + 1) % entities.length];
|
const entity = entities[(index + 1) % entities.length];
|
||||||
game.editor.selectedEntities = entity ? [entity] : [];
|
game.editor.selectedEntities = entity ? [entity] : [];
|
||||||
@@ -227,7 +243,8 @@ export function editorDragEntities(game: PonyTownGame, hover: Point, buttonPress
|
|||||||
e.x = roundPositionX(e.draggingStart!.x + dx);
|
e.x = roundPositionX(e.draggingStart!.x + dx);
|
||||||
e.y = roundPositionY(e.draggingStart!.y + dy);
|
e.y = roundPositionY(e.draggingStart!.y + dy);
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
game.apply(() => game.editor.draggingEntities = false);
|
game.apply(() => game.editor.draggingEntities = false);
|
||||||
game.send(server => server.editorAction({
|
game.send(server => server.editorAction({
|
||||||
type: 'move',
|
type: 'move',
|
||||||
|
|||||||
@@ -5,29 +5,34 @@ try {
|
|||||||
if (!('performance' in window && 'now' in performance)) {
|
if (!('performance' in window && 'now' in performance)) {
|
||||||
(window as any).performance = Date;
|
(window as any).performance = Date;
|
||||||
}
|
}
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!('getGamepads' in navigator)) {
|
if (!('getGamepads' in navigator)) {
|
||||||
(window.navigator as any).getGamepads = () => [];
|
(window.navigator as any).getGamepads = () => [];
|
||||||
}
|
}
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!('requestAnimationFrame' in window)) {
|
if (!('requestAnimationFrame' in window)) {
|
||||||
(window as any).requestAnimationFrame = (callback: any) => setTimeout(() => callback(performance.now()), 1000 / 60) as any;
|
(window as any).requestAnimationFrame = (callback: any) => setTimeout(() => callback(performance.now()), 1000 / 60) as any;
|
||||||
}
|
}
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!('cancelAnimationFrame' in window)) {
|
if (!('cancelAnimationFrame' in window)) {
|
||||||
(window as any).cancelAnimationFrame = clearTimeout;
|
(window as any).cancelAnimationFrame = clearTimeout;
|
||||||
}
|
}
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
// IE <= 10
|
// IE <= 10
|
||||||
try {
|
try {
|
||||||
if (!('devicePixelRatio' in window)) {
|
if (!('devicePixelRatio' in window)) {
|
||||||
(window as any).devicePixelRatio = 1;
|
(window as any).devicePixelRatio = 1;
|
||||||
}
|
}
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
|
|||||||
+42
-20
@@ -162,7 +162,9 @@ export function updatePonyInfo(pony: Pony, info: string | Uint8Array, apply: ()
|
|||||||
pony.discardBatch = true;
|
pony.discardBatch = true;
|
||||||
|
|
||||||
if (isPonyFlying(pony) && !canPonyFly(pony)) {
|
if (isPonyFlying(pony) && !canPonyFly(pony)) {
|
||||||
DEVELOPMENT && console.warn('Force land');
|
if (DEVELOPMENT) {
|
||||||
|
console.warn('Force land');
|
||||||
|
}
|
||||||
pony.state = setFlag(pony.state, EntityState.PonyFlying, false);
|
pony.state = setFlag(pony.state, EntityState.PonyFlying, false);
|
||||||
resetAnimatorState(pony.animator);
|
resetAnimatorState(pony.animator);
|
||||||
}
|
}
|
||||||
@@ -201,7 +203,8 @@ export function doBoopPonyAction(game: PonyTownGame, pony: Pony) {
|
|||||||
if (pony.swimming && pony.lastBoopSplash < performance.now()) {
|
if (pony.swimming && pony.lastBoopSplash < performance.now()) {
|
||||||
if (isFacingRight(pony)) {
|
if (isFacingRight(pony)) {
|
||||||
playEffect(game, pony, boopSplashRight.type);
|
playEffect(game, pony, boopSplashRight.type);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
playEffect(game, pony, boopSplashLeft.type);
|
playEffect(game, pony, boopSplashLeft.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,13 +245,15 @@ export function drawPonyEntity(batch: PaletteSpriteBatch, pony: Pony, drawOption
|
|||||||
if (pony.batch !== undefined) {
|
if (pony.batch !== undefined) {
|
||||||
batch.patchBatchDepth(pony.batch);
|
batch.patchBatchDepth(pony.batch);
|
||||||
batch.drawBatch(pony.batch);
|
batch.drawBatch(pony.batch);
|
||||||
} else if (pony.palettePonyInfo !== undefined) {
|
}
|
||||||
|
else if (pony.palettePonyInfo !== undefined) {
|
||||||
let swimming = false;
|
let swimming = false;
|
||||||
|
|
||||||
if (isSwimmingState(pony.animator.state)) {
|
if (isSwimmingState(pony.animator.state)) {
|
||||||
if (pony.animator.state === swimmingToFlying) {
|
if (pony.animator.state === swimmingToFlying) {
|
||||||
swimming = pony.animator.time < 0.4;
|
swimming = pony.animator.time < 0.4;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
swimming = true;
|
swimming = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,7 +299,9 @@ export function drawPonyEntity(batch: PaletteSpriteBatch, pony: Pony, drawOption
|
|||||||
if (pony.magicEffect.currentAnimation !== undefined) {
|
if (pony.magicEffect.currentAnimation !== undefined) {
|
||||||
drawAnimation(batch, pony.magicEffect, 0, 0, pony.magicColor, flip);
|
drawAnimation(batch, pony.magicEffect, 0, 0, pony.magicColor, flip);
|
||||||
const sprite = sprites.magic3.frames[pony.magicEffect.frame];
|
const sprite = sprites.magic3.frames[pony.magicEffect.frame];
|
||||||
sprite && batch.drawSprite(sprite, WHITE, pony.heartsEffect.palette, 0, 0);
|
if (sprite) {
|
||||||
|
batch.drawSprite(sprite, WHITE, pony.heartsEffect.palette, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,13 +391,16 @@ export function flagsToState(state: EntityState, moving: boolean, isSwimming: bo
|
|||||||
|
|
||||||
if (isSwimming) {
|
if (isSwimming) {
|
||||||
return swimming;
|
return swimming;
|
||||||
} else if (moving) {
|
}
|
||||||
|
else if (moving) {
|
||||||
if (ponyState === EntityState.PonyFlying) {
|
if (ponyState === EntityState.PonyFlying) {
|
||||||
return flying;
|
return flying;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return trotting;
|
return trotting;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
switch (ponyState) {
|
switch (ponyState) {
|
||||||
case EntityState.PonyStanding: return standing;
|
case EntityState.PonyStanding: return standing;
|
||||||
case EntityState.PonyWalking: return trotting;
|
case EntityState.PonyWalking: return trotting;
|
||||||
@@ -435,7 +445,8 @@ export function updatePonyEntity(pony: Pony, delta: number, gameTime: number, sa
|
|||||||
}
|
}
|
||||||
|
|
||||||
pony.doAction = DoAction.None;
|
pony.doAction = DoAction.None;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
setAnimatorState(pony.animator, animationState);
|
setAnimatorState(pony.animator, animationState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,7 +459,8 @@ export function updatePonyEntity(pony: Pony, delta: number, gameTime: number, sa
|
|||||||
if (frame >= pony.headAnimation.frames.length && !pony.headAnimation.loop) {
|
if (frame >= pony.headAnimation.frames.length && !pony.headAnimation.loop) {
|
||||||
pony.headAnimation = undefined;
|
pony.headAnimation = undefined;
|
||||||
state.headAnimationFrame = 0;
|
state.headAnimationFrame = 0;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
state.headAnimationFrame = frame % pony.headAnimation.frames.length;
|
state.headAnimationFrame = frame % pony.headAnimation.frames.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -468,7 +480,8 @@ export function updatePonyEntity(pony: Pony, delta: number, gameTime: number, sa
|
|||||||
|
|
||||||
if ((pony.state & EntityState.Magic) !== 0) {
|
if ((pony.state & EntityState.Magic) !== 0) {
|
||||||
playAnimation(pony.magicEffect, magicAnimation);
|
playAnimation(pony.magicEffect, magicAnimation);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
playAnimation(pony.magicEffect, undefined);
|
playAnimation(pony.magicEffect, undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,11 +559,13 @@ export function updatePonyHold(pony: Pony, game: PonyTownGame) {
|
|||||||
if (pony.hold !== 0) {
|
if (pony.hold !== 0) {
|
||||||
if (ponyState.holding === undefined) {
|
if (ponyState.holding === undefined) {
|
||||||
ponyState.holding = createAnEntity(pony.hold, 0, 0, 0, {}, pony.paletteManager, game);
|
ponyState.holding = createAnEntity(pony.hold, 0, 0, 0, {}, pony.paletteManager, game);
|
||||||
} else if (ponyState.holding.type !== pony.hold) {
|
}
|
||||||
|
else if (ponyState.holding.type !== pony.hold) {
|
||||||
releaseEntity(ponyState.holding);
|
releaseEntity(ponyState.holding);
|
||||||
ponyState.holding = createAnEntity(pony.hold, 0, 0, 0, {}, pony.paletteManager, game);
|
ponyState.holding = createAnEntity(pony.hold, 0, 0, 0, {}, pony.paletteManager, game);
|
||||||
}
|
}
|
||||||
} else if (ponyState.holding !== undefined) {
|
}
|
||||||
|
else if (ponyState.holding !== undefined) {
|
||||||
releaseEntity(ponyState.holding);
|
releaseEntity(ponyState.holding);
|
||||||
ponyState.holding = undefined;
|
ponyState.holding = undefined;
|
||||||
}
|
}
|
||||||
@@ -590,7 +605,8 @@ function filterExpression(expression: Expression) {
|
|||||||
|
|
||||||
if (expression.muzzle === Muzzle.SmilePant) {
|
if (expression.muzzle === Muzzle.SmilePant) {
|
||||||
expression.muzzle = Muzzle.SmileOpen;
|
expression.muzzle = Muzzle.SmileOpen;
|
||||||
} else if (expression.muzzle === Muzzle.NeutralPant) {
|
}
|
||||||
|
else if (expression.muzzle === Muzzle.NeutralPant) {
|
||||||
expression.muzzle = Muzzle.NeutralOpen2;
|
expression.muzzle = Muzzle.NeutralOpen2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -598,9 +614,11 @@ function filterExpression(expression: Expression) {
|
|||||||
if (blush) {
|
if (blush) {
|
||||||
if (expression.muzzle === Muzzle.SmileOpen2) {
|
if (expression.muzzle === Muzzle.SmileOpen2) {
|
||||||
expression.muzzle = Muzzle.SmileOpen;
|
expression.muzzle = Muzzle.SmileOpen;
|
||||||
} else if (expression.muzzle === Muzzle.FrownOpen) {
|
}
|
||||||
|
else if (expression.muzzle === Muzzle.FrownOpen) {
|
||||||
expression.muzzle = Muzzle.ConcernedOpen;
|
expression.muzzle = Muzzle.ConcernedOpen;
|
||||||
} else if (expression.muzzle === Muzzle.NeutralOpen2) {
|
}
|
||||||
|
else if (expression.muzzle === Muzzle.NeutralOpen2) {
|
||||||
expression.muzzle = Muzzle.Oh;
|
expression.muzzle = Muzzle.Oh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -619,21 +637,25 @@ function updatePonyExpression(pony: Pony, expr: number, safe: boolean) {
|
|||||||
|
|
||||||
if (hasFlag(extra, ExpressionExtra.Cry)) {
|
if (hasFlag(extra, ExpressionExtra.Cry)) {
|
||||||
playAnimation(pony.cryEffect, cryAnimation);
|
playAnimation(pony.cryEffect, cryAnimation);
|
||||||
} else if (hasFlag(extra, ExpressionExtra.Tears)) {
|
}
|
||||||
|
else if (hasFlag(extra, ExpressionExtra.Tears)) {
|
||||||
playAnimation(pony.cryEffect, tearsAnimation);
|
playAnimation(pony.cryEffect, tearsAnimation);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
playAnimation(pony.cryEffect, undefined);
|
playAnimation(pony.cryEffect, undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasFlag(extra, ExpressionExtra.Zzz)) {
|
if (hasFlag(extra, ExpressionExtra.Zzz)) {
|
||||||
playOneOfAnimations(pony.zzzEffect, zzzAnimations);
|
playOneOfAnimations(pony.zzzEffect, zzzAnimations);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
playAnimation(pony.zzzEffect, undefined);
|
playAnimation(pony.zzzEffect, undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasFlag(extra, ExpressionExtra.Hearts)) {
|
if (hasFlag(extra, ExpressionExtra.Hearts)) {
|
||||||
playAnimation(pony.heartsEffect, heartsAnimation);
|
playAnimation(pony.heartsEffect, heartsAnimation);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
playAnimation(pony.heartsEffect, undefined);
|
playAnimation(pony.heartsEffect, undefined);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-11
@@ -112,7 +112,8 @@ export function createHeadTransform(
|
|||||||
) {
|
) {
|
||||||
if (originalTransform !== undefined) {
|
if (originalTransform !== undefined) {
|
||||||
copyMat2D(headTransform, originalTransform);
|
copyMat2D(headTransform, originalTransform);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
identityMat2D(headTransform);
|
identityMat2D(headTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +141,8 @@ const hairOffsets = [
|
|||||||
function draw(options: Options, flag: NoDraw) {
|
function draw(options: Options, flag: NoDraw) {
|
||||||
if (TOOLS) {
|
if (TOOLS) {
|
||||||
return !hasFlag(options.no, flag);
|
return !hasFlag(options.no, flag);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,13 +276,17 @@ export function drawPony(batch: Batch, info: Info, state: State, ponyX: number,
|
|||||||
// selection
|
// selection
|
||||||
if (options.selected) {
|
if (options.selected) {
|
||||||
const sprite = at(sprites.ponySelections, shadow.frame);
|
const sprite = at(sprites.ponySelections, shadow.frame);
|
||||||
sprite && batch.drawSprite(sprite, WHITE, info.defaultPalette, shadowX, shadowY);
|
if (sprite) {
|
||||||
|
batch.drawSprite(sprite, WHITE, info.defaultPalette, shadowX, shadowY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// shadow
|
// shadow
|
||||||
if (options.shadow) {
|
if (options.shadow) {
|
||||||
const sprite = at(sprites.ponyShadows, shadow.frame);
|
const sprite = at(sprites.ponyShadows, shadow.frame);
|
||||||
sprite && batch.drawSprite(sprite, options.shadowColor, info.defaultPalette, shadowX, shadowY);
|
if (sprite) {
|
||||||
|
batch.drawSprite(sprite, options.shadowColor, info.defaultPalette, shadowX, shadowY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// head accessory
|
// head accessory
|
||||||
@@ -522,7 +528,8 @@ export function drawHead(
|
|||||||
|
|
||||||
if (toy !== undefined) {
|
if (toy !== undefined) {
|
||||||
drawSet(batch, sprites.extraAccessoriesBehind, toy, extraX, extraY, WHITE);
|
drawSet(batch, sprites.extraAccessoriesBehind, toy, extraX, extraY, WHITE);
|
||||||
} else if (options.extra && draw(options, NoDraw.Behind)) {
|
}
|
||||||
|
else if (options.extra && draw(options, NoDraw.Behind)) {
|
||||||
drawSet(batch, sprites.extraAccessoriesBehind, info.extraAccessory, extraX, extraY, WHITE);
|
drawSet(batch, sprites.extraAccessoriesBehind, info.extraAccessory, extraX, extraY, WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -615,7 +622,9 @@ export function drawHead(
|
|||||||
const noses = at(sprites.noses, muzzle);
|
const noses = at(sprites.noses, muzzle);
|
||||||
const nose = att(noses, info.nose && info.nose.type)![0];
|
const nose = att(noses, info.nose && info.nose.type)![0];
|
||||||
|
|
||||||
nose.mouth && batch.drawSprite(nose.mouth, WHITE, info.defaultPalette, x, y);
|
if (nose.mouth) {
|
||||||
|
batch.drawSprite(nose.mouth, WHITE, info.defaultPalette, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
if (holding !== undefined && holding.draw !== undefined) {
|
if (holding !== undefined && holding.draw !== undefined) {
|
||||||
holding.x = toWorldX(x + toInt(holding.pickableX));
|
holding.x = toWorldX(x + toInt(holding.pickableX));
|
||||||
@@ -647,7 +656,8 @@ export function drawHead(
|
|||||||
|
|
||||||
if (toy !== undefined) {
|
if (toy !== undefined) {
|
||||||
drawSet(batch, sprites.extraAccessories, toy, extraX, extraY, WHITE);
|
drawSet(batch, sprites.extraAccessories, toy, extraX, extraY, WHITE);
|
||||||
} else if (options.extra && draw(options, NoDraw.Front)) {
|
}
|
||||||
|
else if (options.extra && draw(options, NoDraw.Front)) {
|
||||||
drawSet(batch, sprites.extraAccessories, info.extraAccessory, extraX, extraY, WHITE);
|
drawSet(batch, sprites.extraAccessories, info.extraAccessory, extraX, extraY, WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -770,13 +780,21 @@ function drawEye(
|
|||||||
) {
|
) {
|
||||||
if (eye !== undefined) {
|
if (eye !== undefined) {
|
||||||
if (info.eyeshadow === true) {
|
if (info.eyeshadow === true) {
|
||||||
eye.shadow && batch.drawSprite(eye.shadow, WHITE, info.eyeshadowColor, x, y);
|
if (eye.shadow) {
|
||||||
eye.shine && batch.drawSprite(eye.shine, SHINES_COLOR, info.defaultPalette, x, y);
|
batch.drawSprite(eye.shadow, WHITE, info.eyeshadowColor, x, y);
|
||||||
|
}
|
||||||
|
if (eye.shine) {
|
||||||
|
batch.drawSprite(eye.shine, SHINES_COLOR, info.defaultPalette, x, y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eye.base && batch.drawSprite(eye.base, WHITE, eyePalette, x, y);
|
if (eye.base) {
|
||||||
|
batch.drawSprite(eye.base, WHITE, eyePalette, x, y);
|
||||||
|
}
|
||||||
const sprite = at(eye.irises, iris);
|
const sprite = at(eye.irises, iris);
|
||||||
sprite && batch.drawSprite(sprite, WHITE, palette, x, y);
|
if (sprite) {
|
||||||
|
batch.drawSprite(sprite, WHITE, palette, x, y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ import { REV } from '../generated/rev';
|
|||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
export function getUrl(name: string): string {
|
export function getUrl(name: string): string {
|
||||||
if (DEVELOPMENT)
|
if (DEVELOPMENT) {
|
||||||
return `/assets/${name}`;
|
return `/assets/${name}`;
|
||||||
|
}
|
||||||
|
|
||||||
if (!REV[name])
|
if (!REV[name]) {
|
||||||
throw new Error(`Cannot find file url (${name})`);
|
throw new Error(`Cannot find file url (${name})`);
|
||||||
|
}
|
||||||
|
|
||||||
return `/assets/${name.replace(/(\.\S+)$/, `-${REV[name]}$1`)}`;
|
return `/assets/${name.replace(/(\.\S+)$/, `-${REV[name]}$1`)}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ export function restorePlayerPosition() {
|
|||||||
if (currentPlayer.x !== setX || currentPlayer.y !== setY) {
|
if (currentPlayer.x !== setX || currentPlayer.y !== setY) {
|
||||||
currentPlayer.x = setX;
|
currentPlayer.x = setX;
|
||||||
currentPlayer.y = setY;
|
currentPlayer.y = setY;
|
||||||
DEVELOPMENT && console.warn('Restoring player position');
|
if (DEVELOPMENT) {
|
||||||
|
console.warn('Restoring player position');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,8 +68,11 @@ export function initWebGLResources(gl: WebGLRenderingContext, paletteManager: Pa
|
|||||||
try {
|
try {
|
||||||
createFrameBuffer(gl, frameBuffer, camera.w, camera.h, true, null);
|
createFrameBuffer(gl, frameBuffer, camera.w, camera.h, true, null);
|
||||||
createFrameBuffer(gl, frameBuffer2, camera.w, camera.h, false, frameBuffer.depthStencilRenderbuffer);
|
createFrameBuffer(gl, frameBuffer2, camera.w, camera.h, false, frameBuffer.depthStencilRenderbuffer);
|
||||||
} catch (e) {
|
}
|
||||||
DEVELOPMENT && console.warn(e);
|
catch (e) {
|
||||||
|
if (DEVELOPMENT) {
|
||||||
|
console.warn(e);
|
||||||
|
}
|
||||||
failedFBO = true;
|
failedFBO = true;
|
||||||
failedDepthBuffer = true;
|
failedDepthBuffer = true;
|
||||||
}
|
}
|
||||||
|
|||||||
+45
-20
@@ -105,7 +105,8 @@ function pickEntity(
|
|||||||
function pickByBounds(entity: Entity, rect: Rect, pickHidden: boolean): boolean {
|
function pickByBounds(entity: Entity, rect: Rect, pickHidden: boolean): boolean {
|
||||||
if ((entity.flags & EntityFlags.Interactive) === 0 || (isHidden(entity) && !pickHidden)) {
|
if ((entity.flags & EntityFlags.Interactive) === 0 || (isHidden(entity) && !pickHidden)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const bounds = entity.interactBounds || entity.bounds;
|
const bounds = entity.interactBounds || entity.bounds;
|
||||||
return !!bounds && boundsIntersect(entity.x, entity.y, bounds, 0, 0, rect);
|
return !!bounds && boundsIntersect(entity.x, entity.y, bounds, 0, 0, rect);
|
||||||
}
|
}
|
||||||
@@ -128,8 +129,9 @@ export function pickEntitiesByRect(map: WorldMap, rect: Rect, ignorePonies: bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function removeRegions(map: WorldMap, coords: number[]) {
|
export function removeRegions(map: WorldMap, coords: number[]) {
|
||||||
if (coords.length === 0)
|
if (coords.length === 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const entitiesToRemove = new Set<Entity>();
|
const entitiesToRemove = new Set<Entity>();
|
||||||
|
|
||||||
@@ -161,7 +163,9 @@ export function setRegion(map: WorldMap, x: number, y: number, region: Region) {
|
|||||||
const oldRegion = map.regions[index];
|
const oldRegion = map.regions[index];
|
||||||
|
|
||||||
if (oldRegion) {
|
if (oldRegion) {
|
||||||
DEVELOPMENT && !TESTS && console.error(`Region already set (${x}, ${y})`);
|
if (DEVELOPMENT && !TESTS) {
|
||||||
|
console.error(`Region already set (${x}, ${y})`);
|
||||||
|
}
|
||||||
|
|
||||||
for (const e of oldRegion.entities.slice()) {
|
for (const e of oldRegion.entities.slice()) {
|
||||||
releaseAndRemoveEntityFromMap(map, e);
|
releaseAndRemoveEntityFromMap(map, e);
|
||||||
@@ -172,8 +176,11 @@ export function setRegion(map: WorldMap, x: number, y: number, region: Region) {
|
|||||||
setTilesDirty(map, x * REGION_SIZE - 1, y * REGION_SIZE - 1, REGION_SIZE + 2, REGION_SIZE + 2);
|
setTilesDirty(map, x * REGION_SIZE - 1, y * REGION_SIZE - 1, REGION_SIZE + 2, REGION_SIZE + 2);
|
||||||
map.regions[index] = region;
|
map.regions[index] = region;
|
||||||
updateMinMaxRegion(map);
|
updateMinMaxRegion(map);
|
||||||
} else {
|
}
|
||||||
DEVELOPMENT && !TESTS && console.error(`Invalid region coords (${x}, ${y})`);
|
else {
|
||||||
|
if (DEVELOPMENT && !TESTS) {
|
||||||
|
console.error(`Invalid region coords (${x}, ${y})`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +193,8 @@ export function addEntity(map: WorldMap, entity: Entity) {
|
|||||||
|
|
||||||
if (!region) {
|
if (!region) {
|
||||||
throw new Error(`Missing region at ${entity.x} ${entity.y}`);
|
throw new Error(`Missing region at ${entity.x} ${entity.y}`);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
addEntityToMapRegion(map, region, entity);
|
addEntityToMapRegion(map, region, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,7 +217,8 @@ export function removeEntityDirectly(map: WorldMap, entity: Entity) {
|
|||||||
releaseEntity(entity);
|
releaseEntity(entity);
|
||||||
removeEntityFromEntities(map, entity);
|
removeEntityFromEntities(map, entity);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -286,9 +295,11 @@ export function addEntityToMapRegion(map: WorldMap, region: Region, entity: Enti
|
|||||||
const existing = map.entitiesById.get(entity.id);
|
const existing = map.entitiesById.get(entity.id);
|
||||||
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
DEVELOPMENT && !TESTS && console.error(`Adding duplicate entity ${entity.id} (` +
|
if (DEVELOPMENT && !TESTS) {
|
||||||
|
console.error(`Adding duplicate entity ${entity.id} (` +
|
||||||
`${worldToRegionX(existing.x, map)}, ${worldToRegionY(existing.y, map)} => ` +
|
`${worldToRegionX(existing.x, map)}, ${worldToRegionY(existing.y, map)} => ` +
|
||||||
`${worldToRegionX(entity.x, map)}, ${worldToRegionY(entity.y, map)})`);
|
`${worldToRegionX(entity.x, map)}, ${worldToRegionY(entity.y, map)})`);
|
||||||
|
}
|
||||||
|
|
||||||
removeEntity(map, existing);
|
removeEntity(map, existing);
|
||||||
}
|
}
|
||||||
@@ -419,7 +430,8 @@ export function updateEntitiesCoverLifted(map: WorldMap, player: Entity, hideObj
|
|||||||
|
|
||||||
if (e.coverLifted && lifting < 1) {
|
if (e.coverLifted && lifting < 1) {
|
||||||
e.coverLifting = Math.min(lifting + delta * 2, 1);
|
e.coverLifting = Math.min(lifting + delta * 2, 1);
|
||||||
} else if (!e.coverLifted && lifting > 0) {
|
}
|
||||||
|
else if (!e.coverLifted && lifting > 0) {
|
||||||
e.coverLifting = Math.max(lifting - delta * 2, 0);
|
e.coverLifting = Math.max(lifting - delta * 2, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -460,7 +472,9 @@ export function getMapHeightAt(map: WorldMap, x: number, y: number, gameTime: nu
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function updateEntities(game: PonyTownGame, gameTime: number, delta: number, safe: boolean) {
|
export function updateEntities(game: PonyTownGame, gameTime: number, delta: number, safe: boolean) {
|
||||||
TIMING && timeStart('updateEntities');
|
if (TIMING) {
|
||||||
|
timeStart('updateEntities');
|
||||||
|
}
|
||||||
|
|
||||||
const map = game.map;
|
const map = game.map;
|
||||||
|
|
||||||
@@ -475,7 +489,8 @@ export function updateEntities(game: PonyTownGame, gameTime: number, delta: numb
|
|||||||
const bobs = entity.bobs!;
|
const bobs = entity.bobs!;
|
||||||
const frame = (((gameTime / 1000) * entity.bobsFps!) | 0) % bobs.length;
|
const frame = (((gameTime / 1000) * entity.bobsFps!) | 0) % bobs.length;
|
||||||
entity.z = toWorldZ(bobs[frame]);
|
entity.z = toWorldZ(bobs[frame]);
|
||||||
} else if ((flags & EntityFlags.StaticY) === 0) {
|
}
|
||||||
|
else if ((flags & EntityFlags.StaticY) === 0) {
|
||||||
entity.z = getMapHeightAt(map, entity.x, entity.y, gameTime);
|
entity.z = getMapHeightAt(map, entity.x, entity.y, gameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,11 +504,13 @@ export function updateEntities(game: PonyTownGame, gameTime: number, delta: numb
|
|||||||
if (wasSwimming !== pony.swimming) {
|
if (wasSwimming !== pony.swimming) {
|
||||||
if (isFlyingDown(pony.animator.state)) {
|
if (isFlyingDown(pony.animator.state)) {
|
||||||
setTimeout(() => playEffect(game, pony, splash.type), 400);
|
setTimeout(() => playEffect(game, pony, splash.type), 400);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
playEffect(game, pony, splash.type);
|
playEffect(game, pony, splash.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (entity.update !== undefined) {
|
}
|
||||||
|
else if (entity.update !== undefined) {
|
||||||
entity.update(delta, gameTime);
|
entity.update(delta, gameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,7 +533,8 @@ export function updateEntities(game: PonyTownGame, gameTime: number, delta: numb
|
|||||||
if (Math.abs(entity.lightScale! - entity.lightTarget!) < move) {
|
if (Math.abs(entity.lightScale! - entity.lightTarget!) < move) {
|
||||||
entity.lightScale = entity.lightTarget;
|
entity.lightScale = entity.lightTarget;
|
||||||
entity.lightTarget = 1 - Math.random() * 0.15;
|
entity.lightTarget = 1 - Math.random() * 0.15;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
entity.lightScale! += entity.lightScale! < entity.lightTarget! ? move : -move;
|
entity.lightScale! += entity.lightScale! < entity.lightTarget! ? move : -move;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -538,7 +556,9 @@ export function updateEntities(game: PonyTownGame, gameTime: number, delta: numb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TIMING && timeEnd();
|
if (TIMING) {
|
||||||
|
timeEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function invalidatePalettes(entities: Entity[]) {
|
export function invalidatePalettes(entities: Entity[]) {
|
||||||
@@ -552,8 +572,9 @@ export function invalidatePalettes(entities: Entity[]) {
|
|||||||
export function ensureAllVisiblePoniesAreDecoded(map: WorldMap, camera: Camera, paletteManager: PaletteManager) {
|
export function ensureAllVisiblePoniesAreDecoded(map: WorldMap, camera: Camera, paletteManager: PaletteManager) {
|
||||||
const poniesToDecode = map.poniesToDecode;
|
const poniesToDecode = map.poniesToDecode;
|
||||||
|
|
||||||
if (!poniesToDecode.length)
|
if (!poniesToDecode.length) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const decode = new Set<number>();
|
const decode = new Set<number>();
|
||||||
|
|
||||||
@@ -565,8 +586,9 @@ export function ensureAllVisiblePoniesAreDecoded(map: WorldMap, camera: Camera,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!decode.size)
|
if (!decode.size) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (decode.size > 100) {
|
if (decode.size > 100) {
|
||||||
paletteManager.deduplicate = false;
|
paletteManager.deduplicate = false;
|
||||||
@@ -575,10 +597,12 @@ export function ensureAllVisiblePoniesAreDecoded(map: WorldMap, camera: Camera,
|
|||||||
map.poniesToDecode = poniesToDecode.filter((pony, i) => {
|
map.poniesToDecode = poniesToDecode.filter((pony, i) => {
|
||||||
if (pony.palettePonyInfo !== undefined) {
|
if (pony.palettePonyInfo !== undefined) {
|
||||||
return false;
|
return false;
|
||||||
} else if (decode.has(i)) {
|
}
|
||||||
|
else if (decode.has(i)) {
|
||||||
ensurePonyInfoDecoded(pony);
|
ensurePonyInfoDecoded(pony);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -595,7 +619,8 @@ export function switchEntityRegion(map: WorldMap, entity: Entity, x: number, y:
|
|||||||
|
|
||||||
if (region) {
|
if (region) {
|
||||||
addEntityToRegion(region, entity, map);
|
addEntityToRegion(region, entity, map);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
releaseAndRemoveEntityFromMap(map, entity);
|
releaseAndRemoveEntityFromMap(map, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,13 +41,17 @@ function meetsSupporterRequirement(account: AccountSupporter, require: string):
|
|||||||
|
|
||||||
if (require === 'inv') {
|
if (require === 'inv') {
|
||||||
return modOrDev || level >= 1 || !!account.supporterInvited;
|
return modOrDev || level >= 1 || !!account.supporterInvited;
|
||||||
} else if (require === 'sup1') {
|
}
|
||||||
|
else if (require === 'sup1') {
|
||||||
return modOrDev || level >= 1;
|
return modOrDev || level >= 1;
|
||||||
} else if (require === 'sup2') {
|
}
|
||||||
|
else if (require === 'sup2') {
|
||||||
return modOrDev || level >= 2;
|
return modOrDev || level >= 2;
|
||||||
} else if (require === 'sup3') {
|
}
|
||||||
|
else if (require === 'sup3') {
|
||||||
return modOrDev || level >= 3;
|
return modOrDev || level >= 3;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,7 +64,8 @@ export function getCharacterLimit(account: AccountSupporter) {
|
|||||||
default:
|
default:
|
||||||
if (hasFlag(account.flags, AccountDataFlags.PastSupporter)) {
|
if (hasFlag(account.flags, AccountDataFlags.PastSupporter)) {
|
||||||
return BASE_CHARACTER_LIMIT + ADDITIONAL_CHARACTERS_PAST_SUPPORTER;
|
return BASE_CHARACTER_LIMIT + ADDITIONAL_CHARACTERS_PAST_SUPPORTER;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return BASE_CHARACTER_LIMIT;
|
return BASE_CHARACTER_LIMIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,7 +74,8 @@ export function getCharacterLimit(account: AccountSupporter) {
|
|||||||
export function getSupporterInviteLimit(account: AccountSupporter) {
|
export function getSupporterInviteLimit(account: AccountSupporter) {
|
||||||
if (isMod(account) || isDev(account)) {
|
if (isMod(account) || isDev(account)) {
|
||||||
return 100;
|
return 100;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
switch (account.supporter) {
|
switch (account.supporter) {
|
||||||
case 1: return 1;
|
case 1: return 1;
|
||||||
case 2: return 5;
|
case 2: return 5;
|
||||||
|
|||||||
@@ -352,6 +352,7 @@ export const enum SupporterFlags {
|
|||||||
Supporter1 = 1,
|
Supporter1 = 1,
|
||||||
Supporter2 = 2,
|
Supporter2 = 2,
|
||||||
Supporter3 = 3,
|
Supporter3 = 3,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
|
||||||
SupporterMask = 0x0003,
|
SupporterMask = 0x0003,
|
||||||
IgnorePatreon = 0x0080,
|
IgnorePatreon = 0x0080,
|
||||||
PastSupporter = 0x0100,
|
PastSupporter = 0x0100,
|
||||||
@@ -489,11 +490,9 @@ export const eventFields: (keyof Event)[] = [
|
|||||||
|
|
||||||
// models
|
// models
|
||||||
|
|
||||||
export interface OriginInfo extends OriginInfoBase {
|
export type OriginInfo = OriginInfoBase;
|
||||||
}
|
|
||||||
|
|
||||||
export interface Timestamps extends TimestampsBase {
|
export type Timestamps = TimestampsBase;
|
||||||
}
|
|
||||||
|
|
||||||
export interface AccountStatus {
|
export interface AccountStatus {
|
||||||
online: boolean;
|
online: boolean;
|
||||||
|
|||||||
+54
-27
@@ -31,9 +31,11 @@ export function compareAuths(a: Auth, b: Auth) {
|
|||||||
|
|
||||||
if (aDeleted && !bDeleted) {
|
if (aDeleted && !bDeleted) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if (!aDeleted && bDeleted) {
|
}
|
||||||
|
else if (!aDeleted && bDeleted) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return compareByName(a, b);
|
return compareByName(a, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,7 +84,8 @@ export function filterAccounts(items: Account[], search: string, showOnly: strin
|
|||||||
if (filter) {
|
if (filter) {
|
||||||
if (not) {
|
if (not) {
|
||||||
items = items.filter(i => !filter(i));
|
items = items.filter(i => !filter(i));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
items = items.filter(filter);
|
items = items.filter(filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,20 +109,27 @@ export function createFilter(search: string): (account: Account) => boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function filter(account: Account): boolean {
|
function filter(account: Account): boolean {
|
||||||
if (account._id === search)
|
if (account._id === search) {
|
||||||
return true;
|
return true;
|
||||||
if (test(account.name))
|
}
|
||||||
|
if (test(account.name)) {
|
||||||
return true;
|
return true;
|
||||||
if (test(account.note))
|
}
|
||||||
|
if (test(account.note)) {
|
||||||
return true;
|
return true;
|
||||||
if (account.roles && account.roles.some(test))
|
}
|
||||||
|
if (account.roles && account.roles.some(test)) {
|
||||||
return true;
|
return true;
|
||||||
if (account.emails && account.emails.some(test))
|
}
|
||||||
|
if (account.emails && account.emails.some(test)) {
|
||||||
return true;
|
return true;
|
||||||
if (account.auths && account.auths.some(testAuth))
|
}
|
||||||
|
if (account.auths && account.auths.some(testAuth)) {
|
||||||
return true;
|
return true;
|
||||||
if (account.merges && account.merges.some(testMerge))
|
}
|
||||||
|
if (account.merges && account.merges.some(testMerge)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -165,8 +175,9 @@ export function createPotentialDuplicatesFilter(getAccountsByBrowserId: (id: str
|
|||||||
return i => {
|
return i => {
|
||||||
const name = i.nameLower;
|
const name = i.nameLower;
|
||||||
|
|
||||||
if (name === 'anonymous' || !i.lastBrowserId)
|
if (name === 'anonymous' || !i.lastBrowserId) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const accounts = getAccountsByBrowserId(i.lastBrowserId);
|
const accounts = getAccountsByBrowserId(i.lastBrowserId);
|
||||||
|
|
||||||
@@ -187,15 +198,20 @@ export function createFilter2(showOnly: string): ((account: Account) => boolean)
|
|||||||
|
|
||||||
if (showOnly === 'banned') {
|
if (showOnly === 'banned') {
|
||||||
return hasAnyBan;
|
return hasAnyBan;
|
||||||
} else if (showOnly === 'timed out') {
|
}
|
||||||
|
else if (showOnly === 'timed out') {
|
||||||
return i => !!((i.mute && i.mute > now) || (i.shadow && i.shadow > now) || (i.ban && i.ban > now));
|
return i => !!((i.mute && i.mute > now) || (i.shadow && i.shadow > now) || (i.ban && i.ban > now));
|
||||||
} else if (showOnly === 'with flags') {
|
}
|
||||||
|
else if (showOnly === 'with flags') {
|
||||||
return i => !!i.flags;
|
return i => !!i.flags;
|
||||||
} else if (showOnly === 'notes') {
|
}
|
||||||
|
else if (showOnly === 'notes') {
|
||||||
return i => !!i.note;
|
return i => !!i.note;
|
||||||
} else if (showOnly === 'supporters') {
|
}
|
||||||
|
else if (showOnly === 'supporters') {
|
||||||
return i => !!(i.patreon || i.supporter || i.supporterDeclinedSince);
|
return i => !!(i.patreon || i.supporter || i.supporterDeclinedSince);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,7 +222,8 @@ export function getPotentialDuplicates(account: Account, getAccountsByBrowserId:
|
|||||||
|
|
||||||
if (accounts !== undefined && accounts.length > 1 && name !== 'anonymous') {
|
if (accounts !== undefined && accounts.length > 1 && name !== 'anonymous') {
|
||||||
return accounts.filter(a => a !== account && a.nameLower === name);
|
return accounts.filter(a => a !== account && a.nameLower === name);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,18 +231,24 @@ export function getPotentialDuplicates(account: Account, getAccountsByBrowserId:
|
|||||||
// duplicates
|
// duplicates
|
||||||
|
|
||||||
export function compareDuplicates(a: DuplicateBase, b: DuplicateBase): number {
|
export function compareDuplicates(a: DuplicateBase, b: DuplicateBase): number {
|
||||||
if (a.note !== b.note)
|
if (a.note !== b.note) {
|
||||||
return b.note - a.note;
|
return b.note - a.note;
|
||||||
if (a.emails !== b.emails)
|
}
|
||||||
|
if (a.emails !== b.emails) {
|
||||||
return b.emails - a.emails;
|
return b.emails - a.emails;
|
||||||
if (a.name !== b.name)
|
}
|
||||||
|
if (a.name !== b.name) {
|
||||||
return b.name - a.name;
|
return b.name - a.name;
|
||||||
if (a.browserId !== b.browserId)
|
}
|
||||||
|
if (a.browserId !== b.browserId) {
|
||||||
return a.browserId ? -1 : 1;
|
return a.browserId ? -1 : 1;
|
||||||
if (a.origins !== b.origins)
|
}
|
||||||
|
if (a.origins !== b.origins) {
|
||||||
return b.origins - a.origins;
|
return b.origins - a.origins;
|
||||||
if (a.ponies !== b.ponies)
|
}
|
||||||
|
if (a.ponies !== b.ponies) {
|
||||||
return (b.ponies ? b.ponies.length : 0) - (a.ponies ? a.ponies.length : 0);
|
return (b.ponies ? b.ponies.length : 0) - (a.ponies ? a.ponies.length : 0);
|
||||||
|
}
|
||||||
return b.lastVisit.getTime() - a.lastVisit.getTime();
|
return b.lastVisit.getTime() - a.lastVisit.getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +259,8 @@ export function emailName(email: string): string {
|
|||||||
export function createEmailMatcher(emails: string[]): ((email: string) => boolean) | undefined {
|
export function createEmailMatcher(emails: string[]): ((email: string) => boolean) | undefined {
|
||||||
if (!emails || !emails.length) {
|
if (!emails || !emails.length) {
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const match = emails.map(emailName).map(escapeRegExp).join('|');
|
const match = emails.map(emailName).map(escapeRegExp).join('|');
|
||||||
const regex = new RegExp(`^(?:${match})@`, 'i');
|
const regex = new RegExp(`^(?:${match})@`, 'i');
|
||||||
return email => regex.test(email);
|
return email => regex.test(email);
|
||||||
@@ -296,7 +320,8 @@ export function duplicatesCollector(duplicates: string[]) {
|
|||||||
return (item: string) => {
|
return (item: string) => {
|
||||||
if (set.has(item)) {
|
if (set.has(item)) {
|
||||||
duplicates.push(item);
|
duplicates.push(item);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
set.add(item);
|
set.add(item);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -393,7 +418,8 @@ export function addToMap<T>(map: Map<string, T[]>, key: string, item: T) {
|
|||||||
|
|
||||||
if (items) {
|
if (items) {
|
||||||
items.push(item);
|
items.push(item);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
map.set(key, [item]);
|
map.set(key, [item]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -426,7 +452,8 @@ export function createIdStore() {
|
|||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
idsMap.set(id, id);
|
idsMap.set(id, id);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,13 +34,15 @@ export function playAnimation(player: AnimationPlayer, animation: SpriteAnimatio
|
|||||||
player.time = (player.frame + 1) / player.currentAnimation.fps;
|
player.time = (player.frame + 1) / player.currentAnimation.fps;
|
||||||
player.phase = AnimationPhase.Ending;
|
player.phase = AnimationPhase.Ending;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
player.currentAnimation = animation;
|
player.currentAnimation = animation;
|
||||||
player.time = 0;
|
player.time = 0;
|
||||||
player.phase = AnimationPhase.Starting;
|
player.phase = AnimationPhase.Starting;
|
||||||
}
|
}
|
||||||
player.dirty = true;
|
player.dirty = true;
|
||||||
} else if (player.phase === AnimationPhase.Ending) {
|
}
|
||||||
|
else if (player.phase === AnimationPhase.Ending) {
|
||||||
player.nextAnimation = animation;
|
player.nextAnimation = animation;
|
||||||
player.dirty = true;
|
player.dirty = true;
|
||||||
}
|
}
|
||||||
@@ -95,12 +97,14 @@ export function drawAnimation(
|
|||||||
throw new Error('Undefined frame in sprite animation');
|
throw new Error('Undefined frame in sprite animation');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!frame) // TEMP
|
if (!frame) { // TEMP
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (maxY === 0) {
|
if (maxY === 0) {
|
||||||
batch.drawSprite(frame, color, player.palette, x, y);
|
batch.drawSprite(frame, color, player.palette, x, y);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
drawSpriteCropped(batch, frame, color, player.palette, x, y, maxY);
|
drawSpriteCropped(batch, frame, color, player.palette, x, y, maxY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,10 +71,12 @@ export function setAnimatorState<T extends Animation>(animator: Animator<T>, sta
|
|||||||
if (animator.state !== state) {
|
if (animator.state !== state) {
|
||||||
if (animator.state === undefined) {
|
if (animator.state === undefined) {
|
||||||
animator.state = state;
|
animator.state = state;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
animator.target = state;
|
animator.target = state;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
animator.target = undefined;
|
animator.target = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +108,8 @@ export function updateAnimator<T extends Animation>(animator: Animator<T>, delta
|
|||||||
if (frameTimeAfter >= exitAfter || animationEnded) {
|
if (frameTimeAfter >= exitAfter || animationEnded) {
|
||||||
if (!transition.keepTime) {
|
if (!transition.keepTime) {
|
||||||
animator.time = transition.enterTime || 0;
|
animator.time = transition.enterTime || 0;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
animator.time = animator.time % animationLength;
|
animator.time = animator.time % animationLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ export function writeBinary(write: (writer: BinaryWriter) => void): Uint8Array {
|
|||||||
try {
|
try {
|
||||||
write(writer);
|
write(writer);
|
||||||
break;
|
break;
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
if (e instanceof RangeError || isDataViewError(e)) {
|
if (e instanceof RangeError || isDataViewError(e)) {
|
||||||
resizeWriter(writer);
|
resizeWriter(writer);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,7 +25,9 @@ export function writeBinary(write: (writer: BinaryWriter) => void): Uint8Array {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function decodeString(value: DataView | null, offset: number, length: number): string | null {
|
export function decodeString(value: DataView | null, offset: number, length: number): string | null {
|
||||||
if (value == null) return null;
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
let result = '';
|
let result = '';
|
||||||
const end = offset + length;
|
const end = offset + length;
|
||||||
@@ -34,14 +38,16 @@ export function decodeString(value: DataView | null, offset: number, length: num
|
|||||||
|
|
||||||
if ((byte1 & 0x80) === 0) {
|
if ((byte1 & 0x80) === 0) {
|
||||||
code = byte1;
|
code = byte1;
|
||||||
} else if ((byte1 & 0xe0) === 0xc0) {
|
}
|
||||||
|
else if ((byte1 & 0xe0) === 0xc0) {
|
||||||
const byte2 = continuationByte(value, i++, end);
|
const byte2 = continuationByte(value, i++, end);
|
||||||
code = ((byte1 & 0x1f) << 6) | byte2;
|
code = ((byte1 & 0x1f) << 6) | byte2;
|
||||||
|
|
||||||
if (code < 0x80) {
|
if (code < 0x80) {
|
||||||
throw Error('Invalid continuation byte');
|
throw Error('Invalid continuation byte');
|
||||||
}
|
}
|
||||||
} else if ((byte1 & 0xf0) === 0xe0) {
|
}
|
||||||
|
else if ((byte1 & 0xf0) === 0xe0) {
|
||||||
const byte2 = continuationByte(value, i++, end);
|
const byte2 = continuationByte(value, i++, end);
|
||||||
const byte3 = continuationByte(value, i++, end);
|
const byte3 = continuationByte(value, i++, end);
|
||||||
code = ((byte1 & 0x0f) << 12) | (byte2 << 6) | byte3;
|
code = ((byte1 & 0x0f) << 12) | (byte2 << 6) | byte3;
|
||||||
@@ -53,7 +59,8 @@ export function decodeString(value: DataView | null, offset: number, length: num
|
|||||||
if (code >= 0xd800 && code <= 0xdfff) {
|
if (code >= 0xd800 && code <= 0xdfff) {
|
||||||
throw Error(`Lone surrogate U+${code.toString(16).toUpperCase()} is not a scalar value`);
|
throw Error(`Lone surrogate U+${code.toString(16).toUpperCase()} is not a scalar value`);
|
||||||
}
|
}
|
||||||
} else if ((byte1 & 0xf8) === 0xf0) {
|
}
|
||||||
|
else if ((byte1 & 0xf8) === 0xf0) {
|
||||||
const byte2 = continuationByte(value, i++, end);
|
const byte2 = continuationByte(value, i++, end);
|
||||||
const byte3 = continuationByte(value, i++, end);
|
const byte3 = continuationByte(value, i++, end);
|
||||||
const byte4 = continuationByte(value, i++, end);
|
const byte4 = continuationByte(value, i++, end);
|
||||||
@@ -62,7 +69,8 @@ export function decodeString(value: DataView | null, offset: number, length: num
|
|||||||
if (code < 0x010000 || code > 0x10ffff) {
|
if (code < 0x010000 || code > 0x10ffff) {
|
||||||
throw Error('Invalid continuation byte');
|
throw Error('Invalid continuation byte');
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw Error('Invalid UTF-8 detected');
|
throw Error('Invalid UTF-8 detected');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,13 +87,16 @@ export function decodeString(value: DataView | null, offset: number, length: num
|
|||||||
}
|
}
|
||||||
|
|
||||||
function continuationByte(buffer: DataView, index: number, end: number): number {
|
function continuationByte(buffer: DataView, index: number, end: number): number {
|
||||||
if (index >= end) throw Error('Invalid byte index');
|
if (index >= end) {
|
||||||
|
throw Error('Invalid byte index');
|
||||||
|
}
|
||||||
|
|
||||||
const continuationByte = buffer.getUint8(index);
|
const continuationByte = buffer.getUint8(index);
|
||||||
|
|
||||||
if ((continuationByte & 0xC0) === 0x80) {
|
if ((continuationByte & 0xC0) === 0x80) {
|
||||||
return continuationByte & 0x3F;
|
return continuationByte & 0x3F;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw Error('Invalid continuation byte');
|
throw Error('Invalid continuation byte');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,8 +110,9 @@ export function encodeString(string?: string | null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getStringLengthWithLength(value?: string | null) {
|
export function getStringLengthWithLength(value?: string | null) {
|
||||||
if (value == null)
|
if (value == null) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
const len = stringLengthInBytes(value);
|
const len = stringLengthInBytes(value);
|
||||||
return getLength(len) + len;
|
return getLength(len) + len;
|
||||||
}
|
}
|
||||||
@@ -134,7 +146,8 @@ function forEachCharacter(value: string, callback: (code: number) => void) {
|
|||||||
callback(((code & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000);
|
callback(((code & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
callback(code);
|
callback(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,11 +156,14 @@ function forEachCharacter(value: string, callback: (code: number) => void) {
|
|||||||
function charLengthInBytes(code: number): number {
|
function charLengthInBytes(code: number): number {
|
||||||
if ((code & 0xffffff80) === 0) {
|
if ((code & 0xffffff80) === 0) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if ((code & 0xfffff800) === 0) {
|
}
|
||||||
|
else if ((code & 0xfffff800) === 0) {
|
||||||
return 2;
|
return 2;
|
||||||
} else if ((code & 0xffff0000) === 0) {
|
}
|
||||||
|
else if ((code & 0xffff0000) === 0) {
|
||||||
return 3;
|
return 3;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ export function canvasToSource(canvas: HTMLCanvasElement) {
|
|||||||
canvas.toBlob(blob => {
|
canvas.toBlob(blob => {
|
||||||
if (blob) {
|
if (blob) {
|
||||||
resolve(URL.createObjectURL(blob));
|
resolve(URL.createObjectURL(blob));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
reject(new Error('Failed to convert canvas'));
|
reject(new Error('Failed to convert canvas'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -93,7 +94,8 @@ export function saveCanvas(canvas: HTMLCanvasElement, name: string) {
|
|||||||
export function disableImageSmoothing(context: CanvasRenderingContext2D) {
|
export function disableImageSmoothing(context: CanvasRenderingContext2D) {
|
||||||
if ('imageSmoothingEnabled' in context) {
|
if ('imageSmoothingEnabled' in context) {
|
||||||
context.imageSmoothingEnabled = false;
|
context.imageSmoothingEnabled = false;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
(context as any).webkitImageSmoothingEnabled = false;
|
(context as any).webkitImageSmoothingEnabled = false;
|
||||||
(context as any).mozImageSmoothingEnabled = false;
|
(context as any).mozImageSmoothingEnabled = false;
|
||||||
(context as any).msImageSmoothingEnabled = false;
|
(context as any).msImageSmoothingEnabled = false;
|
||||||
|
|||||||
+48
-22
@@ -68,14 +68,16 @@ function isPonyColliding<T extends Region | undefined>(x: number, y: number, map
|
|||||||
function isColliding(x: number, y: number, mask: number, map: IMap<Region | undefined>) {
|
function isColliding(x: number, y: number, mask: number, map: IMap<Region | undefined>) {
|
||||||
if (x < 0 || x >= (map.width * tileWidth) || y < 0 || y >= (map.height * tileHeight)) {
|
if (x < 0 || x >= (map.width * tileWidth) || y < 0 || y >= (map.height * tileHeight)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const regionX = (x / REGION_WIDTH) | 0;
|
const regionX = (x / REGION_WIDTH) | 0;
|
||||||
const regionY = (y / REGION_HEIGHT) | 0;
|
const regionY = (y / REGION_HEIGHT) | 0;
|
||||||
const region = map.regions[regionX + regionY * map.regionsX];
|
const region = map.regions[regionX + regionY * map.regionsX];
|
||||||
|
|
||||||
if (region === undefined) {
|
if (region === undefined) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const insideX = (x % REGION_WIDTH) | 0;
|
const insideX = (x % REGION_WIDTH) | 0;
|
||||||
const insideY = (y % REGION_HEIGHT) | 0;
|
const insideY = (y % REGION_HEIGHT) | 0;
|
||||||
return (region.collider[insideX + insideY * REGION_WIDTH] & mask) !== 0;
|
return (region.collider[insideX + insideY * REGION_WIDTH] & mask) !== 0;
|
||||||
@@ -153,24 +155,29 @@ export function updatePosition(entity: Entity, delta: number, map: IMap<Region |
|
|||||||
oy = 1;
|
oy = 1;
|
||||||
stepYT = 1 | 0;
|
stepYT = 1 | 0;
|
||||||
stepXF = 1 | 0;
|
stepXF = 1 | 0;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
ox = 1;
|
ox = 1;
|
||||||
stepYT = -1 | 0;
|
stepYT = -1 | 0;
|
||||||
stepXF = 1 | 0;
|
stepXF = 1 | 0;
|
||||||
}
|
}
|
||||||
} else if (srcX > dstX) {
|
}
|
||||||
|
else if (srcX > dstX) {
|
||||||
if (srcY < dstY) {
|
if (srcY < dstY) {
|
||||||
oy = 1;
|
oy = 1;
|
||||||
stepYT = 1 | 0;
|
stepYT = 1 | 0;
|
||||||
stepXF = -1 | 0;
|
stepXF = -1 | 0;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
stepYT = -1 | 0;
|
stepYT = -1 | 0;
|
||||||
stepXF = -1 | 0;
|
stepXF = -1 | 0;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (srcY < dstY) {
|
if (srcY < dstY) {
|
||||||
stepYF = stepYT = 1 | 0;
|
stepYF = stepYT = 1 | 0;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
stepYF = stepYT = -1 | 0;
|
stepYF = stepYT = -1 | 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,7 +194,8 @@ export function updatePosition(entity: Entity, delta: number, map: IMap<Region |
|
|||||||
if (useGt ? (fx > fy) : (fx < fy)) {
|
if (useGt ? (fx > fy) : (fx < fy)) {
|
||||||
tx = (tx + stepXT) | 0;
|
tx = (tx + stepXT) | 0;
|
||||||
ty = (ty + stepYT) | 0;
|
ty = (ty + stepYT) | 0;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
tx = (tx + stepXF) | 0;
|
tx = (tx + stepXF) | 0;
|
||||||
ty = (ty + stepYF) | 0;
|
ty = (ty + stepYF) | 0;
|
||||||
}
|
}
|
||||||
@@ -217,7 +225,8 @@ export function updatePosition(entity: Entity, delta: number, map: IMap<Region |
|
|||||||
actualNY -= 1;
|
actualNY -= 1;
|
||||||
dstY -= 1;
|
dstY -= 1;
|
||||||
collides = false;
|
collides = false;
|
||||||
} else if (
|
}
|
||||||
|
else if (
|
||||||
shiftDown && (canShiftDown = !isColliding(actualX, actualY + 1, mask, map)) &&
|
shiftDown && (canShiftDown = !isColliding(actualX, actualY + 1, mask, map)) &&
|
||||||
!isColliding(actualNX, actualY + 1, mask, map)
|
!isColliding(actualNX, actualY + 1, mask, map)
|
||||||
) {
|
) {
|
||||||
@@ -225,12 +234,14 @@ export function updatePosition(entity: Entity, delta: number, map: IMap<Region |
|
|||||||
actualNY += 1;
|
actualNY += 1;
|
||||||
dstY += 1;
|
dstY += 1;
|
||||||
collides = false;
|
collides = false;
|
||||||
} else if (shiftUp && canShiftUp && !isColliding(actualNX, actualY - 2, mask, map)) {
|
}
|
||||||
|
else if (shiftUp && canShiftUp && !isColliding(actualNX, actualY - 2, mask, map)) {
|
||||||
actualNX = actualX;
|
actualNX = actualX;
|
||||||
actualNY -= 1;
|
actualNY -= 1;
|
||||||
dstY -= 1;
|
dstY -= 1;
|
||||||
collides = false;
|
collides = false;
|
||||||
} else if (shiftDown && canShiftDown && !isColliding(actualNX, actualY + 2, mask, map)) {
|
}
|
||||||
|
else if (shiftDown && canShiftDown && !isColliding(actualNX, actualY + 2, mask, map)) {
|
||||||
actualNX = actualX;
|
actualNX = actualX;
|
||||||
actualNY += 1;
|
actualNY += 1;
|
||||||
dstY += 1;
|
dstY += 1;
|
||||||
@@ -238,7 +249,8 @@ export function updatePosition(entity: Entity, delta: number, map: IMap<Region |
|
|||||||
}
|
}
|
||||||
|
|
||||||
canMove = canShiftUp || canShiftDown;
|
canMove = canShiftUp || canShiftDown;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
let canShiftLeft = false;
|
let canShiftLeft = false;
|
||||||
let canShiftRight = false;
|
let canShiftRight = false;
|
||||||
|
|
||||||
@@ -250,7 +262,8 @@ export function updatePosition(entity: Entity, delta: number, map: IMap<Region |
|
|||||||
actualNY = actualY;
|
actualNY = actualY;
|
||||||
dstX -= 1;
|
dstX -= 1;
|
||||||
collides = false;
|
collides = false;
|
||||||
} else if (
|
}
|
||||||
|
else if (
|
||||||
shiftRight && (canShiftRight = !isColliding(actualX + 1, actualY, mask, map)) &&
|
shiftRight && (canShiftRight = !isColliding(actualX + 1, actualY, mask, map)) &&
|
||||||
!isColliding(actualX + 1, actualNY, mask, map)
|
!isColliding(actualX + 1, actualNY, mask, map)
|
||||||
) {
|
) {
|
||||||
@@ -258,12 +271,14 @@ export function updatePosition(entity: Entity, delta: number, map: IMap<Region |
|
|||||||
actualNY = actualY;
|
actualNY = actualY;
|
||||||
dstX += 1;
|
dstX += 1;
|
||||||
collides = false;
|
collides = false;
|
||||||
} else if (shiftLeft && canShiftLeft && !isColliding(actualX - 2, actualNY, mask, map)) {
|
}
|
||||||
|
else if (shiftLeft && canShiftLeft && !isColliding(actualX - 2, actualNY, mask, map)) {
|
||||||
actualNX -= 1;
|
actualNX -= 1;
|
||||||
actualNY = actualY;
|
actualNY = actualY;
|
||||||
dstX -= 1;
|
dstX -= 1;
|
||||||
collides = false;
|
collides = false;
|
||||||
} else if (shiftRight && canShiftRight && !isColliding(actualX + 2, actualNY, mask, map)) {
|
}
|
||||||
|
else if (shiftRight && canShiftRight && !isColliding(actualX + 2, actualNY, mask, map)) {
|
||||||
actualNX += 1;
|
actualNX += 1;
|
||||||
actualNY = actualY;
|
actualNY = actualY;
|
||||||
dstX += 1;
|
dstX += 1;
|
||||||
@@ -277,7 +292,8 @@ export function updatePosition(entity: Entity, delta: number, map: IMap<Region |
|
|||||||
if (!collides) {
|
if (!collides) {
|
||||||
actualX = actualNX;
|
actualX = actualNX;
|
||||||
actualY = actualNY;
|
actualY = actualNY;
|
||||||
} else if (!canMove || horizontalOrVertical) {
|
}
|
||||||
|
else if (!canMove || horizontalOrVertical) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -301,17 +317,27 @@ export function setColliderDirty(map: IMap<Region | undefined>, region: Region,
|
|||||||
|
|
||||||
if (x === 0) {
|
if (x === 0) {
|
||||||
const r = getRegionUnsafe(map, region.x - 1, region.y);
|
const r = getRegionUnsafe(map, region.x - 1, region.y);
|
||||||
r && (r.colliderDirty = true);
|
if (r) {
|
||||||
} else if (x === (REGION_SIZE - 1)) {
|
(r.colliderDirty = true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (x === (REGION_SIZE - 1)) {
|
||||||
const r = getRegionUnsafe(map, region.x + 1, region.y);
|
const r = getRegionUnsafe(map, region.x + 1, region.y);
|
||||||
r && (r.colliderDirty = true);
|
if (r) {
|
||||||
|
(r.colliderDirty = true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y === 0) {
|
if (y === 0) {
|
||||||
const r = getRegionUnsafe(map, region.x, region.y - 1);
|
const r = getRegionUnsafe(map, region.x, region.y - 1);
|
||||||
r && (r.colliderDirty = true);
|
if (r) {
|
||||||
} else if (y === (REGION_SIZE - 1)) {
|
(r.colliderDirty = true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (y === (REGION_SIZE - 1)) {
|
||||||
const r = getRegionUnsafe(map, region.x, region.y + 1);
|
const r = getRegionUnsafe(map, region.x, region.y + 1);
|
||||||
r && (r.colliderDirty = true);
|
if (r) {
|
||||||
|
(r.colliderDirty = true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-14
@@ -217,7 +217,8 @@ export function colorToCSS(color: number): string {
|
|||||||
|
|
||||||
if (alpha === 0xff) {
|
if (alpha === 0xff) {
|
||||||
return `#${colorToHexRGB(color)}`;
|
return `#${colorToHexRGB(color)}`;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return `rgba(${getR(color)},${getG(color)},${getB(color)},${alpha / 255})`;
|
return `rgba(${getR(color)},${getG(color)},${getB(color)},${alpha / 255})`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,26 +278,30 @@ export function colorFromHSVAObject({ h, s, v, a }: HSVA) {
|
|||||||
// parse
|
// parse
|
||||||
|
|
||||||
export function parseColorFast(str: string): number {
|
export function parseColorFast(str: string): number {
|
||||||
if (!isString(str))
|
if (!isString(str)) {
|
||||||
return TRANSPARENT;
|
return TRANSPARENT;
|
||||||
|
}
|
||||||
|
|
||||||
const int = parseInt(str, 16);
|
const int = parseInt(str, 16);
|
||||||
|
|
||||||
if (str.length !== 6 || isNaN(int) || int < 0) {
|
if (str.length !== 6 || isNaN(int) || int < 0) {
|
||||||
return parseColorWithAlpha(str, 1);
|
return parseColorWithAlpha(str, 1);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return (((int << 8) | 0xff) >>> 0);
|
return (((int << 8) | 0xff) >>> 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseColor(str: string): number {
|
export function parseColor(str: string): number {
|
||||||
if (!isString(str))
|
if (!isString(str)) {
|
||||||
return TRANSPARENT;
|
return TRANSPARENT;
|
||||||
|
}
|
||||||
|
|
||||||
str = str.trim().toLowerCase();
|
str = str.trim().toLowerCase();
|
||||||
|
|
||||||
if (str === '' || str === 'none' || str === 'transparent')
|
if (str === '' || str === 'none' || str === 'transparent') {
|
||||||
return TRANSPARENT;
|
return TRANSPARENT;
|
||||||
|
}
|
||||||
|
|
||||||
str = colorNames[str] || str;
|
str = colorNames[str] || str;
|
||||||
|
|
||||||
@@ -320,7 +325,8 @@ export function parseColor(str: string): number {
|
|||||||
parseInt(s.charAt(0), 16) * 0x11,
|
parseInt(s.charAt(0), 16) * 0x11,
|
||||||
parseInt(s.charAt(1), 16) * 0x11,
|
parseInt(s.charAt(1), 16) * 0x11,
|
||||||
parseInt(s.charAt(2), 16) * 0x11, 255);
|
parseInt(s.charAt(2), 16) * 0x11, 255);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return colorFromRGBA(
|
return colorFromRGBA(
|
||||||
parseInt(s.substr(0, 2), 16),
|
parseInt(s.substr(0, 2), 16),
|
||||||
parseInt(s.substr(2, 2), 16),
|
parseInt(s.substr(2, 2), 16),
|
||||||
@@ -511,18 +517,34 @@ export function rgb2hsl(rgb: RGB): HSL {
|
|||||||
let s;
|
let s;
|
||||||
let l;
|
let l;
|
||||||
|
|
||||||
if (max === min) h = 0;
|
if (max === min) {
|
||||||
else if (r === max) h = (g - b) / delta;
|
h = 0;
|
||||||
else if (g === max) h = 2 + (b - r) / delta;
|
}
|
||||||
else if (b === max) h = 4 + (r - g) / delta;
|
else if (r === max) {
|
||||||
|
h = (g - b) / delta;
|
||||||
|
}
|
||||||
|
else if (g === max) {
|
||||||
|
h = 2 + (b - r) / delta;
|
||||||
|
}
|
||||||
|
else if (b === max) {
|
||||||
|
h = 4 + (r - g) / delta;
|
||||||
|
}
|
||||||
|
|
||||||
h = Math.min(h * 60, 360);
|
h = Math.min(h * 60, 360);
|
||||||
if (h < 0) h += 360;
|
if (h < 0) {
|
||||||
|
h += 360;
|
||||||
|
}
|
||||||
l = (min + max) / 2;
|
l = (min + max) / 2;
|
||||||
|
|
||||||
if (max === min) s = 0;
|
if (max === min) {
|
||||||
else if (l <= 0.5) s = delta / (max + min);
|
s = 0;
|
||||||
else s = delta / (2 - max - min);
|
}
|
||||||
|
else if (l <= 0.5) {
|
||||||
|
s = delta / (max + min);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s = delta / (2 - max - min);
|
||||||
|
}
|
||||||
h = Math.floor(h);
|
h = Math.floor(h);
|
||||||
s = Math.floor(s * 100);
|
s = Math.floor(s * 100);
|
||||||
l = Math.floor(l * 100);
|
l = Math.floor(l * 100);
|
||||||
|
|||||||
+10
-5
@@ -123,7 +123,8 @@ export function blushColor(coat: number): number {
|
|||||||
(h > 280 && s > 0.2 && s < 0.7 && v > 0.85)
|
(h > 280 && s > 0.2 && s < 0.7 && v > 0.85)
|
||||||
) {
|
) {
|
||||||
return DARK_BLUSH;
|
return DARK_BLUSH;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return LIGHT_BLUSH;
|
return LIGHT_BLUSH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,9 +135,11 @@ export function getTileColor(tile: TileType, season: Season) {
|
|||||||
case TileType.ElevatedDirt:
|
case TileType.ElevatedDirt:
|
||||||
if (season === Season.Autumn) {
|
if (season === Season.Autumn) {
|
||||||
return 0xedd29eff;
|
return 0xedd29eff;
|
||||||
} else if (season === Season.Winter) {
|
}
|
||||||
|
else if (season === Season.Winter) {
|
||||||
return 0xd9c2a1ff;
|
return 0xd9c2a1ff;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return 0xf5d99bff;
|
return 0xf5d99bff;
|
||||||
}
|
}
|
||||||
case TileType.Water:
|
case TileType.Water:
|
||||||
@@ -146,9 +149,11 @@ export function getTileColor(tile: TileType, season: Season) {
|
|||||||
case TileType.Grass:
|
case TileType.Grass:
|
||||||
if (season === Season.Autumn) {
|
if (season === Season.Autumn) {
|
||||||
return 0xddcf71ff;
|
return 0xddcf71ff;
|
||||||
} else if (season === Season.Winter) {
|
}
|
||||||
|
else if (season === Season.Winter) {
|
||||||
return 0xe1ebf8ff;
|
return 0xe1ebf8ff;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return 0x7cc991ff;
|
return 0x7cc991ff;
|
||||||
}
|
}
|
||||||
case TileType.Ice:
|
case TileType.Ice:
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ export function compressTiles(tiles: Uint8Array): Uint8Array {
|
|||||||
if (i === (tiles.length - 1)) {
|
if (i === (tiles.length - 1)) {
|
||||||
write(count | 0b1000, bitsPerRun);
|
write(count | 0b1000, bitsPerRun);
|
||||||
write(types.indexOf(value), bitsPerTile);
|
write(types.indexOf(value), bitsPerTile);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (value === tiles[i]) {
|
if (value === tiles[i]) {
|
||||||
@@ -56,7 +57,8 @@ export function compressTiles(tiles: Uint8Array): Uint8Array {
|
|||||||
|
|
||||||
write(count, bitsPerRun);
|
write(count, bitsPerRun);
|
||||||
write(types.indexOf(value), bitsPerTile);
|
write(types.indexOf(value), bitsPerTile);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
let last = tiles[i];
|
let last = tiles[i];
|
||||||
let last2 = last;
|
let last2 = last;
|
||||||
let pushLast = true;
|
let pushLast = true;
|
||||||
@@ -71,10 +73,12 @@ export function compressTiles(tiles: Uint8Array): Uint8Array {
|
|||||||
count--;
|
count--;
|
||||||
pushLast = false;
|
pushLast = false;
|
||||||
break;
|
break;
|
||||||
} else if (count === 0b111) {
|
}
|
||||||
|
else if (count === 0b111) {
|
||||||
i -= 1;
|
i -= 1;
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
values.push(last);
|
values.push(last);
|
||||||
count++;
|
count++;
|
||||||
last = last2;
|
last = last2;
|
||||||
@@ -110,7 +114,8 @@ export function decompressTiles(data: Uint8Array): Uint8Array {
|
|||||||
|
|
||||||
if (types.length === 1) {
|
if (types.length === 1) {
|
||||||
result.fill(types[0]);
|
result.fill(types[0]);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const bitsPerTile = getBitsForNumber(typesCount);
|
const bitsPerTile = getBitsForNumber(typesCount);
|
||||||
const bitsPerRun = 4;
|
const bitsPerRun = 4;
|
||||||
|
|
||||||
@@ -125,7 +130,8 @@ export function decompressTiles(data: Uint8Array): Uint8Array {
|
|||||||
result[i] = types[entry];
|
result[i] = types[entry];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const count = value & 0b0111;
|
const count = value & 0b0111;
|
||||||
|
|
||||||
for (let j = 0; j < count; j++) {
|
for (let j = 0; j < count; j++) {
|
||||||
|
|||||||
@@ -307,13 +307,15 @@ const ALL_LOCKED = array(MAX_COLORS, true);
|
|||||||
export function precompressSet<T>(
|
export function precompressSet<T>(
|
||||||
set: SpriteSet<T> | undefined, def: SetDefinition, customOutlines: boolean, defaultColor: T, addColor: (color: T) => number
|
set: SpriteSet<T> | undefined, def: SetDefinition, customOutlines: boolean, defaultColor: T, addColor: (color: T) => number
|
||||||
): PrecompressedSet | undefined {
|
): PrecompressedSet | undefined {
|
||||||
if (!set)
|
if (!set) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const type = clamp(toInt(set.type), 0, def.sets.length - 1);
|
const type = clamp(toInt(set.type), 0, def.sets.length - 1);
|
||||||
|
|
||||||
if (type === 0 && !def.preserveOnZero)
|
if (type === 0 && !def.preserveOnZero) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const patterns = at(def.sets, type);
|
const patterns = at(def.sets, type);
|
||||||
const pattern = clamp(toInt(set.pattern), 0, patterns ? patterns.length - 1 : 0);
|
const pattern = clamp(toInt(set.pattern), 0, patterns ? patterns.length - 1 : 0);
|
||||||
@@ -321,8 +323,9 @@ export function precompressSet<T>(
|
|||||||
const colors = Math.max(getColorCount(sprite), def.minColors || 0);
|
const colors = Math.max(getColorCount(sprite), def.minColors || 0);
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
if (type === 0 && pattern === 0 && colors === 0)
|
if (type === 0 && pattern === 0 && colors === 0) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const fillLocks = compressLockSet(set.lockFills, colors);
|
const fillLocks = compressLockSet(set.lockFills, colors);
|
||||||
const fills = precompressColorSet(set.fills, colors, fillLocks, defaultColor, addColor);
|
const fills = precompressColorSet(set.fills, colors, fillLocks, defaultColor, addColor);
|
||||||
@@ -355,7 +358,8 @@ function precompressFields<TDef extends FieldDefinition<TResult>, TValue, TResul
|
|||||||
return trimRight(defs.map(def => {
|
return trimRight(defs.map(def => {
|
||||||
if (def.dontSave || (def.omit && def.omit(data))) {
|
if (def.dontSave || (def.omit && def.omit(data))) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return encode(data[def.name], def);
|
return encode(data[def.name], def);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@@ -512,7 +516,8 @@ export function readSet(
|
|||||||
const outlineLocks = customOutlines ? read(colors) : 0;
|
const outlineLocks = customOutlines ? read(colors) : 0;
|
||||||
const outlines = customOutlines ? readTimes(read, colors - countBits(outlineLocks), colorBits) : [];
|
const outlines = customOutlines ? readTimes(read, colors - countBits(outlineLocks), colorBits) : [];
|
||||||
return { type, pattern, colors, fillLocks, fills, outlineLocks, outlines };
|
return { type, pattern, colors, fillLocks, fills, outlineLocks, outlines };
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ import { hasFlag } from '../utils';
|
|||||||
export const EMPTY_EXPRESSION = 0x1fffffff;
|
export const EMPTY_EXPRESSION = 0x1fffffff;
|
||||||
|
|
||||||
export function encodeExpression(expression: Expression | undefined): number {
|
export function encodeExpression(expression: Expression | undefined): number {
|
||||||
if (!expression)
|
if (!expression) {
|
||||||
return EMPTY_EXPRESSION;
|
return EMPTY_EXPRESSION;
|
||||||
|
}
|
||||||
|
|
||||||
const { extra, rightIris, leftIris, right, left, muzzle } = expression;
|
const { extra, rightIris, leftIris, right, left, muzzle } = expression;
|
||||||
|
|
||||||
@@ -16,8 +17,9 @@ export function encodeExpression(expression: Expression | undefined): number {
|
|||||||
export function decodeExpression(value: number): Expression | undefined {
|
export function decodeExpression(value: number): Expression | undefined {
|
||||||
value = value >>> 0;
|
value = value >>> 0;
|
||||||
|
|
||||||
if (value === EMPTY_EXPRESSION)
|
if (value === EMPTY_EXPRESSION) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const muzzle = value & 0x1f;
|
const muzzle = value & 0x1f;
|
||||||
const left = (value >> 5) & 0x1f;
|
const left = (value >> 5) & 0x1f;
|
||||||
|
|||||||
@@ -90,8 +90,9 @@ export function decodeUpdate(data: Uint8Array): DecodedRegionUpdate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function readOneUpdate(reader: BinaryReader): DecodedUpdate | undefined {
|
export function readOneUpdate(reader: BinaryReader): DecodedUpdate | undefined {
|
||||||
if (reader.offset >= reader.view.byteLength)
|
if (reader.offset >= reader.view.byteLength) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const flags = readUint16(reader);
|
const flags = readUint16(reader);
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,9 @@ if (DEVELOPMENT) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const { type } of entities) {
|
for (const { type } of entities) {
|
||||||
if (type === 0)
|
if (type === 0) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const entity = createAnEntity(type, 0, 0, 0, {}, mockPaletteManager, defaultWorldState);
|
const entity = createAnEntity(type, 0, 0, 0, {}, mockPaletteManager, defaultWorldState);
|
||||||
const name = getEntityTypeName(type);
|
const name = getEntityTypeName(type);
|
||||||
|
|||||||
@@ -134,7 +134,8 @@ export function mixBounds(x: number, y: number, w: number, h: number): MixinEnti
|
|||||||
export function mixServerFlags(flags: ServerFlags): MixinEntity {
|
export function mixServerFlags(flags: ServerFlags): MixinEntity {
|
||||||
if (SERVER) {
|
if (SERVER) {
|
||||||
return base => base.serverFlags! |= flags;
|
return base => base.serverFlags! |= flags;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return () => { };
|
return () => { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,7 +181,9 @@ export function doodadSet(name: string, sprite: PaletteRenderable, ox: number, o
|
|||||||
|
|
||||||
// placeholder entity
|
// placeholder entity
|
||||||
|
|
||||||
registerMix(n('null'), () => { throw new Error('Invalid type (0)'); });
|
registerMix(n('null'), () => {
|
||||||
|
throw new Error('Invalid type (0)');
|
||||||
|
});
|
||||||
|
|
||||||
// entities
|
// entities
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,11 @@ export function getPonyChatHeight(pony: Pony) {
|
|||||||
|
|
||||||
if (pony.animator.state === trotting) {
|
if (pony.animator.state === trotting) {
|
||||||
return baseHeight;
|
return baseHeight;
|
||||||
} else if (pony.animator.state === flying || pony.animator.state === hovering) {
|
}
|
||||||
|
else if (pony.animator.state === flying || pony.animator.state === hovering) {
|
||||||
return baseHeight - 16;
|
return baseHeight - 16;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const frame = getPonyAnimationFrame(state.animation, state.animationFrame, defaultBodyFrame);
|
const frame = getPonyAnimationFrame(state.animation, state.animationFrame, defaultBodyFrame);
|
||||||
const animation = state.headAnimation || defaultHeadAnimation;
|
const animation = state.headAnimation || defaultHeadAnimation;
|
||||||
const headFrame = getPonyAnimationFrame(animation, state.headAnimationFrame, defaultHeadFrame);
|
const headFrame = getPonyAnimationFrame(animation, state.headAnimationFrame, defaultHeadFrame);
|
||||||
@@ -284,7 +286,8 @@ export function addOrRemoveFromEntityList(list: Entity[], entity: Entity, had: b
|
|||||||
if (had !== has) {
|
if (had !== has) {
|
||||||
if (has) {
|
if (has) {
|
||||||
pushUniq(list, entity);
|
pushUniq(list, entity);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
removeItemFast(list, entity);
|
removeItemFast(list, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,13 +180,15 @@ const horizontalRegex = new RegExp(`^${any(horizontalEyesRight)}(//)?${any(horiz
|
|||||||
function matchVertical(
|
function matchVertical(
|
||||||
text: string, regex: RegExp, flip: boolean, muzzleMap: Dict<Muzzle>, eyesMap: Dict<Eye>, command: boolean = false
|
text: string, regex: RegExp, flip: boolean, muzzleMap: Dict<Muzzle>, eyesMap: Dict<Eye>, command: boolean = false
|
||||||
): Expression | undefined {
|
): Expression | undefined {
|
||||||
if (!command && /^([|]{2,}|BS|8x|x8|x-?x|\d+)$/i.test(text))
|
if (!command && /^([|]{2,}|BS|8x|x8|x-?x|\d+)$/i.test(text)) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const match = regex.exec(text);
|
const match = regex.exec(text);
|
||||||
|
|
||||||
if (!match)
|
if (!match) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const eyesStr = flip ? match[3] : match[1];
|
const eyesStr = flip ? match[3] : match[1];
|
||||||
const muzzleStr = flip ? match[1] : match[3];
|
const muzzleStr = flip ? match[1] : match[3];
|
||||||
@@ -288,11 +290,14 @@ const constants = createPlainMap<() => Expression | undefined>({
|
|||||||
function matchOther(text: string): Expression | undefined {
|
function matchOther(text: string): Expression | undefined {
|
||||||
if (/^A{5,}\.*$/.test(text)) {
|
if (/^A{5,}\.*$/.test(text)) {
|
||||||
return expression(Eye.Neutral, Eye.Neutral, Muzzle.ConcernedOpen3, Iris.Shocked, Iris.Shocked);
|
return expression(Eye.Neutral, Eye.Neutral, Muzzle.ConcernedOpen3, Iris.Shocked, Iris.Shocked);
|
||||||
} else if (/^a{5,}\.*$/.test(text)) {
|
}
|
||||||
|
else if (/^a{5,}\.*$/.test(text)) {
|
||||||
return expression(Eye.Neutral, Eye.Neutral, Muzzle.ConcernedOpen3);
|
return expression(Eye.Neutral, Eye.Neutral, Muzzle.ConcernedOpen3);
|
||||||
} else if (/^z{3,}\.*$/i.test(text)) {
|
}
|
||||||
|
else if (/^z{3,}\.*$/i.test(text)) {
|
||||||
return expression(Eye.Closed, Eye.Closed, Muzzle.Neutral);
|
return expression(Eye.Closed, Eye.Closed, Muzzle.Neutral);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return constants[text] && constants[text]();
|
return constants[text] && constants[text]();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ export const urlRegexTexts = [
|
|||||||
export function trimRepeatedLetters(test: string): string {
|
export function trimRepeatedLetters(test: string): string {
|
||||||
if (test.length > MAX_REPEATS && (/^.?(.)\1+$/u.test(test) || /^.?(..)\1+$/u.test(test))) {
|
if (test.length > MAX_REPEATS && (/^.?(.)\1+$/u.test(test) || /^.?(..)\1+$/u.test(test))) {
|
||||||
return test.substr(0, MAX_REPEATS) + '…';
|
return test.substr(0, MAX_REPEATS) + '…';
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,9 @@ export const enum EntityState {
|
|||||||
Editable = 8,
|
Editable = 8,
|
||||||
|
|
||||||
// pony
|
// pony
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
|
||||||
HeadTurned = 4,
|
HeadTurned = 4,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
|
||||||
Magic = 8,
|
Magic = 8,
|
||||||
// CanFly ?, // Or in flags ?
|
// CanFly ?, // Or in flags ?
|
||||||
|
|
||||||
@@ -203,7 +205,8 @@ export const enum MessageType {
|
|||||||
export function toMessageType(type: MessageType) {
|
export function toMessageType(type: MessageType) {
|
||||||
if (type === MessageType.WhisperAnnouncement) {
|
if (type === MessageType.WhisperAnnouncement) {
|
||||||
return MessageType.WhisperToAnnouncement;
|
return MessageType.WhisperToAnnouncement;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return MessageType.WhisperTo;
|
return MessageType.WhisperTo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1274,11 +1277,9 @@ export interface PalettePonyInfo extends PonyInfoBase<Palette, PaletteSpriteSet>
|
|||||||
magicColorValue: number;
|
magicColorValue: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PonyInfo extends PonyInfoBase<string, SpriteSet<string>> {
|
export type PonyInfo = PonyInfoBase<string, SpriteSet<string>>;
|
||||||
}
|
|
||||||
|
|
||||||
export interface PonyInfoNumber extends PonyInfoBase<number, SpriteSet<number>> {
|
export type PonyInfoNumber = PonyInfoBase<number, SpriteSet<number>>;
|
||||||
}
|
|
||||||
|
|
||||||
export interface ColorExtra {
|
export interface ColorExtra {
|
||||||
color: Sprite;
|
color: Sprite;
|
||||||
@@ -1742,7 +1743,7 @@ export interface EntityDescriptor {
|
|||||||
create: CreateEntity;
|
create: CreateEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type EntityOptions = PonyEntityOptions | SpiderEntityOptions | SignEntityOptions | {};
|
export type EntityOptions = PonyEntityOptions | SpiderEntityOptions | SignEntityOptions | object;
|
||||||
export type EntityOrPonyOptions = Partial<PonyOptions> & EntityOptions;
|
export type EntityOrPonyOptions = Partial<PonyOptions> & EntityOptions;
|
||||||
|
|
||||||
export interface EntityWorldState {
|
export interface EntityWorldState {
|
||||||
@@ -1826,7 +1827,8 @@ export let counterNow: () => number;
|
|||||||
|
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
counterNow = performance.now;
|
counterNow = performance.now;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const hrtime = process.hrtime;
|
const hrtime = process.hrtime;
|
||||||
const getNanoSeconds = () => {
|
const getNanoSeconds = () => {
|
||||||
const hr = hrtime();
|
const hr = hrtime();
|
||||||
|
|||||||
@@ -102,7 +102,8 @@ export function skewTransform(base: Matrix2D | undefined, skew: number, ox: numb
|
|||||||
translateMat2D(tempMatrix, tempMatrix, ox + x, oy + y);
|
translateMat2D(tempMatrix, tempMatrix, ox + x, oy + y);
|
||||||
skewY(tempMatrix, tempMatrix, skew);
|
skewY(tempMatrix, tempMatrix, skew);
|
||||||
translateMat2D(tempMatrix, tempMatrix, -ox, -oy);
|
translateMat2D(tempMatrix, tempMatrix, -ox, -oy);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
translateMat2D(tempMatrix, tempMatrix, x, y);
|
translateMat2D(tempMatrix, tempMatrix, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+90
-34
@@ -50,11 +50,14 @@ function getBounds(sprite: Sprite | undefined, ox: number, oy: number): Rect {
|
|||||||
export function getRenderableBounds({ color, shadow }: Renderable, dx: number, dy: number): Rect {
|
export function getRenderableBounds({ color, shadow }: Renderable, dx: number, dy: number): Rect {
|
||||||
if (color && shadow) {
|
if (color && shadow) {
|
||||||
return addRects(getBounds(color, -dx, -dy), getBounds(shadow, -dx, -dy));
|
return addRects(getBounds(color, -dx, -dy), getBounds(shadow, -dx, -dy));
|
||||||
} else if (color) {
|
}
|
||||||
|
else if (color) {
|
||||||
return getBounds(color, -dx, -dy);
|
return getBounds(color, -dx, -dy);
|
||||||
} else if (shadow) {
|
}
|
||||||
|
else if (shadow) {
|
||||||
return getBounds(shadow, -dx, -dy);
|
return getBounds(shadow, -dx, -dy);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return rect(0, 0, 0, 0);
|
return rect(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -288,15 +291,20 @@ export function mixAnimation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return at(animations[animation], frameNumber) || 0;
|
return at(animations[animation], frameNumber) || 0;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return repeat ? (frameNumber % anim.frames.length) : Math.min(frameNumber, anim.frames.length - 1);
|
return repeat ? (frameNumber % anim.frames.length) : Math.min(frameNumber, anim.frames.length - 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
base.bounds = bounds;
|
base.bounds = bounds;
|
||||||
base.palettes = [];
|
base.palettes = [];
|
||||||
defaultPalette && base.palettes.push(defaultPalette);
|
if (defaultPalette) {
|
||||||
palette && base.palettes.push(palette);
|
base.palettes.push(defaultPalette);
|
||||||
|
}
|
||||||
|
if (palette) {
|
||||||
|
base.palettes.push(palette);
|
||||||
|
}
|
||||||
|
|
||||||
base.update = function (delta: number) {
|
base.update = function (delta: number) {
|
||||||
time += delta;
|
time += delta;
|
||||||
@@ -313,7 +321,8 @@ export function mixAnimation(
|
|||||||
if (lastFrame !== frameNumber) {
|
if (lastFrame !== frameNumber) {
|
||||||
lastFrame = frameNumber;
|
lastFrame = frameNumber;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -332,8 +341,12 @@ export function mixAnimation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
batch.translate(-dx, -dy);
|
batch.translate(-dx, -dy);
|
||||||
anim.shadow && batch.drawSprite(anim.shadow, options.shadowColor, defaultPalette, 0, 0);
|
if (anim.shadow) {
|
||||||
frameSprite && batch.drawSprite(frameSprite, color, palette, 0, 0);
|
batch.drawSprite(anim.shadow, options.shadowColor, defaultPalette, 0, 0);
|
||||||
|
}
|
||||||
|
if (frameSprite) {
|
||||||
|
batch.drawSprite(frameSprite, color, palette, 0, 0);
|
||||||
|
}
|
||||||
batch.restore();
|
batch.restore();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -374,8 +387,12 @@ export function mixDrawWindow(
|
|||||||
const defaultPalette = sprite.shadow && createPalette(sprites.defaultPalette);
|
const defaultPalette = sprite.shadow && createPalette(sprites.defaultPalette);
|
||||||
const palette = createPalette(att(sprite.palettes, paletteIndex));
|
const palette = createPalette(att(sprite.palettes, paletteIndex));
|
||||||
base.palettes = [];
|
base.palettes = [];
|
||||||
defaultPalette && base.palettes.push(defaultPalette);
|
if (defaultPalette) {
|
||||||
palette && base.palettes.push(palette);
|
base.palettes.push(defaultPalette);
|
||||||
|
}
|
||||||
|
if (palette) {
|
||||||
|
base.palettes.push(palette);
|
||||||
|
}
|
||||||
|
|
||||||
base.draw = function (batch, options) {
|
base.draw = function (batch, options) {
|
||||||
const baseX = toScreenX(this.x + (this.ox || 0));
|
const baseX = toScreenX(this.x + (this.ox || 0));
|
||||||
@@ -407,8 +424,12 @@ export function mixDraw(sprite: PaletteRenderable, dx: number, dy: number, palet
|
|||||||
const defaultPalette = sprite.shadow && createPalette(sprites.defaultPalette);
|
const defaultPalette = sprite.shadow && createPalette(sprites.defaultPalette);
|
||||||
const palette = createPalette(att(sprite.palettes, paletteIndex));
|
const palette = createPalette(att(sprite.palettes, paletteIndex));
|
||||||
base.palettes = [];
|
base.palettes = [];
|
||||||
defaultPalette && base.palettes.push(defaultPalette);
|
if (defaultPalette) {
|
||||||
palette && base.palettes.push(palette);
|
base.palettes.push(defaultPalette);
|
||||||
|
}
|
||||||
|
if (palette) {
|
||||||
|
base.palettes.push(palette);
|
||||||
|
}
|
||||||
|
|
||||||
base.draw = function (batch: PaletteSpriteBatch, options: DrawOptions) {
|
base.draw = function (batch: PaletteSpriteBatch, options: DrawOptions) {
|
||||||
const x = toScreenX(this.x + (this.ox || 0)) - dx;
|
const x = toScreenX(this.x + (this.ox || 0)) - dx;
|
||||||
@@ -506,8 +527,12 @@ export function mixDrawSeasonal(setup: MixDrawSeasonal): MixinEntity {
|
|||||||
defaultPalette = sprite.shadow && createPalette(sprites.defaultPalette);
|
defaultPalette = sprite.shadow && createPalette(sprites.defaultPalette);
|
||||||
palette = createPalette(att(sprite.palettes, paletteIndex));
|
palette = createPalette(att(sprite.palettes, paletteIndex));
|
||||||
base.palettes = [];
|
base.palettes = [];
|
||||||
defaultPalette && base.palettes.push(defaultPalette);
|
if (defaultPalette) {
|
||||||
palette && base.palettes.push(palette);
|
base.palettes.push(defaultPalette);
|
||||||
|
}
|
||||||
|
if (palette) {
|
||||||
|
base.palettes.push(palette);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
setupSeason(worldState.season);
|
setupSeason(worldState.season);
|
||||||
@@ -597,8 +622,9 @@ export function mixDrawDirectionSign(): MixinEntity {
|
|||||||
base.bounds = rect(-20, -boundsH, 40, boundsH);
|
base.bounds = rect(-20, -boundsH, 40, boundsH);
|
||||||
base.options = options;
|
base.options = options;
|
||||||
|
|
||||||
if (SERVER && !TESTS)
|
if (SERVER && !TESTS) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
shadowUp, shadowDown, spriteUp, spriteDown, upDX, upDY, downDX, downDY,
|
shadowUp, shadowDown, spriteUp, spriteDown, upDX, upDY, downDX, downDY,
|
||||||
@@ -613,18 +639,30 @@ export function mixDrawDirectionSign(): MixinEntity {
|
|||||||
const defaultPalette = pole.sprite.shadow && createPalette(sprites.defaultPalette);
|
const defaultPalette = pole.sprite.shadow && createPalette(sprites.defaultPalette);
|
||||||
const palette = createPalette(att(pole.sprite.palettes, 0));
|
const palette = createPalette(att(pole.sprite.palettes, 0));
|
||||||
base.palettes = [];
|
base.palettes = [];
|
||||||
defaultPalette && base.palettes.push(defaultPalette);
|
if (defaultPalette) {
|
||||||
palette && base.palettes.push(palette);
|
base.palettes.push(defaultPalette);
|
||||||
|
}
|
||||||
|
if (palette) {
|
||||||
|
base.palettes.push(palette);
|
||||||
|
}
|
||||||
|
|
||||||
base.draw = function (batch, options) {
|
base.draw = function (batch, options) {
|
||||||
const x = toScreenX(this.x);
|
const x = toScreenX(this.x);
|
||||||
const y = toScreenYWithZ(this.y, this.z);
|
const y = toScreenYWithZ(this.y, this.z);
|
||||||
|
|
||||||
batch.drawSprite(pole.sprite.shadow, options.shadowColor, defaultPalette, x + poleDX, y + pole.dy);
|
batch.drawSprite(pole.sprite.shadow, options.shadowColor, defaultPalette, x + poleDX, y + pole.dy);
|
||||||
leftShadow && batch.drawSprite(shadowLeft, options.shadowColor, defaultPalette, x - 18, y - 1);
|
if (leftShadow) {
|
||||||
rightShadow && batch.drawSprite(shadowRight, options.shadowColor, defaultPalette, x + 4, y - 1);
|
batch.drawSprite(shadowLeft, options.shadowColor, defaultPalette, x - 18, y - 1);
|
||||||
upShadow && batch.drawSprite(shadowUp, options.shadowColor, defaultPalette, x + shadowUpDX, y + shadowUpDY);
|
}
|
||||||
downShadow && batch.drawSprite(shadowDown, options.shadowColor, defaultPalette, x + shadowDownDX, y + shadowDownDY);
|
if (rightShadow) {
|
||||||
|
batch.drawSprite(shadowRight, options.shadowColor, defaultPalette, x + 4, y - 1);
|
||||||
|
}
|
||||||
|
if (upShadow) {
|
||||||
|
batch.drawSprite(shadowUp, options.shadowColor, defaultPalette, x + shadowUpDX, y + shadowUpDY);
|
||||||
|
}
|
||||||
|
if (downShadow) {
|
||||||
|
batch.drawSprite(shadowDown, options.shadowColor, defaultPalette, x + shadowDownDX, y + shadowDownDY);
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = n.length - 1; i >= 0; i--) {
|
for (let i = n.length - 1; i >= 0; i--) {
|
||||||
if (n[i] !== -1) {
|
if (n[i] !== -1) {
|
||||||
@@ -637,14 +675,18 @@ export function mixDrawDirectionSign(): MixinEntity {
|
|||||||
for (let i = 0; i < w.length; i++) {
|
for (let i = 0; i < w.length; i++) {
|
||||||
if (w[i] !== -1) {
|
if (w[i] !== -1) {
|
||||||
const sprite = leftSprites[w[i]];
|
const sprite = leftSprites[w[i]];
|
||||||
sprite && batch.drawSprite(sprite, WHITE, palette, x + leftDX, y + pole.dy + plateDY + i * leftRightStep);
|
if (sprite) {
|
||||||
|
batch.drawSprite(sprite, WHITE, palette, x + leftDX, y + pole.dy + plateDY + i * leftRightStep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < e.length; i++) {
|
for (let i = 0; i < e.length; i++) {
|
||||||
if (e[i] !== -1) {
|
if (e[i] !== -1) {
|
||||||
const sprite = rightSprites[e[i]];
|
const sprite = rightSprites[e[i]];
|
||||||
sprite && batch.drawSprite(rightSprites[e[i]], WHITE, palette, x + rightDX, y + pole.dy + plateDY + i * leftRightStep);
|
if (sprite) {
|
||||||
|
batch.drawSprite(rightSprites[e[i]], WHITE, palette, x + rightDX, y + pole.dy + plateDY + i * leftRightStep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,8 +710,9 @@ export function mixLight(color: number, dx: number, dy: number, w: number, h: nu
|
|||||||
const adjustedScale = base.lightScale * base.lightScaleAdjust * LIGHT_VOLUME_SCALE;
|
const adjustedScale = base.lightScale * base.lightScaleAdjust * LIGHT_VOLUME_SCALE;
|
||||||
base.lightBounds = rect(-(dx + w / 2), -(dy + h / 2), w * adjustedScale, h * adjustedScale);
|
base.lightBounds = rect(-(dx + w / 2), -(dy + h / 2), w * adjustedScale, h * adjustedScale);
|
||||||
base.drawLight = function (batch: SpriteBatch) {
|
base.drawLight = function (batch: SpriteBatch) {
|
||||||
if (!this.lightOn)
|
if (!this.lightOn) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const x = toScreenX(this.x);
|
const x = toScreenX(this.x);
|
||||||
const y = toScreenYWithZ(this.y, this.z);
|
const y = toScreenYWithZ(this.y, this.z);
|
||||||
@@ -692,8 +735,9 @@ export function mixLightSprite(sprite: Sprite, color: number, dx: number, dy: nu
|
|||||||
base.lightSpriteColor = color;
|
base.lightSpriteColor = color;
|
||||||
base.lightSpriteBounds = getBounds(sprite, -dx, -dy);
|
base.lightSpriteBounds = getBounds(sprite, -dx, -dy);
|
||||||
base.drawLightSprite = function (batch: SpriteBatch) {
|
base.drawLightSprite = function (batch: SpriteBatch) {
|
||||||
if (!this.lightSpriteOn)
|
if (!this.lightSpriteOn) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const x = toScreenX(this.x) - this.lightSpriteX!;
|
const x = toScreenX(this.x) - this.lightSpriteX!;
|
||||||
const y = toScreenYWithZ(this.y, this.z) - this.lightSpriteY!;
|
const y = toScreenYWithZ(this.y, this.z) - this.lightSpriteY!;
|
||||||
@@ -711,8 +755,9 @@ export function mixDrawRain(): MixinEntity {
|
|||||||
return base => {
|
return base => {
|
||||||
base.bounds = bounds;
|
base.bounds = bounds;
|
||||||
|
|
||||||
if (SERVER && !TESTS)
|
if (SERVER && !TESTS) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let time = 0;
|
let time = 0;
|
||||||
const palette = createPalette(sprites.defaultPalette);
|
const palette = createPalette(sprites.defaultPalette);
|
||||||
@@ -747,7 +792,9 @@ export function mixDrawShadow(sprite: PaletteRenderable, dx: number, dy: number,
|
|||||||
const x = toScreenX(this.x + (this.ox || 0)) - dx;
|
const x = toScreenX(this.x + (this.ox || 0)) - dx;
|
||||||
const y = toScreenYWithZ(this.y + (this.oy || 0), this.z) - dy;
|
const y = toScreenYWithZ(this.y + (this.oy || 0), this.z) - dy;
|
||||||
const color = shadowColor === undefined ? options.shadowColor : shadowColor;
|
const color = shadowColor === undefined ? options.shadowColor : shadowColor;
|
||||||
sprite.shadow && batch.drawSprite(sprite.shadow, color, defaultPalette, x, y);
|
if (sprite.shadow) {
|
||||||
|
batch.drawSprite(sprite.shadow, color, defaultPalette, x, y);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -776,22 +823,29 @@ export function mixDrawWall(
|
|||||||
return base => {
|
return base => {
|
||||||
base.bounds = fullBounds; // fullWalls ? fullBounds : halfBounds
|
base.bounds = fullBounds; // fullWalls ? fullBounds : halfBounds
|
||||||
|
|
||||||
if (SERVER && !TESTS)
|
if (SERVER && !TESTS) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const fullPalette = createPalette(att(full.palettes, 0));
|
const fullPalette = createPalette(att(full.palettes, 0));
|
||||||
const halfPalette = createPalette(att(half.palettes, 0));
|
const halfPalette = createPalette(att(half.palettes, 0));
|
||||||
|
|
||||||
base.palettes = [];
|
base.palettes = [];
|
||||||
fullPalette && base.palettes.push(fullPalette);
|
if (fullPalette) {
|
||||||
halfPalette && base.palettes.push(halfPalette);
|
base.palettes.push(fullPalette);
|
||||||
|
}
|
||||||
|
if (halfPalette) {
|
||||||
|
base.palettes.push(halfPalette);
|
||||||
|
}
|
||||||
|
|
||||||
base.draw = function (batch: PaletteSpriteBatch) {
|
base.draw = function (batch: PaletteSpriteBatch) {
|
||||||
const sprite = fullWalls ? full : half;
|
const sprite = fullWalls ? full : half;
|
||||||
const palette = fullWalls ? fullPalette : halfPalette;
|
const palette = fullWalls ? fullPalette : halfPalette;
|
||||||
const x = toScreenX(this.x) - dx;
|
const x = toScreenX(this.x) - dx;
|
||||||
const y = toScreenYWithZ(this.y, this.z) - (fullWalls ? dy : dy2);
|
const y = toScreenYWithZ(this.y, this.z) - (fullWalls ? dy : dy2);
|
||||||
sprite.color && batch.drawSprite(sprite.color, WHITE, palette, x, y);
|
if (sprite.color) {
|
||||||
|
batch.drawSprite(sprite.color, WHITE, palette, x, y);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -803,8 +857,9 @@ export function mixDrawSpider(
|
|||||||
const spriteColor = sprite.color;
|
const spriteColor = sprite.color;
|
||||||
const baseBounds = getRenderableBounds(sprite, dx, dy);
|
const baseBounds = getRenderableBounds(sprite, dx, dy);
|
||||||
|
|
||||||
if (!spriteColor)
|
if (!spriteColor) {
|
||||||
throw new Error('Missing sprite');
|
throw new Error('Missing sprite');
|
||||||
|
}
|
||||||
|
|
||||||
return base => {
|
return base => {
|
||||||
const { height, time } = base.options as { height: number; time: number; };
|
const { height, time } = base.options as { height: number; time: number; };
|
||||||
@@ -813,8 +868,9 @@ export function mixDrawSpider(
|
|||||||
bounds.h += height;
|
bounds.h += height;
|
||||||
base.bounds = bounds;
|
base.bounds = bounds;
|
||||||
|
|
||||||
if (SERVER && !TESTS)
|
if (SERVER && !TESTS) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const palette = createPalette(sprite.palettes && sprite.palettes[0]);
|
const palette = createPalette(sprite.palettes && sprite.palettes[0]);
|
||||||
base.palettes = [palette];
|
base.palettes = [palette];
|
||||||
|
|||||||
@@ -36,9 +36,11 @@ export function flagsToSpeed(flags: EntityState): number {
|
|||||||
|
|
||||||
if (state === EntityState.PonyTrotting) {
|
if (state === EntityState.PonyTrotting) {
|
||||||
return PONY_SPEED_TROT;
|
return PONY_SPEED_TROT;
|
||||||
} else if (state === EntityState.PonyWalking) {
|
}
|
||||||
|
else if (state === EntityState.PonyWalking) {
|
||||||
return PONY_SPEED_WALK;
|
return PONY_SPEED_WALK;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable camelcase */
|
||||||
import { BodyAnimation, BodyAnimationFrame, HeadAnimation, HeadAnimationFrame, BodyShadow, HeadAnimationProperties } from './interfaces';
|
import { BodyAnimation, BodyAnimationFrame, HeadAnimation, HeadAnimationFrame, BodyShadow, HeadAnimationProperties } from './interfaces';
|
||||||
import { repeat, flatten } from './utils';
|
import { repeat, flatten } from './utils';
|
||||||
|
|
||||||
|
|||||||
@@ -37,8 +37,9 @@ export const mockPaletteManager: PaletteManager = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function spriteSet(type: number, lockFirstFill = true, fill = 'ffd700', otherFills = FILLS): SpriteSet<string> {
|
export function spriteSet(type: number, lockFirstFill = true, fill = 'ffd700', otherFills = FILLS): SpriteSet<string> {
|
||||||
if (otherFills.length !== (MAX_COLORS - 1))
|
if (otherFills.length !== (MAX_COLORS - 1)) {
|
||||||
throw new Error('Invalid fills count');
|
throw new Error('Invalid fills count');
|
||||||
|
}
|
||||||
|
|
||||||
const fills = [fill, ...otherFills];
|
const fills = [fill, ...otherFills];
|
||||||
const outlines = fills.map(fillToOutline);
|
const outlines = fills.map(fillToOutline);
|
||||||
@@ -147,13 +148,15 @@ export function syncLockedSpriteSet<T>(
|
|||||||
set: SpriteSet<T> | undefined, customOutlines: boolean, fillToOutline: FillToOutline<T>, baseFill?: T,
|
set: SpriteSet<T> | undefined, customOutlines: boolean, fillToOutline: FillToOutline<T>, baseFill?: T,
|
||||||
baseOutline?: T
|
baseOutline?: T
|
||||||
) {
|
) {
|
||||||
if (set === undefined)
|
if (set === undefined) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const fills = set.fills;
|
const fills = set.fills;
|
||||||
|
|
||||||
if (!fills)
|
if (!fills) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const lockFills = set.lockFills;
|
const lockFills = set.lockFills;
|
||||||
|
|
||||||
@@ -177,7 +180,8 @@ export function syncLockedSpriteSet<T>(
|
|||||||
if (lockOutlines[i]) {
|
if (lockOutlines[i]) {
|
||||||
if (i === 0 && baseOutline && lockFills && lockFills[i]) {
|
if (i === 0 && baseOutline && lockFills && lockFills[i]) {
|
||||||
outlines[i] = baseOutline;
|
outlines[i] = baseOutline;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
outlines[i] = fillToOutline(fills[i]);
|
outlines[i] = fillToOutline(fills[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,7 +206,8 @@ function syncLockedSpritesSet2<T>(
|
|||||||
if (locked) {
|
if (locked) {
|
||||||
if (baseOutlines[i] && set.lockFills && set.lockFills[i]) {
|
if (baseOutlines[i] && set.lockFills && set.lockFills[i]) {
|
||||||
set.outlines![i] = baseOutlines[i];
|
set.outlines![i] = baseOutlines[i];
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
set.outlines![i] = fillToOutline(set.fills![i]);
|
set.outlines![i] = fillToOutline(set.fills![i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -356,7 +361,8 @@ function getColorsGeneric(
|
|||||||
|
|
||||||
if (darken) {
|
if (darken) {
|
||||||
colors[i * 2 + 1] = outlines[i] ? colorToHexRGB(darkenForOutline(parseColorFast(outlines[i]!))) : defaultColor;
|
colors[i * 2 + 1] = outlines[i] ? colorToHexRGB(darkenForOutline(parseColorFast(outlines[i]!))) : defaultColor;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
colors[i * 2 + 1] = outlines[i] || defaultColor;
|
colors[i * 2 + 1] = outlines[i] || defaultColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -398,7 +404,8 @@ export const getColorsForSetNumber: GetColorsForSet<number> = (set, length, dark
|
|||||||
|
|
||||||
if (darken) {
|
if (darken) {
|
||||||
result[((i << 1) + 2) | 0] = i < outlines.length ? darkenForOutline(outlines[i] || BLACK) : BLACK;
|
result[((i << 1) + 2) | 0] = i < outlines.length ? darkenForOutline(outlines[i] || BLACK) : BLACK;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
result[((i << 1) + 2) | 0] = i < outlines.length ? (outlines[i] || BLACK) : BLACK;
|
result[((i << 1) + 2) | 0] = i < outlines.length ? (outlines[i] || BLACK) : BLACK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -432,8 +439,9 @@ function createCMPalette<T>(
|
|||||||
): Palette | undefined {
|
): Palette | undefined {
|
||||||
const size = CM_SIZE * CM_SIZE;
|
const size = CM_SIZE * CM_SIZE;
|
||||||
|
|
||||||
if (cm === undefined || cm.length === 0 || cm.length > size)
|
if (cm === undefined || cm.length === 0 || cm.length > size) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const result = new Uint32Array(size);
|
const result = new Uint32Array(size);
|
||||||
|
|
||||||
@@ -568,7 +576,8 @@ export function releasePalettes(info: PalettePonyInfo): void {
|
|||||||
if ('refs' in value) {
|
if ('refs' in value) {
|
||||||
const palette = value as Palette;
|
const palette = value as Palette;
|
||||||
releasePalette(palette);
|
releasePalette(palette);
|
||||||
} else if ('palette' in value) {
|
}
|
||||||
|
else if ('palette' in value) {
|
||||||
const set = value as PaletteSpriteSet;
|
const set = value as PaletteSpriteSet;
|
||||||
releasePalette(set.palette);
|
releasePalette(set.palette);
|
||||||
releasePalette(set.extraPalette);
|
releasePalette(set.extraPalette);
|
||||||
|
|||||||
+30
-11
@@ -72,30 +72,49 @@ export function canMagic(info: PonyInfoBase<any, SpriteSetBase>) {
|
|||||||
export function flipIris(iris: Iris): Iris {
|
export function flipIris(iris: Iris): Iris {
|
||||||
if (iris === Iris.Left || iris === Iris.UpLeft) {
|
if (iris === Iris.Left || iris === Iris.UpLeft) {
|
||||||
return iris + 1;
|
return iris + 1;
|
||||||
} else if (iris === Iris.Right || iris === Iris.UpRight) {
|
}
|
||||||
|
else if (iris === Iris.Right || iris === Iris.UpRight) {
|
||||||
return iris - 1;
|
return iris - 1;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return iris;
|
return iris;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function flipFaceAccessoryType(type: number) {
|
export function flipFaceAccessoryType(type: number) {
|
||||||
if (type === 6) return 7;
|
if (type === 6) {
|
||||||
if (type === 7) return 6;
|
return 7;
|
||||||
|
}
|
||||||
|
if (type === 7) {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
if (type === 9) return 10;
|
if (type === 9) {
|
||||||
if (type === 10) return 9;
|
return 10;
|
||||||
|
}
|
||||||
|
if (type === 10) {
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function flipFaceAccessoryPattern(type: number, pattern: number) {
|
export function flipFaceAccessoryPattern(type: number, pattern: number) {
|
||||||
if (type === 2) { // dark glasses
|
if (type === 2) { // dark glasses
|
||||||
if (pattern === 1) return 2;
|
if (pattern === 1) {
|
||||||
if (pattern === 2) return 1;
|
return 2;
|
||||||
} else if (type === 11) { // large dark glasses
|
}
|
||||||
if (pattern === 1) return 2;
|
if (pattern === 2) {
|
||||||
if (pattern === 2) return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type === 11) { // large dark glasses
|
||||||
|
if (pattern === 1) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (pattern === 2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pattern;
|
return pattern;
|
||||||
|
|||||||
@@ -131,8 +131,9 @@ export function generateRegionCollider<T extends Region | undefined>(region: Reg
|
|||||||
for (let rx = minX; rx <= maxX; rx++) {
|
for (let rx = minX; rx <= maxX; rx++) {
|
||||||
const r = getRegion(map, rx, ry);
|
const r = getRegion(map, rx, ry);
|
||||||
|
|
||||||
if (r === undefined)
|
if (r === undefined) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (const entity of r.colliders) {
|
for (const entity of r.colliders) {
|
||||||
const entityX = toScreenX(entity.x - baseX) | 0;
|
const entityX = toScreenX(entity.x - baseX) | 0;
|
||||||
@@ -171,7 +172,8 @@ export function generateRegionCollider<T extends Region | undefined>(region: Reg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
for (const pc of ponyColliders) {
|
for (const pc of ponyColliders) {
|
||||||
const tx0 = (baseX0 + pc.x) | 0;
|
const tx0 = (baseX0 + pc.x) | 0;
|
||||||
const ty0 = (baseY0 + pc.y) | 0;
|
const ty0 = (baseY0 + pc.y) | 0;
|
||||||
@@ -210,7 +212,8 @@ export function getRegionGlobal<T>(map: IMap<T>, x: number, y: number): T {
|
|||||||
export function getRegion<T>(map: IMap<T>, x: number, y: number): T {
|
export function getRegion<T>(map: IMap<T>, x: number, y: number): T {
|
||||||
if (x < 0 || y < 0 || x >= map.regionsX || y >= map.regionsY) {
|
if (x < 0 || y < 0 || x >= map.regionsX || y >= map.regionsY) {
|
||||||
throw new Error(`Invalid region coords (${x}, ${y})`);
|
throw new Error(`Invalid region coords (${x}, ${y})`);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return map.regions[((x | 0) + (y | 0) * map.regionsX) | 0];
|
return map.regions[((x | 0) + (y | 0) * map.regionsX) | 0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,7 +221,8 @@ export function getRegion<T>(map: IMap<T>, x: number, y: number): T {
|
|||||||
export function getRegionUnsafe<T>(map: IMap<T>, x: number, y: number): T | undefined {
|
export function getRegionUnsafe<T>(map: IMap<T>, x: number, y: number): T | undefined {
|
||||||
if (x < 0 || y < 0 || x >= map.regionsX || y >= map.regionsY) {
|
if (x < 0 || y < 0 || x >= map.regionsX || y >= map.regionsY) {
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return map.regions[((x | 0) + (y | 0) * map.regionsX) | 0];
|
return map.regions[((x | 0) + (y | 0) * map.regionsX) | 0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,9 +80,11 @@ export interface Person {
|
|||||||
function getLabel(arg: LogArgument | undefined) {
|
function getLabel(arg: LogArgument | undefined) {
|
||||||
if (typeof arg === 'string') {
|
if (typeof arg === 'string') {
|
||||||
return arg;
|
return arg;
|
||||||
} else if (arg && 'message' in arg) {
|
}
|
||||||
|
else if (arg && 'message' in arg) {
|
||||||
return (arg as any).message + (arg.stack || '');
|
return (arg as any).message + (arg.stack || '');
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return arg ? arg.toString() : '';
|
return arg ? arg.toString() : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,12 @@ function createRegExpFromList(list: string | undefined, wholeWords = false): Reg
|
|||||||
|
|
||||||
if (wholeWords) {
|
if (wholeWords) {
|
||||||
return new RegExp(`\\b(${combined})\\b`, 'ui');
|
return new RegExp(`\\b(${combined})\\b`, 'ui');
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return new RegExp(combined, 'ui');
|
return new RegExp(combined, 'ui');
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,8 +49,9 @@ export const createIsSuspiciousMessage = (general: GeneralSettings) => {
|
|||||||
const testWholeInstant = createCachedTest(true);
|
const testWholeInstant = createCachedTest(true);
|
||||||
|
|
||||||
return (text: string, { filterSwears }: GameServerSettings): Suspicious => {
|
return (text: string, { filterSwears }: GameServerSettings): Suspicious => {
|
||||||
if (test(general.suspiciousMessages, text))
|
if (test(general.suspiciousMessages, text)) {
|
||||||
return Suspicious.Very;
|
return Suspicious.Very;
|
||||||
|
}
|
||||||
|
|
||||||
if (filterSwears) {
|
if (filterSwears) {
|
||||||
if (testSafeInstant(general.suspiciousSafeInstantMessages, text) ||
|
if (testSafeInstant(general.suspiciousSafeInstantMessages, text) ||
|
||||||
@@ -85,7 +88,8 @@ export const createIsSuspiciousAuth =
|
|||||||
function tryParseJSON(value: string): any {
|
function tryParseJSON(value: string): any {
|
||||||
try {
|
try {
|
||||||
return JSON.parse(value);
|
return JSON.parse(value);
|
||||||
} catch {
|
}
|
||||||
|
catch {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +112,8 @@ function matchPony(info: PonyInfoNumber, match: Partial<PonyInfo>) {
|
|||||||
function comparePonyInfoFields(a: any, b: any): boolean {
|
function comparePonyInfoFields(a: any, b: any): boolean {
|
||||||
if (typeof a === 'number' && typeof b === 'string') {
|
if (typeof a === 'number' && typeof b === 'string') {
|
||||||
return a === parseColorFast(b);
|
return a === parseColorFast(b);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return undefined as any;
|
return undefined as any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ export function addTitles(sprites: ColorExtraSets, titles: string[]): ColorExtra
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function addLabels(sprites: ColorExtraSets, labels: string[]) {
|
export function addLabels(sprites: ColorExtraSets, labels: string[]) {
|
||||||
sprites && sprites.forEach((s, i) => s && s[0] ? s[0]!.label = labels[i] : undefined);
|
if (sprites) {
|
||||||
|
sprites.forEach((s, i) => s && s[0] ? s[0]!.label = labels[i] : undefined);
|
||||||
|
}
|
||||||
return sprites;
|
return sprites;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -213,7 +213,8 @@ export function filterString(value: string | undefined, filter: (code: number) =
|
|||||||
code = fromSurrogate(code, extra);
|
code = fromSurrogate(code, extra);
|
||||||
i++;
|
i++;
|
||||||
size++;
|
size++;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
invalidSurrogate = true;
|
invalidSurrogate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1478,7 +1478,8 @@ const ascii = createBadWords(true);
|
|||||||
function tryRegex(value: string, flags: string) {
|
function tryRegex(value: string, flags: string) {
|
||||||
try {
|
try {
|
||||||
return new RegExp(value, flags);
|
return new RegExp(value, flags);
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
return new RegExp(/(?!.*)/);
|
return new RegExp(/(?!.*)/);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,9 +42,11 @@ export function getTagPalette(tag: CharacterTag, palettes: FontPalettes) {
|
|||||||
export function canUseTag(account: AccountRoles, tag: string) {
|
export function canUseTag(account: AccountRoles, tag: string) {
|
||||||
if (tag === 'mod') {
|
if (tag === 'mod') {
|
||||||
return hasRole(account, 'mod');
|
return hasRole(account, 'mod');
|
||||||
} else if (tag === 'dev' || /^dev:/.test(tag)) {
|
}
|
||||||
|
else if (tag === 'dev' || /^dev:/.test(tag)) {
|
||||||
return hasRole(account, 'dev');
|
return hasRole(account, 'dev');
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-10
@@ -423,7 +423,8 @@ function getTileNormal(
|
|||||||
) {
|
) {
|
||||||
if (x >= 0 && y >= 0 && x < REGION_SIZE && y < REGION_SIZE) {
|
if (x >= 0 && y >= 0 && x < REGION_SIZE && y < REGION_SIZE) {
|
||||||
return normalizeTile(tiles[x | (y << 3)], base);
|
return normalizeTile(tiles[x | (y << 3)], base);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const mapX = clamp(x + baseX, 0, map.width - 1);
|
const mapX = clamp(x + baseX, 0, map.width - 1);
|
||||||
const mapY = clamp(y + baseY, 0, map.height - 1);
|
const mapY = clamp(y + baseY, 0, map.height - 1);
|
||||||
const region = getRegionGlobal(map, mapX, mapY);
|
const region = getRegionGlobal(map, mapX, mapY);
|
||||||
@@ -432,7 +433,8 @@ function getTileNormal(
|
|||||||
const regionX = mapX - region.x * REGION_SIZE;
|
const regionX = mapX - region.x * REGION_SIZE;
|
||||||
const regionY = mapY - region.y * REGION_SIZE;
|
const regionY = mapY - region.y * REGION_SIZE;
|
||||||
return normalizeTile(region.tiles[regionX | (regionY << 3)], base);
|
return normalizeTile(region.tiles[regionX | (regionY << 3)], base);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return TileType.None;
|
return TileType.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -446,7 +448,8 @@ function getTileIndex(region: Region, index: number, x: number, y: number, map:
|
|||||||
|
|
||||||
if (type === TileType.Dirt || type === TileType.ElevatedDirt) {
|
if (type === TileType.Dirt || type === TileType.ElevatedDirt) {
|
||||||
baseTileIndex = 47;
|
baseTileIndex = 47;
|
||||||
} else if (type !== TileType.None) {
|
}
|
||||||
|
else if (type !== TileType.None) {
|
||||||
let topLeft = 0, top = 0, topRight = 0, left = 0, right = 0, bottomLeft = 0, bottom = 0, bottomRight = 0;
|
let topLeft = 0, top = 0, topRight = 0, left = 0, right = 0, bottomLeft = 0, bottom = 0, bottomRight = 0;
|
||||||
|
|
||||||
if (x > 1 && y > 1 && x < (REGION_SIZE - 1) && y < (REGION_SIZE - 1)) {
|
if (x > 1 && y > 1 && x < (REGION_SIZE - 1) && y < (REGION_SIZE - 1)) {
|
||||||
@@ -458,7 +461,8 @@ function getTileIndex(region: Region, index: number, x: number, y: number, map:
|
|||||||
bottomLeft = normalizeTile(tiles[(x - 1) | (y + 1) << 3], type);
|
bottomLeft = normalizeTile(tiles[(x - 1) | (y + 1) << 3], type);
|
||||||
bottom = normalizeTile(tiles[(x) | (y + 1) << 3], type);
|
bottom = normalizeTile(tiles[(x) | (y + 1) << 3], type);
|
||||||
bottomRight = normalizeTile(tiles[(x + 1) | (y + 1) << 3], type);
|
bottomRight = normalizeTile(tiles[(x + 1) | (y + 1) << 3], type);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const baseX = (region.x * REGION_SIZE) | 0;
|
const baseX = (region.x * REGION_SIZE) | 0;
|
||||||
const baseY = (region.y * REGION_SIZE) | 0;
|
const baseY = (region.y * REGION_SIZE) | 0;
|
||||||
topLeft = getTileNormal(tiles, baseX, baseY, x - 1, y - 1, map, type);
|
topLeft = getTileNormal(tiles, baseX, baseY, x - 1, y - 1, map, type);
|
||||||
@@ -508,8 +512,9 @@ function valueToHeight(value: number, bottom: number, top: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function initializeTileHeightmaps() {
|
export function initializeTileHeightmaps() {
|
||||||
if (tileHeightMapsInitialized)
|
if (tileHeightMapsInitialized) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
function createTileHeightMaps(sprite: Sprite, tileType: TileTypeNumber, bottom: number, top: number) {
|
function createTileHeightMaps(sprite: Sprite, tileType: TileTypeNumber, bottom: number, top: number) {
|
||||||
const sheetData = sprites.normalSpriteSheet.data!;
|
const sheetData = sprites.normalSpriteSheet.data!;
|
||||||
@@ -591,11 +596,14 @@ export function getTileHeight(
|
|||||||
return heightMaps[tx + ty * tileWidth];
|
return heightMaps[tx + ty * tileWidth];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (typeNumber === TileTypeNumber.SnowOnIce) {
|
}
|
||||||
|
else if (typeNumber === TileTypeNumber.SnowOnIce) {
|
||||||
return -0.2;
|
return -0.2;
|
||||||
} else if (tileType === TileType.ElevatedDirt) {
|
}
|
||||||
|
else if (tileType === TileType.ElevatedDirt) {
|
||||||
return 0.5;
|
return 0.5;
|
||||||
} else if (typeNumber === TileTypeNumber.Boat) {
|
}
|
||||||
|
else if (typeNumber === TileTypeNumber.Boat) {
|
||||||
const frame = ((gameTime / 1000) * WATER_FPS) | 0;
|
const frame = ((gameTime / 1000) * WATER_FPS) | 0;
|
||||||
return waterHeight[frame % waterHeight.length];
|
return waterHeight[frame % waterHeight.length];
|
||||||
}
|
}
|
||||||
@@ -610,7 +618,8 @@ export function getTile<T>(map: IMap<T>, x: number, y: number): TileType {
|
|||||||
const regionX = Math.floor(x - region.x * REGION_SIZE);
|
const regionX = Math.floor(x - region.x * REGION_SIZE);
|
||||||
const regionY = Math.floor(y - region.y * REGION_SIZE);
|
const regionY = Math.floor(y - region.y * REGION_SIZE);
|
||||||
return getRegionTile(region, regionX, regionY);
|
return getRegionTile(region, regionX, regionY);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return TileType.None;
|
return TileType.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -618,8 +627,9 @@ export function getTile<T>(map: IMap<T>, x: number, y: number): TileType {
|
|||||||
export function setTile(map: WorldMap, worldX: number, worldY: number, type: TileType) {
|
export function setTile(map: WorldMap, worldX: number, worldY: number, type: TileType) {
|
||||||
const region = getRegionGlobal(map, worldX, worldY);
|
const region = getRegionGlobal(map, worldX, worldY);
|
||||||
|
|
||||||
if (!region)
|
if (!region) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const x = Math.floor(worldX - region.x * REGION_SIZE);
|
const x = Math.floor(worldX - region.x * REGION_SIZE);
|
||||||
const y = Math.floor(worldY - region.y * REGION_SIZE);
|
const y = Math.floor(worldY - region.y * REGION_SIZE);
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ export function timeStart(name: string) {
|
|||||||
entry.time = performance.now();
|
entry.time = performance.now();
|
||||||
entry.name = name;
|
entry.name = name;
|
||||||
entriesCount++;
|
entriesCount++;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
console.warn(`exceeded timing entry limit`);
|
console.warn(`exceeded timing entry limit`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,7 +45,8 @@ export function timeEnd() {
|
|||||||
entry.time = performance.now();
|
entry.time = performance.now();
|
||||||
entry.name = undefined;
|
entry.name = undefined;
|
||||||
entriesCount++;
|
entriesCount++;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
console.warn(`exceeded timing entry limit`);
|
console.warn(`exceeded timing entry limit`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,7 +72,8 @@ export function timingCollate(): TimingResult[] {
|
|||||||
|
|
||||||
if (entry.name !== undefined) {
|
if (entry.name !== undefined) {
|
||||||
startStack.push({ ...entry, excludedTime: 0 });
|
startStack.push({ ...entry, excludedTime: 0 });
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const start = startStack.pop()!;
|
const start = startStack.pop()!;
|
||||||
const name = start.name!;
|
const name = start.name!;
|
||||||
const time = entry.time - start.time;
|
const time = entry.time - start.time;
|
||||||
|
|||||||
+35
-16
@@ -52,11 +52,14 @@ export function formatDuration(duration: number) {
|
|||||||
|
|
||||||
if (d > 0) {
|
if (d > 0) {
|
||||||
return h ? `${d}d ${h}h` : `${d}d`;
|
return h ? `${d}d ${h}h` : `${d}d`;
|
||||||
} else if (h > 0) {
|
}
|
||||||
|
else if (h > 0) {
|
||||||
return m ? `${h}h ${m}m` : `${h}h`;
|
return m ? `${h}h ${m}m` : `${h}h`;
|
||||||
} else if (m > 0) {
|
}
|
||||||
|
else if (m > 0) {
|
||||||
return s ? `${m}m ${s}s` : `${m}m`;
|
return s ? `${m}m ${s}s` : `${m}m`;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return `${s}s`;
|
return `${s}s`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +96,8 @@ export function createValidBirthDate(day: number, month: number, year: number) {
|
|||||||
year >= (currentYear - 120) && year < currentYear
|
year >= (currentYear - 120) && year < currentYear
|
||||||
) {
|
) {
|
||||||
return date;
|
return date;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,7 +169,9 @@ export function toInt(value: any): number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function dispose<T extends { dispose(): void; }>(obj: T | undefined): undefined {
|
export function dispose<T extends { dispose(): void; }>(obj: T | undefined): undefined {
|
||||||
obj && obj.dispose();
|
if (obj) {
|
||||||
|
obj.dispose();
|
||||||
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +273,8 @@ export function removeItem<T>(items: T[], item: T): boolean {
|
|||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
items.splice(index, 1);
|
items.splice(index, 1);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -279,7 +286,8 @@ export function removeItemFast<T>(items: T[], item: T): boolean {
|
|||||||
items[index] = items[items.length - 1];
|
items[index] = items[items.length - 1];
|
||||||
items.pop();
|
items.pop();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,7 +299,8 @@ export function removeById<U, T extends { id: U }>(items: T[], id: U): T | undef
|
|||||||
const item = items[index];
|
const item = items[index];
|
||||||
items.splice(index, 1);
|
items.splice(index, 1);
|
||||||
return item;
|
return item;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -316,7 +325,8 @@ export function pushUniq<T>(array: T[], item: T) {
|
|||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
array.push(item);
|
array.push(item);
|
||||||
return array.length;
|
return array.length;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return index + 1;
|
return index + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -433,13 +443,17 @@ export function createError(status: number, data: string | { error: string; }):
|
|||||||
return new Error(PROTECTION_ERROR);
|
return new Error(PROTECTION_ERROR);
|
||||||
// } else if (status === 400) {
|
// } else if (status === 400) {
|
||||||
// return new Error('Bad Request');
|
// return new Error('Bad Request');
|
||||||
} else if (status === 403) {
|
}
|
||||||
|
else if (status === 403) {
|
||||||
return new Error(ACCESS_ERROR);
|
return new Error(ACCESS_ERROR);
|
||||||
} else if (status === 404) {
|
}
|
||||||
|
else if (status === 404) {
|
||||||
return new Error(NOT_FOUND_ERROR);
|
return new Error(NOT_FOUND_ERROR);
|
||||||
} else if (typeof data === 'string') {
|
}
|
||||||
|
else if (typeof data === 'string') {
|
||||||
return new Error(data || OFFLINE_ERROR);
|
return new Error(data || OFFLINE_ERROR);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return new Error((data && data.error) || OFFLINE_ERROR);
|
return new Error((data && data.error) || OFFLINE_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -455,7 +469,8 @@ export function observableToPromise<T>(observable: Observable<T>) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
error = JSON.parse(error);
|
error = JSON.parse(error);
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
const e: RequestError = createError(status || 0, error);
|
const e: RequestError = createError(status || 0, error);
|
||||||
e.status = status;
|
e.status = status;
|
||||||
@@ -518,7 +533,9 @@ export function processCommand(text: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function parseSeason(value?: string): Season | undefined {
|
export function parseSeason(value?: string): Season | undefined {
|
||||||
if (!value) return undefined;
|
if (!value) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
switch (value.toLowerCase()) {
|
switch (value.toLowerCase()) {
|
||||||
case 'spring': return Season.Spring;
|
case 'spring': return Season.Spring;
|
||||||
case 'summer': return Season.Summer;
|
case 'summer': return Season.Summer;
|
||||||
@@ -529,7 +546,9 @@ export function parseSeason(value?: string): Season | undefined {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function parseHoliday(value?: string): Holiday | undefined {
|
export function parseHoliday(value?: string): Holiday | undefined {
|
||||||
if (!value) return undefined;
|
if (!value) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
switch (value.toLowerCase()) {
|
switch (value.toLowerCase()) {
|
||||||
case 'none': return Holiday.None;
|
case 'none': return Holiday.None;
|
||||||
case 'halloween': return Holiday.Halloween;
|
case 'halloween': return Holiday.Halloween;
|
||||||
|
|||||||
@@ -145,9 +145,15 @@ export class AdminAccountDetails implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.model.updated = () => { };
|
this.model.updated = () => { };
|
||||||
this.authsSubscription && this.authsSubscription.unsubscribe();
|
if (this.authsSubscription) {
|
||||||
this.accountSubscription && this.accountSubscription.unsubscribe();
|
this.authsSubscription.unsubscribe();
|
||||||
this.originsSubscription && this.originsSubscription.unsubscribe();
|
}
|
||||||
|
if (this.accountSubscription) {
|
||||||
|
this.accountSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
if (this.originsSubscription) {
|
||||||
|
this.originsSubscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
refresh() {
|
refresh() {
|
||||||
const account = this.account;
|
const account = this.account;
|
||||||
@@ -160,10 +166,14 @@ export class AdminAccountDetails implements OnInit, OnDestroy {
|
|||||||
this.accountObject = undefined;
|
this.accountObject = undefined;
|
||||||
this.loadingDuplicates = false;
|
this.loadingDuplicates = false;
|
||||||
|
|
||||||
this.authsSubscription && this.authsSubscription.unsubscribe();
|
if (this.authsSubscription) {
|
||||||
|
this.authsSubscription.unsubscribe();
|
||||||
|
}
|
||||||
this.authsSubscription = undefined;
|
this.authsSubscription = undefined;
|
||||||
|
|
||||||
this.originsSubscription && this.originsSubscription.unsubscribe();
|
if (this.originsSubscription) {
|
||||||
|
this.originsSubscription.unsubscribe();
|
||||||
|
}
|
||||||
this.originsSubscription = undefined;
|
this.originsSubscription = undefined;
|
||||||
|
|
||||||
this.auths = [];
|
this.auths = [];
|
||||||
@@ -201,7 +211,8 @@ export class AdminAccountDetails implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
this.originsSubscription = this.model.accountOrigins
|
this.originsSubscription = this.model.accountOrigins
|
||||||
.subscribe(account._id, origins => this.origins = origins || []);
|
.subscribe(account._id, origins => this.origins = origins || []);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.duplicates = [];
|
this.duplicates = [];
|
||||||
this.ignores = [];
|
this.ignores = [];
|
||||||
this.ignoredBy = [];
|
this.ignoredBy = [];
|
||||||
@@ -468,7 +479,8 @@ export class AdminAccountDetails implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
if (merge.data) {
|
if (merge.data) {
|
||||||
return `${mergeInfo('ACCOUNT', merge.data.account)}\n\n${mergeInfo('MERGED', merge.data.merge)}`;
|
return `${mergeInfo('ACCOUNT', merge.data.account)}\n\n${mergeInfo('MERGED', merge.data.merge)}`;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return '<empty>';
|
return '<empty>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -552,7 +564,9 @@ export class AdminAccountDetails implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
private update() {
|
private update() {
|
||||||
if (this.id) {
|
if (this.id) {
|
||||||
this.accountSubscription && this.accountSubscription.unsubscribe();
|
if (this.accountSubscription) {
|
||||||
|
this.accountSubscription.unsubscribe();
|
||||||
|
}
|
||||||
this.accountSubscription = this.id ? this.model.accounts.subscribe(this.id, a => this.setAccount(a)) : undefined;
|
this.accountSubscription = this.id ? this.model.accounts.subscribe(this.id, a => this.setAccount(a)) : undefined;
|
||||||
|
|
||||||
this.events = this.model.events
|
this.events = this.model.events
|
||||||
|
|||||||
@@ -49,7 +49,9 @@ export class AdminOther implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
saveFields() {
|
saveFields() {
|
||||||
let settings: any = {};
|
let settings: any = {};
|
||||||
@@ -67,7 +69,8 @@ export class AdminOther implements OnInit, OnDestroy {
|
|||||||
try {
|
try {
|
||||||
compact(this.suspiciousPonies!.split(/\n/g).map(x => x.trim())).map(x => JSON.parse(x));
|
compact(this.suspiciousPonies!.split(/\n/g).map(x => x.trim())).map(x => JSON.parse(x));
|
||||||
this.model.updateSettings({ suspiciousPonies: this.suspiciousPonies });
|
this.model.updateSettings({ suspiciousPonies: this.suspiciousPonies });
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
this.suspiciousPoniesError = isErrorAlike(e) ? e.message : 'Unknown error';
|
this.suspiciousPoniesError = isErrorAlike(e) ? e.message : 'Unknown error';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,8 @@ export class AdminPonies implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.items = result.items;
|
this.items = result.items;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.items = [];
|
this.items = [];
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -112,7 +112,8 @@ export class AdminReportsPerf {
|
|||||||
element.style.left = `${x + 10}px`;
|
element.style.left = `${x + 10}px`;
|
||||||
element.style.top = `${y + 10}px`;
|
element.style.top = `${y + 10}px`;
|
||||||
element.innerText = tooltip.text;
|
element.innerText = tooltip.text;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
element.style.display = 'none';
|
element.style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,8 +209,9 @@ export class AdminReportsPerf {
|
|||||||
|
|
||||||
this.tooltips.length = 0;
|
this.tooltips.length = 0;
|
||||||
|
|
||||||
if (!this.timings.length)
|
if (!this.timings.length) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const firstTime = this.timings[0].time;
|
const firstTime = this.timings[0].time;
|
||||||
const startTime = this.startTime;
|
const startTime = this.startTime;
|
||||||
@@ -254,7 +256,8 @@ export class AdminReportsPerf {
|
|||||||
for (const entry of this.timings) {
|
for (const entry of this.timings) {
|
||||||
if (entry.type === TimingEntryType.Start) {
|
if (entry.type === TimingEntryType.Start) {
|
||||||
startStack.push(entry);
|
startStack.push(entry);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const start = startStack.pop()!;
|
const start = startStack.pop()!;
|
||||||
const name = start.name!;
|
const name = start.name!;
|
||||||
const startX = timeToX(start.time);
|
const startX = timeToX(start.time);
|
||||||
@@ -267,9 +270,11 @@ export class AdminReportsPerf {
|
|||||||
if (startStack.length === 0) {
|
if (startStack.length === 0) {
|
||||||
context.fillStyle = '#efc457';
|
context.fillStyle = '#efc457';
|
||||||
text = `${text} (${time.toFixed(2)} ms) ${(100 * time / frameTime).toFixed(0)}%`;
|
text = `${text} (${time.toFixed(2)} ms) ${(100 * time / frameTime).toFixed(0)}%`;
|
||||||
} else if (/\(\)$/.test(name)) {
|
}
|
||||||
|
else if (/\(\)$/.test(name)) {
|
||||||
context.fillStyle = '#d4ecc6';
|
context.fillStyle = '#d4ecc6';
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
context.fillStyle = '#c6dcec';
|
context.fillStyle = '#c6dcec';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,7 +303,8 @@ export class AdminReportsPerf {
|
|||||||
for (const entry of this.timings) {
|
for (const entry of this.timings) {
|
||||||
if (entry.type === TimingEntryType.Start) {
|
if (entry.type === TimingEntryType.Start) {
|
||||||
startStack.push({ ...entry, excludedTime: 0 });
|
startStack.push({ ...entry, excludedTime: 0 });
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const start = startStack.pop()!;
|
const start = startStack.pop()!;
|
||||||
const name = start.name!;
|
const name = start.name!;
|
||||||
const time = entry.time - start.time;
|
const time = entry.time - start.time;
|
||||||
|
|||||||
@@ -41,11 +41,14 @@ export class AdminApp {
|
|||||||
get loading() {
|
get loading() {
|
||||||
if (!this.model.initialized) {
|
if (!this.model.initialized) {
|
||||||
return 'Initializing';
|
return 'Initializing';
|
||||||
} else if (!this.model.connected) {
|
}
|
||||||
|
else if (!this.model.connected) {
|
||||||
return 'Connecting';
|
return 'Connecting';
|
||||||
} else if (!this.model.loaded) {
|
}
|
||||||
|
else if (!this.model.loaded) {
|
||||||
return 'Loading';
|
return 'Loading';
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ export abstract class BaseTable<T> {
|
|||||||
sortBy(field: string) {
|
sortBy(field: string) {
|
||||||
if (this.sortedBy === field) {
|
if (this.sortedBy === field) {
|
||||||
this.sortedAsc = !this.sortedAsc;
|
this.sortedAsc = !this.sortedAsc;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.sortedBy = field;
|
this.sortedBy = field;
|
||||||
this.sortedAsc = true;
|
this.sortedAsc = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ import { transliterate } from 'transliteration';
|
|||||||
})
|
})
|
||||||
export class TranslitPipe implements PipeTransform {
|
export class TranslitPipe implements PipeTransform {
|
||||||
transform(value: string) {
|
transform(value: string) {
|
||||||
if (!value || /^[a-z0-9-_.,[]!@#$%^&*{}|\/\\ ]+$/i.test(value))
|
if (!value || /^[a-z0-9-_.,[]!@#$%^&*{}|\/\\ ]+$/i.test(value)) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const translit = transliterate(value);
|
const translit = transliterate(value);
|
||||||
return translit !== value ? translit : undefined;
|
return translit !== value ? translit : undefined;
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ export class AccountInfoRemote implements OnDestroy {
|
|||||||
constructor(private model: AdminModel) {
|
constructor(private model: AdminModel) {
|
||||||
}
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
get accountId() {
|
get accountId() {
|
||||||
return this._accountId;
|
return this._accountId;
|
||||||
|
|||||||
@@ -134,11 +134,14 @@ export class AccountInfo implements OnInit, OnChanges {
|
|||||||
|
|
||||||
if (this.account.flags) {
|
if (this.account.flags) {
|
||||||
return 'text-banned';
|
return 'text-banned';
|
||||||
} else if (!counters && !this.account.supporter) {
|
}
|
||||||
|
else if (!counters && !this.account.supporter) {
|
||||||
return 'text-muted';
|
return 'text-muted';
|
||||||
} else if (counters && ((counters.spam || 0) > 100 || (counters.swears || 0) > 10)) {
|
}
|
||||||
|
else if (counters && ((counters.spam || 0) > 100 || (counters.swears || 0) > 10)) {
|
||||||
return 'text-alert';
|
return 'text-alert';
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return 'text-present';
|
return 'text-present';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,7 +193,9 @@ export class AccountInfo implements OnInit, OnChanges {
|
|||||||
this.alertModalRef = this.modalService.show(this.alertModal, { ignoreBackdropClick: true });
|
this.alertModalRef = this.modalService.show(this.alertModal, { ignoreBackdropClick: true });
|
||||||
}
|
}
|
||||||
cancelAlert() {
|
cancelAlert() {
|
||||||
this.alertModalRef && this.alertModalRef.hide();
|
if (this.alertModalRef) {
|
||||||
|
this.alertModalRef.hide();
|
||||||
|
}
|
||||||
this.alertModalRef = undefined;
|
this.alertModalRef = undefined;
|
||||||
}
|
}
|
||||||
confirmAlert() {
|
confirmAlert() {
|
||||||
@@ -206,7 +211,8 @@ export class AccountInfo implements OnInit, OnChanges {
|
|||||||
|
|
||||||
if (cached && cached.generatedAt > threshold.getTime()) {
|
if (cached && cached.generatedAt > threshold.getTime()) {
|
||||||
this.duplicates = cached;
|
this.duplicates = cached;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.model.getAllDuplicatesQuickInfo(account._id)
|
this.model.getAllDuplicatesQuickInfo(account._id)
|
||||||
.then(duplicates => {
|
.then(duplicates => {
|
||||||
if (duplicates) {
|
if (duplicates) {
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ export class AdminChatLog implements OnDestroy {
|
|||||||
set autoRefresh(value: boolean) {
|
set autoRefresh(value: boolean) {
|
||||||
if (value) {
|
if (value) {
|
||||||
this.refreshInterval = this.refreshInterval || setInterval(() => this.refresh(), 10 * 1000);
|
this.refreshInterval = this.refreshInterval || setInterval(() => this.refresh(), 10 * 1000);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.stopInterval();
|
this.stopInterval();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +76,8 @@ export class AdminChatLog implements OnDestroy {
|
|||||||
add(account: Account) {
|
add(account: Account) {
|
||||||
if (!this.account) {
|
if (!this.account) {
|
||||||
this.show(account);
|
this.show(account);
|
||||||
} else if (account !== this.account && !includes(this.accounts, account)) {
|
}
|
||||||
|
else if (account !== this.account && !includes(this.accounts, account)) {
|
||||||
this.date = this.date || this.today;
|
this.date = this.date || this.today;
|
||||||
this.accounts.push(account);
|
this.accounts.push(account);
|
||||||
this.refresh();
|
this.refresh();
|
||||||
@@ -116,7 +118,8 @@ export class AdminChatLog implements OnDestroy {
|
|||||||
if (this.account) {
|
if (this.account) {
|
||||||
const accounts = [this.account._id, ...this.accounts.map(a => a._id)];
|
const accounts = [this.account._id, ...this.accounts.map(a => a._id)];
|
||||||
this.handleChat(this.model.accountsFormattedChat(accounts, date));
|
this.handleChat(this.model.accountsFormattedChat(accounts, date));
|
||||||
} else if (this.search) {
|
}
|
||||||
|
else if (this.search) {
|
||||||
this.handleChat(this.model.searchFormattedChat(this.search, date));
|
this.handleChat(this.model.searchFormattedChat(this.search, date));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,7 +180,8 @@ export class AdminChatLog implements OnDestroy {
|
|||||||
|
|
||||||
this.atNode += i;
|
this.atNode += i;
|
||||||
this.processIdle = requestIdleCallback(() => this.processNodes());
|
this.processIdle = requestIdleCallback(() => this.processNodes());
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.nodesToProcess = undefined;
|
this.nodesToProcess = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,12 +30,16 @@ export class AuthInfoEdit implements OnDestroy {
|
|||||||
if (this.authId !== value) {
|
if (this.authId !== value) {
|
||||||
this._authId = value;
|
this._authId = value;
|
||||||
this.auth = undefined;
|
this.auth = undefined;
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
this.subscription = value ? this.model.auths.subscribe(value, auth => this.auth = auth) : undefined;
|
this.subscription = value ? this.model.auths.subscribe(value, auth => this.auth = auth) : undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
removeAuth(auth: Auth | undefined) {
|
removeAuth(auth: Auth | undefined) {
|
||||||
if (auth && confirm('Are you sure?')) {
|
if (auth && confirm('Are you sure?')) {
|
||||||
|
|||||||
@@ -23,11 +23,15 @@ export class AuthInfoRemote implements OnDestroy {
|
|||||||
if (this.authId !== value) {
|
if (this.authId !== value) {
|
||||||
this._authId = value;
|
this._authId = value;
|
||||||
this.auth = undefined;
|
this.auth = undefined;
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
this.subscription = value ? this.model.auths.subscribe(value, auth => this.auth = auth) : undefined;
|
this.subscription = value ? this.model.auths.subscribe(value, auth => this.auth = auth) : undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ export class AuthListRemote implements OnDestroy {
|
|||||||
this._accountId = value;
|
this._accountId = value;
|
||||||
this.auths = [];
|
this.auths = [];
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
this.subscription = value ? this.model.accountAuths.subscribe(value, auths => {
|
this.subscription = value ? this.model.accountAuths.subscribe(value, auths => {
|
||||||
this.auths = auths || [];
|
this.auths = auths || [];
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
@@ -34,6 +36,8 @@ export class AuthListRemote implements OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,9 +37,11 @@ export class BanIcon implements OnInit, OnDestroy, OnChanges {
|
|||||||
get className() {
|
get className() {
|
||||||
if (this.isPerma) {
|
if (this.isPerma) {
|
||||||
return 'text-banned';
|
return 'text-banned';
|
||||||
} else if (this.isTimedOut) {
|
}
|
||||||
|
else if (this.isTimedOut) {
|
||||||
return 'text-alert';
|
return 'text-alert';
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return 'text-muted';
|
return 'text-muted';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ export class EventsTable {
|
|||||||
onShowChat(e: MouseEvent, event: Event, account: Account | undefined) {
|
onShowChat(e: MouseEvent, event: Event, account: Account | undefined) {
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
this.addChat.emit({ event, account });
|
this.addChat.emit({ event, account });
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.showChat.emit({ event, account });
|
this.showChat.emit({ event, account });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ export class FromNow implements OnInit, OnDestroy, OnChanges {
|
|||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.unsubscribe && this.unsubscribe();
|
if (this.unsubscribe) {
|
||||||
|
this.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private update() {
|
private update() {
|
||||||
const text = this.date
|
const text = this.date
|
||||||
|
|||||||
@@ -23,11 +23,15 @@ export class OriginInfoRemote implements OnDestroy {
|
|||||||
if (this.originIP !== value) {
|
if (this.originIP !== value) {
|
||||||
this._originIP = value;
|
this._originIP = value;
|
||||||
this.origin = undefined;
|
this.origin = undefined;
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
this.subscription = value ? this.model.origins.subscribe(value, origin => this.origin = origin) : undefined;
|
this.subscription = value ? this.model.origins.subscribe(value, origin => this.origin = origin) : undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,11 +24,15 @@ export class OriginListRemote implements OnDestroy {
|
|||||||
if (this.accountId !== value) {
|
if (this.accountId !== value) {
|
||||||
this._accountId = value;
|
this._accountId = value;
|
||||||
this.origins = [];
|
this.origins = [];
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
this.subscription = value ? this.model.accountOrigins.subscribe(value, x => this.origins = x || []) : undefined;
|
this.subscription = value ? this.model.accountOrigins.subscribe(value, x => this.origins = x || []) : undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,11 +24,15 @@ export class PonyInfoRemote implements OnDestroy {
|
|||||||
if (this.ponyId !== value) {
|
if (this.ponyId !== value) {
|
||||||
this._ponyId = value;
|
this._ponyId = value;
|
||||||
this.pony = undefined;
|
this.pony = undefined;
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
this.subscription = value ? this.model.ponies.subscribe(value, pony => this.pony = pony) : undefined;
|
this.subscription = value ? this.model.ponies.subscribe(value, pony => this.pony = pony) : undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,11 @@ export class PonyInfo implements OnChanges {
|
|||||||
if (this.pony) {
|
if (this.pony) {
|
||||||
if (isForbiddenName(this.pony.name)) {
|
if (isForbiddenName(this.pony.name)) {
|
||||||
this.labelClass = 'badge-forbidden';
|
this.labelClass = 'badge-forbidden';
|
||||||
} else if (hasFlag(this.pony.flags, CharacterFlags.BadCM)) {
|
}
|
||||||
|
else if (hasFlag(this.pony.flags, CharacterFlags.BadCM)) {
|
||||||
this.labelClass = 'badge-danger';
|
this.labelClass = 'badge-danger';
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.labelClass = 'badge-none';
|
this.labelClass = 'badge-none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ export class PonyListRemote implements OnDestroy {
|
|||||||
this.ponies = [];
|
this.ponies = [];
|
||||||
this.ponyInfos = [];
|
this.ponyInfos = [];
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
this.subscription = value ? this.model.accountPonies.subscribe(value, (x = []) => {
|
this.subscription = value ? this.model.accountPonies.subscribe(value, (x = []) => {
|
||||||
this.ponyInfos = x;
|
this.ponyInfos = x;
|
||||||
this.updatePonies();
|
this.updatePonies();
|
||||||
@@ -48,7 +50,9 @@ export class PonyListRemote implements OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
remove(characterId: string) {
|
remove(characterId: string) {
|
||||||
if (confirm('Are you sure?')) {
|
if (confirm('Are you sure?')) {
|
||||||
|
|||||||
@@ -193,7 +193,8 @@ export class App implements OnInit, OnDestroy {
|
|||||||
if (isSelected(this.game, message.entityId)) {
|
if (isSelected(this.game, message.entityId)) {
|
||||||
this.game.whisperTo = entity;
|
this.game.whisperTo = entity;
|
||||||
chatBox.setChatType('whisper');
|
chatBox.setChatType('whisper');
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.game.select(entity as Pony);
|
this.game.select(entity as Pony);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -490,8 +490,11 @@ export class Character implements OnInit, OnDestroy {
|
|||||||
await this.model.savePony(pony, true);
|
await this.model.savePony(pony, true);
|
||||||
imported++;
|
imported++;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
DEVELOPMENT && console.error(e);
|
catch (e) {
|
||||||
|
if (DEVELOPMENT) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ export class Help {
|
|||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
this.route.fragment.subscribe(f => {
|
this.route.fragment.subscribe(f => {
|
||||||
const element = document.querySelector('#' + f);
|
const element = document.querySelector('#' + f);
|
||||||
if (element) setTimeout(() => element.scrollIntoView(), 10);
|
if (element) {
|
||||||
|
setTimeout(() => element.scrollIntoView(), 10);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,8 +177,9 @@ export class AdminModel {
|
|||||||
return this.liveEvents.finished;
|
return this.liveEvents.finished;
|
||||||
}
|
}
|
||||||
initialize(live: boolean) {
|
initialize(live: boolean) {
|
||||||
if (this.initializedLive)
|
if (this.initializedLive) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
notification.requestPermission();
|
notification.requestPermission();
|
||||||
|
|
||||||
@@ -545,8 +546,9 @@ export class AdminModel {
|
|||||||
}
|
}
|
||||||
private updateStateTimeout: any;
|
private updateStateTimeout: any;
|
||||||
private updateState(): void {
|
private updateState(): void {
|
||||||
if (!this.running)
|
if (!this.running) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
clearTimeout(this.updateStateTimeout);
|
clearTimeout(this.updateStateTimeout);
|
||||||
|
|
||||||
@@ -590,7 +592,8 @@ export class AdminModel {
|
|||||||
function decodeDate(value: number | undefined, base: string | undefined): Date {
|
function decodeDate(value: number | undefined, base: string | undefined): Date {
|
||||||
if (value == null || base == null) {
|
if (value == null || base == null) {
|
||||||
return new Date(0);
|
return new Date(0);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const d = new Date(base);
|
const d = new Date(base);
|
||||||
d.setTime(d.getTime() + value);
|
d.setTime(d.getTime() + value);
|
||||||
return d;
|
return d;
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ function fadeOut(track: Track, id: number, volume: number) {
|
|||||||
howl
|
howl
|
||||||
.fade(volume, 0, 1000, id)
|
.fade(volume, 0, 1000, id)
|
||||||
.once('fade', () => howl.pause(id).stop(id), id);
|
.once('fade', () => howl.pause(id).stop(id), id);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
howl
|
howl
|
||||||
.volume(0, id)
|
.volume(0, id)
|
||||||
.pause(id)
|
.pause(id)
|
||||||
@@ -124,7 +125,8 @@ export class Audio {
|
|||||||
if (this.playing) {
|
if (this.playing) {
|
||||||
if (this.instance) {
|
if (this.instance) {
|
||||||
this.setInstanceVolume(this.instance, this.volume);
|
this.setInstanceVolume(this.instance, this.volume);
|
||||||
} else if (this.volume) {
|
}
|
||||||
|
else if (this.volume) {
|
||||||
this.playRandomTrack();
|
this.playRandomTrack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,12 +139,14 @@ export class Audio {
|
|||||||
if (this.volume) {
|
if (this.volume) {
|
||||||
if (this.instance) {
|
if (this.instance) {
|
||||||
this.resumeInstance(this.instance);
|
this.resumeInstance(this.instance);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.playRandomTrack();
|
this.playRandomTrack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,10 +154,12 @@ export class Audio {
|
|||||||
if (FADE_TRACKS) {
|
if (FADE_TRACKS) {
|
||||||
if (this.playing && this.volume) {
|
if (this.playing && this.volume) {
|
||||||
this.playRandomTrack();
|
this.playRandomTrack();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.play();
|
this.play();
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.play();
|
this.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,15 +181,15 @@ export class Audio {
|
|||||||
private switchToTrack(track: Track) {
|
private switchToTrack(track: Track) {
|
||||||
if (this.instance && this.instance.track === track) {
|
if (this.instance && this.instance.track === track) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.stopInstance(this.instance);
|
this.stopInstance(this.instance);
|
||||||
this.instance = this.playTrack(track);
|
this.instance = this.playTrack(track);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
playRandomTrack() {
|
playRandomTrack() {
|
||||||
while (!this.switchToTrack(sample(this.tracks)!))
|
while (!this.switchToTrack(sample(this.tracks)!)) {}
|
||||||
;
|
|
||||||
|
|
||||||
this.loops = random(4, 7);
|
this.loops = random(4, 7);
|
||||||
}
|
}
|
||||||
@@ -215,7 +221,8 @@ export class Audio {
|
|||||||
|
|
||||||
if (volume && !howl.playing(instance.id)) {
|
if (volume && !howl.playing(instance.id)) {
|
||||||
howl.play(instance.id);
|
howl.play(instance.id);
|
||||||
} else if (!volume && howl.playing(instance.id)) {
|
}
|
||||||
|
else if (!volume && howl.playing(instance.id)) {
|
||||||
howl.pause(instance.id);
|
howl.pause(instance.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,7 +250,8 @@ export class Audio {
|
|||||||
|
|
||||||
if (this.volume && this.playing) {
|
if (this.volume && this.playing) {
|
||||||
this.playRandomTrack();
|
this.playRandomTrack();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.stopInstance(this.instance);
|
this.stopInstance(this.instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ export class AuthGuard implements CanActivate {
|
|||||||
.then(account => {
|
.then(account => {
|
||||||
if (account) {
|
if (account) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.router.navigate(['/']);
|
this.router.navigate(['/']);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { meetsRequirement } from '../../common/accountUtils';
|
|||||||
import { isLanguage, isFocused, sortServersForRussian } from '../../client/clientUtils';
|
import { isLanguage, isFocused, sortServersForRussian } from '../../client/clientUtils';
|
||||||
import { StorageService } from './storageService';
|
import { StorageService } from './storageService';
|
||||||
|
|
||||||
export interface ClientSocketService extends SocketService<ClientActions, IServerActions> { }
|
export type ClientSocketService = SocketService<ClientActions, IServerActions>;
|
||||||
|
|
||||||
function createSocket(
|
function createSocket(
|
||||||
gameService: GameService, game: PonyTownGame, model: Model, zone: NgZone, options: ClientOptions,
|
gameService: GameService, game: PonyTownGame, model: Model, zone: NgZone, options: ClientOptions,
|
||||||
@@ -183,7 +183,8 @@ export class GameService {
|
|||||||
if (reason === LeaveReason.Swearing) {
|
if (reason === LeaveReason.Swearing) {
|
||||||
this.leftMessage = 'Kicked for swearing or inappropriate language';
|
this.leftMessage = 'Kicked for swearing or inappropriate language';
|
||||||
this.locked = true;
|
this.locked = true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.leftMessage = undefined;
|
this.leftMessage = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,11 +234,14 @@ export class GameService {
|
|||||||
private getAndUpdateStatus(account: AccountData | undefined) {
|
private getAndUpdateStatus(account: AccountData | undefined) {
|
||||||
if (this.joining || this.playing || !account || !isFocused()) {
|
if (this.joining || this.playing || !account || !isFocused()) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return this.model.status(this.initialized)
|
return this.model.status(this.initialized)
|
||||||
.then(status => this.updateStatus(account, status))
|
.then(status => this.updateStatus(account, status))
|
||||||
.catch((e: RequestError) => {
|
.catch((e: RequestError) => {
|
||||||
DEVELOPMENT && console.error(e);
|
if (DEVELOPMENT) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
this.offline = e.message === OFFLINE_ERROR;
|
this.offline = e.message === OFFLINE_ERROR;
|
||||||
this.versionError = e.message === VERSION_ERROR;
|
this.versionError = e.message === VERSION_ERROR;
|
||||||
this.protectionError = e.message === PROTECTION_ERROR;
|
this.protectionError = e.message === PROTECTION_ERROR;
|
||||||
@@ -255,14 +259,16 @@ export class GameService {
|
|||||||
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
merge(existing, server);
|
merge(existing, server);
|
||||||
} else if ('name' in server) {
|
}
|
||||||
|
else if ('name' in server) {
|
||||||
const info = server as ServerInfo;
|
const info = server as ServerInfo;
|
||||||
info.countryFlags = info.flag && /^[a-z]{2}( [a-z]{2})*$/.test(info.flag) ? info.flag.split(/ /g) : [];
|
info.countryFlags = info.flag && /^[a-z]{2}( [a-z]{2})*$/.test(info.flag) ? info.flag.split(/ /g) : [];
|
||||||
|
|
||||||
if (info.name && account && meetsRequirement(account, info.require)) {
|
if (info.name && account && meetsRequirement(account, info.require)) {
|
||||||
this.servers.push(info);
|
this.servers.push(info);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// got new server on the list
|
// got new server on the list
|
||||||
this.initialized = false;
|
this.initialized = false;
|
||||||
}
|
}
|
||||||
@@ -302,7 +308,8 @@ export class GameService {
|
|||||||
if (socket.isConnected) {
|
if (socket.isConnected) {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
this.zone.run(resolve);
|
this.zone.run(resolve);
|
||||||
} else if (!this.joining) {
|
}
|
||||||
|
else if (!this.joining) {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
this.zone.run(() => reject(new Error('Cancelled (poll)')));
|
this.zone.run(() => reject(new Error('Cancelled (poll)')));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ export class IntervalUpdateService {
|
|||||||
return (on: boolean) => {
|
return (on: boolean) => {
|
||||||
if (on && !unsubscribe) {
|
if (on && !unsubscribe) {
|
||||||
unsubscribe = this.subscribe(action);
|
unsubscribe = this.subscribe(action);
|
||||||
} else if (!on && unsubscribe) {
|
}
|
||||||
|
else if (!on && unsubscribe) {
|
||||||
unsubscribe();
|
unsubscribe();
|
||||||
unsubscribe = undefined;
|
unsubscribe = undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ export class LiveCollection<T extends Document> {
|
|||||||
if (removeFromList || this.options.deleteItems) {
|
if (removeFromList || this.options.deleteItems) {
|
||||||
removeItem(this.items, item);
|
removeItem(this.items, item);
|
||||||
this.itemsMap.delete(key);
|
this.itemsMap.delete(key);
|
||||||
} else if (deleted) {
|
}
|
||||||
|
else if (deleted) {
|
||||||
item.deleted = true;
|
item.deleted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,8 +65,9 @@ export class LiveCollection<T extends Document> {
|
|||||||
return this.server.assignAccount(this.name, id, account);
|
return this.server.assignAccount(this.name, id, account);
|
||||||
}
|
}
|
||||||
live(): Promise<void> {
|
live(): Promise<void> {
|
||||||
if (!this.running)
|
if (!this.running) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
clearTimeout(this.liveTimeout);
|
clearTimeout(this.liveTimeout);
|
||||||
|
|
||||||
@@ -129,11 +131,13 @@ export class LiveCollection<T extends Document> {
|
|||||||
if (doc) {
|
if (doc) {
|
||||||
if (this.options.onUpdate) {
|
if (this.options.onUpdate) {
|
||||||
this.options.onUpdate(doc, update);
|
this.options.onUpdate(doc, update);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Object.assign(doc, update);
|
Object.assign(doc, update);
|
||||||
}
|
}
|
||||||
all.push(doc);
|
all.push(doc);
|
||||||
} else if (!liveFetch || !this.options.ignore || !this.options.ignore(update)) {
|
}
|
||||||
|
else if (!liveFetch || !this.options.ignore || !this.options.ignore(update)) {
|
||||||
this.push(update);
|
this.push(update);
|
||||||
added.push(update);
|
added.push(update);
|
||||||
all.push(update);
|
all.push(update);
|
||||||
|
|||||||
@@ -78,7 +78,8 @@ export function getPonyTag(pony: PonyObject, account: AccountData | undefined) {
|
|||||||
if (account) {
|
if (account) {
|
||||||
const tag = canUseTag(account, pony.tag || '') ? pony.tag : undefined;
|
const tag = canUseTag(account, pony.tag || '') ? pony.tag : undefined;
|
||||||
return (!tag && account.supporter && !pony.hideSupport) ? `sup${account.supporter}` : tag;
|
return (!tag && account.supporter && !pony.hideSupport) ? `sup${account.supporter}` : tag;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,7 +180,8 @@ export class Model {
|
|||||||
modStatus.mod = isMod(account);
|
modStatus.mod = isMod(account);
|
||||||
modStatus.check = account.check;
|
modStatus.check = account.check;
|
||||||
modStatus.editor = account.editor || modStatus.editor;
|
modStatus.editor = account.editor || modStatus.editor;
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
if (modStatus.editor) {
|
if (modStatus.editor) {
|
||||||
modStatus.editor.typeToName.forEach(({ type, name }) => entityTypeToName.set(type, name));
|
modStatus.editor.typeToName.forEach(({ type, name }) => entityTypeToName.set(type, name));
|
||||||
@@ -208,18 +210,22 @@ export class Model {
|
|||||||
if (e.message === ACCESS_ERROR) {
|
if (e.message === ACCESS_ERROR) {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.storage.setItem('vid', '---');
|
this.storage.setItem('vid', '---');
|
||||||
} else if (e.message === LIMIT_ERROR) {
|
}
|
||||||
|
else if (e.message === LIMIT_ERROR) {
|
||||||
this.loadingError = 'request-limit';
|
this.loadingError = 'request-limit';
|
||||||
return delay(5000).then(() => this.initializeAccount());
|
return delay(5000).then(() => this.initializeAccount());
|
||||||
} else if (e.message === OFFLINE_ERROR) {
|
}
|
||||||
|
else if (e.message === OFFLINE_ERROR) {
|
||||||
this.loadingError = 'cannot-connect';
|
this.loadingError = 'cannot-connect';
|
||||||
return delay(5000).then(() => this.initializeAccount());
|
return delay(5000).then(() => this.initializeAccount());
|
||||||
} else if (e.message === PROTECTION_ERROR) {
|
}
|
||||||
|
else if (e.message === PROTECTION_ERROR) {
|
||||||
this.loadingError = 'cloudflare-error';
|
this.loadingError = 'cloudflare-error';
|
||||||
this.protectionErrors.next();
|
this.protectionErrors.next();
|
||||||
// } else if (e.message === VERSION_ERROR) {
|
// } else if (e.message === VERSION_ERROR) {
|
||||||
// this.updating = true;
|
// this.updating = true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
setTimeout(() => this.loadingError = 'unexpected-error', 5 * SECOND);
|
setTimeout(() => this.loadingError = 'unexpected-error', 5 * SECOND);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
@@ -240,7 +246,9 @@ export class Model {
|
|||||||
})).sort(compareFriends);
|
})).sort(compareFriends);
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
DEVELOPMENT && console.error(e);
|
if (DEVELOPMENT) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
setTimeout(() => this.fetchFriends(), 5000);
|
setTimeout(() => this.fetchFriends(), 5000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -275,7 +283,8 @@ export class Model {
|
|||||||
try {
|
try {
|
||||||
const ponyInfo = decompressPonyString(pony.info, true);
|
const ponyInfo = decompressPonyString(pony.info, true);
|
||||||
return { ponyInfo, ...pony };
|
return { ponyInfo, ...pony };
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
this.errorReporter.reportError(e, { ponyInfo: pony.info });
|
this.errorReporter.reportError(e, { ponyInfo: pony.info });
|
||||||
this.errorReporter.reportError('Pony info reading error', { originalError: isErrorAlike(e) ? e.message: '', ponyInfo: pony.info });
|
this.errorReporter.reportError('Pony info reading error', { originalError: isErrorAlike(e) ? e.message: '', ponyInfo: pony.info });
|
||||||
throw new Error('Error while reading pony info');
|
throw new Error('Error while reading pony info');
|
||||||
@@ -283,7 +292,9 @@ export class Model {
|
|||||||
}
|
}
|
||||||
selectPony(pony: PonyObject) {
|
selectPony(pony: PonyObject) {
|
||||||
const copy = this.parsePonyObject(pony);
|
const copy = this.parsePonyObject(pony);
|
||||||
copy.ponyInfo && syncLockedPonyInfo(copy.ponyInfo);
|
if (copy.ponyInfo) {
|
||||||
|
syncLockedPonyInfo(copy.ponyInfo);
|
||||||
|
}
|
||||||
this._pony = copy;
|
this._pony = copy;
|
||||||
}
|
}
|
||||||
// account
|
// account
|
||||||
@@ -308,7 +319,8 @@ export class Model {
|
|||||||
|
|
||||||
if (isStandalone()) {
|
if (isStandalone()) {
|
||||||
window.open(url);
|
window.open(url);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
location.href = url;
|
location.href = url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -394,7 +406,8 @@ export class Model {
|
|||||||
|
|
||||||
if (pony.id) {
|
if (pony.id) {
|
||||||
removeById(this.ponies, pony.id);
|
removeById(this.ponies, pony.id);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.account!.characterCount++;
|
this.account!.characterCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,7 +456,8 @@ export class Model {
|
|||||||
|
|
||||||
if (this.account.birthyear) {
|
if (this.account.birthyear) {
|
||||||
age = currentYear - this.account.birthyear;
|
age = currentYear - this.account.birthyear;
|
||||||
} else if (this.account.birthdate) {
|
}
|
||||||
|
else if (this.account.birthdate) {
|
||||||
const [year, month] = this.account.birthdate.split('-');
|
const [year, month] = this.account.birthdate.split('-');
|
||||||
const before = parseInt(month, 10) > currentMonth;
|
const before = parseInt(month, 10) > currentMonth;
|
||||||
age = Math.max(0, currentYear - parseInt(year, 10) - (before ? 1 : 0));
|
age = Math.max(0, currentYear - parseInt(year, 10) - (before ? 1 : 0));
|
||||||
@@ -458,12 +472,15 @@ export class Model {
|
|||||||
return observableToPromise(this.http.get<GameStatus>('/api2/game/status', { params }));
|
return observableToPromise(this.http.get<GameStatus>('/api2/game/status', { params }));
|
||||||
}
|
}
|
||||||
join(serverId: string, ponyId: string): Promise<JoinResponse> {
|
join(serverId: string, ponyId: string): Promise<JoinResponse> {
|
||||||
if (this.pending)
|
if (this.pending) {
|
||||||
return Promise.reject(new Error('Joining in progress'));
|
return Promise.reject(new Error('Joining in progress'));
|
||||||
if (!serverId)
|
}
|
||||||
|
if (!serverId) {
|
||||||
return Promise.reject(new Error('Invalid server ID'));
|
return Promise.reject(new Error('Invalid server ID'));
|
||||||
if (!ponyId)
|
}
|
||||||
|
if (!ponyId) {
|
||||||
return Promise.reject(new Error('Invalid pony ID'));
|
return Promise.reject(new Error('Invalid pony ID'));
|
||||||
|
}
|
||||||
|
|
||||||
this.pending = true;
|
this.pending = true;
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ export class ModelSubscriber<T> {
|
|||||||
if (subscription.value !== undefined) {
|
if (subscription.value !== undefined) {
|
||||||
callback(subscription.value);
|
callback(subscription.value);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.socket.server.subscribe(this.type, id);
|
this.socket.server.subscribe(this.type, id);
|
||||||
this.subscriptions.set(id, {
|
this.subscriptions.set(id, {
|
||||||
value: this.defaultValue,
|
value: this.defaultValue,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable camelcase */
|
||||||
import { ErrorHandler, Injectable, Injector, InjectionToken } from '@angular/core';
|
import { ErrorHandler, Injectable, Injector, InjectionToken } from '@angular/core';
|
||||||
import Rollbar from 'rollbar';
|
import Rollbar from 'rollbar';
|
||||||
import { version } from '../../client/data';
|
import { version } from '../../client/data';
|
||||||
@@ -34,7 +35,8 @@ export const RollbarService = new InjectionToken<Rollbar>('rollbar');
|
|||||||
export function rollbarFactory() {
|
export function rollbarFactory() {
|
||||||
if (DEVELOPMENT) {
|
if (DEVELOPMENT) {
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const rollbar = Rollbar.init(rollbarConfig);
|
const rollbar = Rollbar.init(rollbarConfig);
|
||||||
rollbar.configure({ checkIgnore: rollbarCheckIgnore });
|
rollbar.configure({ checkIgnore: rollbarCheckIgnore });
|
||||||
return rollbar;
|
return rollbar;
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ export class RollbarErrorReporter extends ErrorReporter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
reportError(error: any, data?: any) {
|
reportError(error: any, data?: any) {
|
||||||
DEVELOPMENT && console.error(error, data);
|
if (DEVELOPMENT) {
|
||||||
|
console.error(error, data);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.rollbar && !isIgnoredError(error)) {
|
if (this.rollbar && !isIgnoredError(error)) {
|
||||||
this.rollbar.error(error, data);
|
this.rollbar.error(error, data);
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ export class SettingsService {
|
|||||||
|
|
||||||
if (this.save(settings)) {
|
if (this.save(settings)) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return this.model.saveSettings(settings);
|
return this.model.saveSettings(settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,18 +9,21 @@ export class StorageService {
|
|||||||
if (typeof localStorage === 'undefined') {
|
if (typeof localStorage === 'undefined') {
|
||||||
this.data = new Map();
|
this.data = new Map();
|
||||||
}
|
}
|
||||||
} catch {
|
}
|
||||||
|
catch {
|
||||||
this.data = new Map();
|
this.data = new Map();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getItem(key: string) {
|
getItem(key: string) {
|
||||||
if (this.data) {
|
if (this.data) {
|
||||||
return this.data.get(key);
|
return this.data.get(key);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
try {
|
try {
|
||||||
const value = localStorage.getItem(key);
|
const value = localStorage.getItem(key);
|
||||||
return value == null ? undefined : value;
|
return value == null ? undefined : value;
|
||||||
} catch {
|
}
|
||||||
|
catch {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,7 +32,8 @@ export class StorageService {
|
|||||||
try {
|
try {
|
||||||
localStorage.setItem(key, data);
|
localStorage.setItem(key, data);
|
||||||
this.data = undefined;
|
this.data = undefined;
|
||||||
} catch {
|
}
|
||||||
|
catch {
|
||||||
if (!this.data) {
|
if (!this.data) {
|
||||||
this.data = new Map();
|
this.data = new Map();
|
||||||
}
|
}
|
||||||
@@ -40,25 +44,30 @@ export class StorageService {
|
|||||||
removeItem(key: string) {
|
removeItem(key: string) {
|
||||||
if (this.data) {
|
if (this.data) {
|
||||||
this.data.delete(key);
|
this.data.delete(key);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
try {
|
try {
|
||||||
localStorage.removeItem(key);
|
localStorage.removeItem(key);
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clear() {
|
clear() {
|
||||||
if (this.data) {
|
if (this.data) {
|
||||||
this.data.clear();
|
this.data.clear();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
try {
|
try {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
} catch { }
|
}
|
||||||
|
catch { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getJSON<T>(key: string, defaultValue: T): T {
|
getJSON<T>(key: string, defaultValue: T): T {
|
||||||
try {
|
try {
|
||||||
return JSON.parse(this.getItem(key) || '');
|
return JSON.parse(this.getItem(key) || '');
|
||||||
} catch {
|
}
|
||||||
|
catch {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,7 +86,8 @@ export class StorageService {
|
|||||||
setBoolean(key: string, value: boolean) {
|
setBoolean(key: string, value: boolean) {
|
||||||
if (value) {
|
if (value) {
|
||||||
this.setItem(key, 'true');
|
this.setItem(key, 'true');
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.removeItem(key);
|
this.removeItem(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,7 +117,8 @@ export class ActionBar {
|
|||||||
while (actions.length < 5 || (last(actions)!.action !== undefined && actions.length < ACTIONS_LIMIT)) {
|
while (actions.length < 5 || (last(actions)!.action !== undefined && actions.length < ACTIONS_LIMIT)) {
|
||||||
actions.push({ action: undefined });
|
actions.push({ action: undefined });
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
while (actions.length > 0 && last(actions)!.action === undefined) {
|
while (actions.length > 0 && last(actions)!.action === undefined) {
|
||||||
actions.pop();
|
actions.pop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,9 @@ export class ActionsModal implements OnInit, OnDestroy {
|
|||||||
document.body.classList.remove('actions-modal-opened');
|
document.body.classList.remove('actions-modal-opened');
|
||||||
this.game.editingActions = false;
|
this.game.editingActions = false;
|
||||||
clearInterval(this.interval);
|
clearInterval(this.interval);
|
||||||
this.subscription && this.subscription.unsubscribe();
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
this.close.emit(); // need to emit in case the menu wasn't closed with the Close button
|
this.close.emit(); // need to emit in case the menu wasn't closed with the Close button
|
||||||
this.notify.emit();
|
this.notify.emit();
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user