mirror of
https://github.com/Terncode/pixel.horse.git
synced 2026-09-24 21:55:52 +02:00
Archive update v0.55.0
This commit is contained in:
@@ -26,7 +26,7 @@ h1(focusTitle) Account settings
|
||||
| Changes saved
|
||||
.form-group.text-right
|
||||
button.btn.btn-default(type="submit" [disabled]="!canSubmit" style="min-width: 100px;")
|
||||
| Save
|
||||
| {{saveButtonText}}
|
||||
|
||||
div(style="margin-bottom: 100px;")
|
||||
.form-group
|
||||
|
||||
@@ -8,6 +8,7 @@ import { oauthProviders } from '../../../client/data';
|
||||
import { Model } from '../../services/model';
|
||||
import { getProviderIcon } from '../../shared/sign-in-box/sign-in-box';
|
||||
import { faStar, faExclamationCircle, faSync } from '../../../client/icons';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'account',
|
||||
@@ -33,9 +34,10 @@ export class Account implements OnInit, OnDestroy {
|
||||
removedAccount?: boolean;
|
||||
accountError?: string;
|
||||
accountSaved = false;
|
||||
isNewAccount = false;
|
||||
hides: HiddenPlayer[] | undefined = undefined;
|
||||
page = 0;
|
||||
constructor(private model: Model) {
|
||||
constructor(private model: Model, private router: Router) {
|
||||
}
|
||||
ngOnInit() {
|
||||
const account = this.account!;
|
||||
@@ -44,6 +46,7 @@ export class Account implements OnInit, OnDestroy {
|
||||
name: account.name,
|
||||
birthdate: account.birthdate,
|
||||
};
|
||||
this.isNewAccount = account.birthdate === '';
|
||||
|
||||
this.pageChanged();
|
||||
}
|
||||
@@ -88,6 +91,9 @@ export class Account implements OnInit, OnDestroy {
|
||||
get showAccountAlert() {
|
||||
return this.model.missingBirthdate;
|
||||
}
|
||||
get saveButtonText() {
|
||||
return this.isNewAccount ? 'Save and continue' : 'Save';
|
||||
}
|
||||
icon(id: string) {
|
||||
return getProviderIcon(id);
|
||||
}
|
||||
@@ -98,6 +104,9 @@ export class Account implements OnInit, OnDestroy {
|
||||
this.model.updateAccount(this.data)
|
||||
.catch((e: Error) => this.accountError = e.message)
|
||||
.then(() => this.accountSaved = true);
|
||||
if (this.isNewAccount) {
|
||||
this.router.navigate(['home']);
|
||||
}
|
||||
}
|
||||
}
|
||||
removeSite(site: SocialSiteInfo) {
|
||||
|
||||
@@ -204,13 +204,15 @@ h1(focusTitle) Help
|
||||
p.text-fading.
|
||||
This is usually caused by outdated graphics drivers or browser.
|
||||
Check if your browser is #[a(href="https://updatemybrowser.org/") up to date] and check
|
||||
if there are new updates for your graphics card or device.
|
||||
if there are new updates for your graphics driver or your device.
|
||||
p.text-fading.
|
||||
If your browser is already up to date, try installing different browser.
|
||||
We recommend using #[a(href="https://www.google.com/chrome/") Chrome]
|
||||
or #[a(href="https://www.mozilla.org/en-US/firefox/new/") Firefox].
|
||||
p.text-fading.
|
||||
Some older devices don't support necessary functions and will never work with the game.
|
||||
If other workarounds didn't help, switching Graphics Quality to Low usually works.
|
||||
You'll find that option in the game settings. After switching to Low, it
|
||||
might take a minute for the screen to stop glitching.
|
||||
|
||||
section
|
||||
h4 Graphical glitches, disappearing objects
|
||||
|
||||
@@ -83,6 +83,13 @@ export class ActionBar {
|
||||
this.closeActions();
|
||||
}
|
||||
else {
|
||||
// if the action menu was opened from the settings dropdown, just do nothing
|
||||
// it means you can't close that menu by clicking on this button, but it's
|
||||
// a minor issue
|
||||
if (document.body.classList.contains('actions-modal-opened')) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isWaitingForActionsModal = true;
|
||||
this.modalRef = this.modalService.show(this.actionsModal, { ignoreBackdropClick: true });
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ export class ActionsModal implements OnInit, OnDestroy {
|
||||
this.game.editingActions = false;
|
||||
clearInterval(this.interval);
|
||||
this.subscription && this.subscription.unsubscribe();
|
||||
this.close.emit(); // need to emit in case the menu wasn't closed with the Close button
|
||||
this.notify.emit();
|
||||
}
|
||||
ok() {
|
||||
|
||||
@@ -92,8 +92,8 @@
|
||||
.form-group
|
||||
custom-checkbox(
|
||||
[(checked)]="account.filterCyrillic"
|
||||
help="Hide all messages containing russian alphabet")
|
||||
| Filter russian chat
|
||||
help="Hide all messages containing Russian alphabet")
|
||||
| Filter Russian chat
|
||||
.form-group
|
||||
custom-checkbox(
|
||||
[(checked)]="account.filterSwearWords"
|
||||
|
||||
@@ -112,6 +112,12 @@ ng-template(#shareLinkPopover)
|
||||
.form-group
|
||||
button.btn.btn-sm.ml-1([(ngModel)]="animation.loop" btnCheckbox [btnHighlight]="animation.loop")
|
||||
| loop
|
||||
.form-group(*ngIf="mode !== 'body'")
|
||||
button.btn.btn-sm.ml-1([(ngModel)]="animation.dontOpenEyes" btnCheckbox [btnHighlight]="animation.dontOpenEyes")
|
||||
| dontOpenEyes
|
||||
.form-group(*ngIf="mode !== 'body'")
|
||||
button.btn.btn-sm.ml-1([(ngModel)]="animation.dontCloseMouth" btnCheckbox [btnHighlight]="animation.dontCloseMouth")
|
||||
| dontCloseMouth
|
||||
.btn-group.ml-1(dropdown)
|
||||
button.btn.btn-sm.btn-default.dropdown-toggle(dropdownToggle title="Before animation")
|
||||
| before: {{beforeAnimation?.name || 'none'}}
|
||||
|
||||
@@ -7,9 +7,9 @@ import {
|
||||
BodyAnimationFrame as IBodyAnimationFrame,
|
||||
HeadAnimation as IHeadAnimation,
|
||||
HeadAnimationFrame as IHeadAnimationFrame,
|
||||
ColorExtraSet, PonyInfo, PonyObject, BodyShadow, PonyEye
|
||||
ColorExtraSet, PonyInfo, PonyObject, BodyShadow, PonyEye, HeadAnimationProperties
|
||||
} from '../../../common/interfaces';
|
||||
import { removeItem, repeat, isKeyEventInvalid, cloneDeep, array } from '../../../common/utils';
|
||||
import { removeItem, repeat, isKeyEventInvalid, cloneDeep, array, hasFlag } from '../../../common/utils';
|
||||
import { toPalette, createDefaultPony, syncLockedPonyInfo } from '../../../common/ponyInfo';
|
||||
import { Key } from '../../../client/input/input';
|
||||
import { defaultPonyState, defaultDrawPonyOptions } from '../../../client/ponyHelpers';
|
||||
@@ -63,6 +63,8 @@ interface BodyAnimation extends BaseAnimation {
|
||||
interface HeadAnimation extends BaseAnimation {
|
||||
lockEyes?: boolean;
|
||||
frames: HeadAnimationFrame[];
|
||||
dontOpenEyes?: boolean;
|
||||
dontCloseMouth?: boolean;
|
||||
}
|
||||
|
||||
interface AnimationsData {
|
||||
@@ -201,6 +203,13 @@ export class ToolsAnimation implements OnInit, OnDestroy {
|
||||
if (!this.playing) {
|
||||
if (this.mode === 'body') {
|
||||
this.state.animationFrame = this.frame;
|
||||
|
||||
if (this.state.headAnimation) {
|
||||
const headFrames = this.state.headAnimation.frames.length;
|
||||
let headFrame = Math.floor(this.frame / this.state.animation.frames.length * headFrames);
|
||||
headFrame = Math.min(headFrame, headFrames - 1);
|
||||
this.state.headAnimationFrame = headFrame;
|
||||
}
|
||||
} else {
|
||||
this.state.headAnimationFrame = this.frame;
|
||||
}
|
||||
@@ -459,9 +468,10 @@ export class ToolsAnimation implements OnInit, OnDestroy {
|
||||
console.log(`shadow: [${shadow.map(x => `[${x.join(', ')}]`).join(', ')}]`);
|
||||
}
|
||||
} else {
|
||||
const animation = toHeadAnimation(this.headAnimation, true);
|
||||
const compressed = animation.frames.map(compressHeadFrame);
|
||||
console.log(JSON.stringify(compressed));
|
||||
const frames = this.headAnimation.frames
|
||||
.map(f => [f.duration, '[' + compressHeadFrame(f).join(', ') + ']'])
|
||||
.map(([repeat, frame]) => repeat > 1 ? `...repeat(${repeat}, ${frame})` : frame);
|
||||
console.log(`frames: [\n${frames.map(x => `\t${x}`).join(',\n')}\n]`);
|
||||
}
|
||||
}
|
||||
png(scale = 1) {
|
||||
@@ -531,9 +541,11 @@ export class ToolsAnimation implements OnInit, OnDestroy {
|
||||
if (this.playing) {
|
||||
this.time += delta;
|
||||
|
||||
if (this.mode === 'body') {
|
||||
const isBodyMode = this.mode === 'body';
|
||||
|
||||
if (isBodyMode) {
|
||||
if (this.state.animation) {
|
||||
const frame = this.time * this.state.animation.fps;
|
||||
const frame = Math.floor(this.time * this.state.animation.fps);
|
||||
|
||||
if (frame > this.state.animation.frames.length && !this.state.animation.loop) {
|
||||
this.bodyAnimationPlaying = (this.bodyAnimationPlaying + 1) % this.bodyAnimationsToPlay.length;
|
||||
@@ -541,14 +553,15 @@ export class ToolsAnimation implements OnInit, OnDestroy {
|
||||
this.state.animationFrame = 0;
|
||||
this.time = 0;
|
||||
} else {
|
||||
this.state.animationFrame = Math.floor(frame) % this.state.animation.frames.length;
|
||||
this.state.animationFrame = frame % this.state.animation.frames.length;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this.state.headAnimation) {
|
||||
const frame = Math.floor(this.time * this.state.headAnimation.fps);
|
||||
this.state.headAnimationFrame = frame % this.state.headAnimation.frames.length;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state.headAnimation) {
|
||||
const fps = this.state.headAnimation.fps;
|
||||
const frame = Math.floor(this.time * fps) + (isBodyMode && !this.state.headAnimation.loop ? fps : 0);
|
||||
this.state.headAnimationFrame = frame % this.state.headAnimation.frames.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -564,9 +577,10 @@ export class ToolsAnimation implements OnInit, OnDestroy {
|
||||
return this.storage.getJSON<AnimationsData>('tools-animations', {});
|
||||
}
|
||||
private createAnimationSprites(scale: number) {
|
||||
const isBodyMode = this.mode === 'body';
|
||||
const animation = toBodyAnimation(this.bodyAnimation, true, this.switch);
|
||||
const headAnimation = toHeadAnimation(this.headAnimation, true);
|
||||
const frames = this.mode === 'body' ? animation.frames.length : headAnimation.frames.length;
|
||||
const frames = isBodyMode ? animation.frames.length : headAnimation.frames.length;
|
||||
const buffer = createCanvas(ponyWidth, ponyHeight);
|
||||
const batch = new ContextSpriteBatch(buffer);
|
||||
const info = toPalette(this.pony.info);
|
||||
@@ -582,14 +596,23 @@ export class ToolsAnimation implements OnInit, OnDestroy {
|
||||
const x = i % cols;
|
||||
const y = Math.floor(i / cols);
|
||||
|
||||
let headFrame = 0;
|
||||
if (isBodyMode) {
|
||||
let animTime = i / animation.fps;
|
||||
if (!headAnimation.loop) {
|
||||
animTime += 1;
|
||||
}
|
||||
headFrame = Math.floor(animTime * headAnimation.fps);
|
||||
}
|
||||
|
||||
batch.start(sprites.paletteSpriteSheet, 0);
|
||||
|
||||
drawPony(batch, info, {
|
||||
...defaultPonyState(),
|
||||
animation,
|
||||
animationFrame: this.mode === 'body' ? i : 0,
|
||||
headAnimation: this.mode === 'head' ? headAnimation : undefined,
|
||||
headAnimationFrame: this.mode === 'head' ? i : 0,
|
||||
animationFrame: isBodyMode ? i : 0,
|
||||
headAnimation: headAnimation,
|
||||
headAnimationFrame: isBodyMode ? headFrame : i,
|
||||
blinkFrame: 1,
|
||||
}, ponyWidth / 2, ponyHeight - 10, options);
|
||||
|
||||
@@ -696,7 +719,7 @@ function compressBodyFrame(f: BodyAnimationFrame): number[] {
|
||||
], x => !x);
|
||||
}
|
||||
|
||||
function fromHeadAnimation({ name, fps, loop, frames }: IHeadAnimation, index: number): HeadAnimation {
|
||||
function fromHeadAnimation({ name, fps, loop, properties, frames }: IHeadAnimation, index: number): HeadAnimation {
|
||||
const fs: HeadAnimationFrame[] = [];
|
||||
|
||||
frames.forEach(f => {
|
||||
@@ -713,18 +736,30 @@ function fromHeadAnimation({ name, fps, loop, frames }: IHeadAnimation, index: n
|
||||
builtin: true,
|
||||
fps,
|
||||
loop,
|
||||
dontOpenEyes: hasFlag(properties, HeadAnimationProperties.DontIncreaseEyeOpenness),
|
||||
dontCloseMouth: hasFlag(properties, HeadAnimationProperties.DontDecreaseMouthOpenness),
|
||||
name: `# builtin ${index.toString().padStart(2, '0')} # ${name}`,
|
||||
frames: fs,
|
||||
};
|
||||
}
|
||||
|
||||
function toHeadAnimation({ name, frames, fps, loop }: HeadAnimation, full: boolean): IHeadAnimation {
|
||||
function toHeadAnimation({ name, frames, fps, loop, dontOpenEyes, dontCloseMouth }: HeadAnimation, full: boolean):
|
||||
IHeadAnimation {
|
||||
const fs = (full && !loop) ? repeat(fps, createDefaultHeadFrame()).concat(frames) : frames;
|
||||
|
||||
let properties = HeadAnimationProperties.None;
|
||||
if (dontOpenEyes) {
|
||||
properties |= HeadAnimationProperties.DontIncreaseEyeOpenness;
|
||||
}
|
||||
if (dontCloseMouth) {
|
||||
properties |= HeadAnimationProperties.DontDecreaseMouthOpenness;
|
||||
}
|
||||
|
||||
return {
|
||||
name,
|
||||
fps,
|
||||
loop,
|
||||
properties,
|
||||
frames: flatMap(fs, f => repeat(full ? f.duration : 1, f)),
|
||||
};
|
||||
}
|
||||
@@ -788,6 +823,7 @@ function fixHeadAnimation(a: HeadAnimation): HeadAnimation {
|
||||
fps: a.fps || 24,
|
||||
loop: a.loop || false,
|
||||
lockEyes: a.lockEyes || false,
|
||||
dontOpenEyes: a.dontOpenEyes || false,
|
||||
frames: (a.frames || []).map(fixHeadFrame),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import { createCamera } from '../../../common/camera';
|
||||
import { mockPaletteManager } from '../../../common/ponyInfo';
|
||||
import { isCritter } from '../../../common/entityUtils';
|
||||
import {
|
||||
createAnEntity, cloud, pony, apple, apple2, orange, orange2, candy, gift1, gift2, appleGreen, appleGreen2
|
||||
createAnEntity, cloud, pony, apple, apple2, orange, orange2, candy, gift1, gift2, appleGreen, appleGreen2, bunny
|
||||
} from '../../../common/entities';
|
||||
import { drawMap } from '../../../client/draw';
|
||||
import { includes, observableToPromise, hasFlag } from '../../../common/utils';
|
||||
@@ -141,7 +141,7 @@ function drawTheMap(canvas: HTMLCanvasElement, map: WorldMap, info: ToolsMapOthe
|
||||
};
|
||||
|
||||
const ignoreTypes = [
|
||||
cloud, pony, apple, apple2, appleGreen, appleGreen2, orange, orange2, candy, gift1, gift2
|
||||
cloud, pony, apple, apple2, appleGreen, appleGreen2, orange, orange2, candy, gift1, gift2, bunny
|
||||
].map(e => e.type);
|
||||
|
||||
const shouldDraw = (e: Entity) => {
|
||||
|
||||
Reference in New Issue
Block a user