mirror of
https://github.com/Terncode/pixel.horse.git
synced 2026-09-24 21:55:52 +02:00
Merge remote-tracking branch 'upstream/archive' into archive-update-v0.55.0
This commit is contained in:
@@ -2,7 +2,7 @@ import { compact } from 'lodash';
|
||||
import {
|
||||
Expression, ExpressionButtonAction, CommandButtonAction, ActionButtonAction, ItemButtonAction,
|
||||
ColorShadow, Eye, Muzzle, Iris, ButtonActionSlot, ExpressionExtra, ButtonAction, ChatType, BodyAnimation,
|
||||
Action, isPartyChat, EntityButtonAction, defaultDrawOptions
|
||||
Action, isPartyChat, EntityButtonAction, defaultDrawOptions, HeadAnimationProperties
|
||||
} from '../common/interfaces';
|
||||
import * as sprites from '../generated/sprites';
|
||||
import { createExpression } from './clientUtils';
|
||||
@@ -11,7 +11,7 @@ import { PonyTownGame } from './game';
|
||||
import { boopAction, upAction, downAction, turnHeadAction } from './playerActions';
|
||||
import { ACTIONS_LIMIT, COMMAND_ACTION_TIME_DELAY } from '../common/constants';
|
||||
import { cloneDeep, hasFlag } from '../common/utils';
|
||||
import { boop, defaultHeadFrame, stand, sneeze, yawn, lie, sit, fly, laugh, excite } from './ponyAnimations';
|
||||
import { boop, defaultHeadFrame, stand, sneeze, yawn, lie, sit, fly, laugh, kiss, excite } from './ponyAnimations';
|
||||
import { createDefaultPony, syncLockedPonyInfo, toPalette, mockPaletteManager } from '../common/ponyInfo';
|
||||
import {
|
||||
ACTION_EXPRESSION_EYE_COLOR, ACTION_EXPRESSION_BG, ACTION_ACTION_COAT_COLOR, WHITE, HEARTS_COLOR,
|
||||
@@ -118,10 +118,7 @@ const actionActions = [
|
||||
actionButtonAction('drop', 'Drop item', Action.Drop),
|
||||
actionButtonAction('drop-toy', 'Drop toy', Action.DropToy),
|
||||
actionButtonAction('magic', 'Magic', Action.Magic),
|
||||
actionButtonAction('switch-tool', 'Switch tool', Action.SwitchTool),
|
||||
actionButtonAction('switch-entity', 'Switch item to place'),
|
||||
actionButtonAction('switch-entity-rev', 'Switch item to place (reverse)'),
|
||||
actionButtonAction('switch-tile', 'Switch tile to place'),
|
||||
actionButtonAction('kiss', 'Kiss', Action.Kiss),
|
||||
];
|
||||
|
||||
const commandActions = [
|
||||
@@ -395,7 +392,8 @@ export function drawAction(canvas: HTMLCanvasElement, action: ButtonAction | und
|
||||
const buffer = drawCanvas(bufferSize, bufferSize, sprites.paletteSpriteSheet, undefined, batch => {
|
||||
const state = { ...createState(), expression: action.expression };
|
||||
const options = { ...defaultDrawPonyOptions(), noEars: true };
|
||||
drawHead(batch, expressionPony, headX, headY, undefined, defaultHeadFrame, state, options, false, 0);
|
||||
drawHead(batch, expressionPony, headX, headY, undefined,
|
||||
defaultHeadFrame, HeadAnimationProperties.None, state, options, false, 0);
|
||||
|
||||
if (action.expression) {
|
||||
const extra = action.expression.extra;
|
||||
@@ -525,6 +523,11 @@ export function drawAction(canvas: HTMLCanvasElement, action: ButtonAction | und
|
||||
batch.drawSprite(sprites.magic_icon, WHITE, defaultPalette, 4, 2);
|
||||
break;
|
||||
}
|
||||
case 'kiss': {
|
||||
const state = { ...createState(), headAnimation: kiss, headAnimationFrame: 9 };
|
||||
drawPony(batch, actionPony, state, 17, 40, defaultDrawPonyOptions());
|
||||
break;
|
||||
}
|
||||
case 'switch-tool': {
|
||||
const palette = mockPaletteManager.addArray(sprites.tools_icon.palettes![0]);
|
||||
batch.drawSprite(sprites.tools_icon.color, WHITE, palette, 0, 2);
|
||||
|
||||
@@ -91,6 +91,7 @@ export const CONTRIBUTORS: Contributors[] = [
|
||||
group: 'Programmers',
|
||||
contributors: [
|
||||
{ name: 'Industrialice' },
|
||||
{ name: 'Stubenhocker', links: ['https://twitter.com/Stubenhocker13'] },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -129,6 +130,7 @@ export const CONTRIBUTORS: Contributors[] = [
|
||||
{ name: 'Deeraw', links: ['https://www.deviantart.com/deerdraw', 'https://twitter.com/TheOnlyDeeraw'] },
|
||||
{ name: 'Aviivix' },
|
||||
{ name: 'SnowFl8keAnge1' },
|
||||
{ name: '3aHo3a', links: ['http://twitter.com/imnuclearimwild'] },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -14,7 +14,8 @@ import { getPonyState, setPonyState, isPonyFlying, addChatBubble, isHidden } fro
|
||||
import {
|
||||
isPony, createPony, setPonyExpression, updatePonyInfo, updatePonyHold, doPonyAction, hasHeadAnimation,
|
||||
setHeadAnimation,
|
||||
doBoopPonyAction
|
||||
doBoopPonyAction,
|
||||
isPonyBug
|
||||
} from '../common/pony';
|
||||
import { PonyTownGame } from './game';
|
||||
import { setupPlayer, savePlayerPosition } from './sec';
|
||||
@@ -25,7 +26,7 @@ import { decodeUpdate, readOneUpdate } from '../common/encoders/updateDecoder';
|
||||
import { updateEntityVelocity } from '../common/entityUtils';
|
||||
import { decodePonyInfo } from '../common/compressPony';
|
||||
import { mockPaletteManager } from '../common/ponyInfo';
|
||||
import { yawn, laugh, sneeze, excite } from './ponyAnimations';
|
||||
import { yawn, laugh, sneeze, kiss, kissFly, kissFlyBug, excite } from './ponyAnimations';
|
||||
import {
|
||||
findEntityById, getRegionGlobal, setTile, removeEntity, addEntity, removeEntityDirectly, setRegion,
|
||||
addEntityToMapRegion, switchEntityRegion, getRegionUnsafe, addOrRemoveFromEntityList,
|
||||
@@ -420,6 +421,22 @@ export function handleAction(game: PonyTownGame, id: number, action: Action) {
|
||||
setHeadAnimation(pony, excite);
|
||||
}
|
||||
break;
|
||||
case Action.Kiss:
|
||||
if (!pony.ponyState.headTurned) {
|
||||
doPonyAction(pony, DoAction.Kiss);
|
||||
}
|
||||
if (isPonyFlying(pony)) {
|
||||
if (isPonyBug(pony)) {
|
||||
setHeadAnimation(pony, kissFlyBug);
|
||||
}
|
||||
else {
|
||||
setHeadAnimation(pony, kissFly);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setHeadAnimation(pony, kiss);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
log(`handleAction: Invalid action: ${action}`);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BodyAnimation, BodyAnimationFrame, HeadAnimation, HeadAnimationFrame, BodyShadow } from '../common/interfaces';
|
||||
import { BodyAnimation, BodyAnimationFrame, HeadAnimation, HeadAnimationFrame, BodyShadow, HeadAnimationProperties } from '../common/interfaces';
|
||||
import { repeat, flatten } from '../common/utils';
|
||||
|
||||
// body animations
|
||||
@@ -23,7 +23,7 @@ export function createBodyAnimation(
|
||||
name: string, fps: number, loop: boolean, frames: number[][], shadowOffsets?: number[][]
|
||||
): Readonly<BodyAnimation> {
|
||||
if (shadowOffsets && shadowOffsets.length !== frames.length) {
|
||||
throw new Error(`Incorrect frame count for shadowOffsets for ${name}`);
|
||||
throw new Error(`Incorrect frame count for shadowOffsets for ${name}, animation frames ${frames.length}, shadow frames ${shadowOffsets.length}`);
|
||||
}
|
||||
|
||||
const shadow = shadowOffsets && shadowOffsets.map<BodyShadow>(([frame, offset]) => ({ frame, offset }));
|
||||
@@ -459,14 +459,163 @@ export const swing = createBodyAnimation('swing', 12, false, [
|
||||
...repeat(3, [2, 1, 0, 0, 12, 17, 11, 11, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1]),
|
||||
]);
|
||||
|
||||
export const flyAnims = [undefined, fly, fly, fly, flyBug];
|
||||
export const kissBody = createBodyAnimation('kiss-body', 24, false, [
|
||||
...repeat(3, [2, 1, 0, 0, 1, 1, 1, 1, -1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]),
|
||||
[2, 1, 1, 0, 28, 28, 18, 18, -2, 0, -1, 1, 1, 0, 1, 0, 1, 0, 1],
|
||||
[2, 1, 1, 0, 26, 26, 19, 19, -3, 0, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1],
|
||||
...repeat(2, [5, 1, 1, 0, 26, 26, 19, 19, -10, -6, 1, 0, 1, 1, 1, 1, 1, -1, 1, -1]),
|
||||
...repeat(60, [5, 1, 1, 0, 27, 27, 20, 20, -11, -6, 1, 0, 1, 1, 1, 1, 1, -1, 1, -1]),
|
||||
...repeat(2, [5, 1, 1, 0, 26, 26, 19, 19, -10, -6, 1, 0, 1, 1, 1, 1, 1, -1, 1, -1]),
|
||||
[5, 1, 1, 0, 28, 28, 18, 18, -9, -5, 1, 0, 1, 1, 1, 1, 1, -1, 1, -1],
|
||||
...repeat(2, [2, 1, 1, 0, 1, 1, 1, 1, -1, 0, -1, 1, 1, 0, 1, 0, 1, 0, 1])
|
||||
]);
|
||||
|
||||
export const kissLiftHoofBody = createBodyAnimation('kiss-lift-hoof-body', 24, false, [
|
||||
...repeat(3, [2, 1, 0, 0, 1, 1, 1, 1, -1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1]),
|
||||
[2, 1, 1, 0, 28, 28, 18, 18, -2, 0, -1, 1, 1, 0, 1, 0, 1, 0, 1],
|
||||
[2, 1, 1, 0, 27, 26, 19, 19, -3, 0, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1],
|
||||
...repeat(2, [5, 1, 1, 0, 8, 26, 19, 19, -10, -6, 1, 0, 1, 2, 1, 1, 1, -1, 1, -1]),
|
||||
...repeat(60, [5, 1, 1, 0, 8, 27, 20, 20, -11, -6, 1, 0, 1, 1, 1, 1, 1, -1, 1, -1]),
|
||||
...repeat(2, [5, 1, 1, 0, 8, 26, 19, 19, -10, -6, 1, 0, 1, 2, 1, 1, 1, -1, 1, -1]),
|
||||
[5, 1, 1, 0, 28, 28, 18, 18, -9, -5, 1, 0, 1, 1, 1, 1, 1, -1, 1, -1],
|
||||
...repeat(2, [2, 1, 1, 0, 1, 1, 1, 1, -1, 0, -1, 1, 1, 0, 1, 0, 1, 0, 1])
|
||||
]);
|
||||
|
||||
export const kissFlyBody = createBodyAnimation('kiss-fly-body', 16, false, [
|
||||
[1, 1, 3, 0, 8, 10, 6, 5, 0, -16],
|
||||
[1, 1, 4, 0, 8, 10, 6, 5, 0, -15],
|
||||
[1, 1, 5, 0, 8, 10, 6, 5, 0, -14],
|
||||
[1, 1, 6, 0, 8, 10, 6, 5, 0, -14],
|
||||
[1, 1, 7, 0, 8, 10, 6, 5, -1, -15],
|
||||
[1, 1, 8, 0, 9, 10, 5, 5, -1, -17, -1],
|
||||
[1, 1, 9, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 10, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 11, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 12, 0, 9, 10, 4, 4, -1, -17, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 3, 0, 9, 10, 4, 4, -1, -16, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -15, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 5, 0, 9, 10, 4, 4, -1, -14, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 6, 0, 9, 10, 4, 4, -1, -14, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 7, 0, 9, 10, 4, 4, -1, -15, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 8, 0, 9, 10, 4, 4, -1, -17, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 9, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 10, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 11, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 12, 0, 9, 10, 4, 4, -1, -17, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 3, 0, 9, 10, 4, 4, -1, -16, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -15, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 5, 0, 9, 10, 4, 4, -1, -14, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 6, 0, 9, 10, 4, 4, -1, -14, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 7, 0, 9, 10, 4, 4, -1, -15, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 8, 0, 9, 10, 4, 4, -1, -17, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 9, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 10, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 11, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 12, 0, 9, 10, 4, 4, 0, -17, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 3, 0, 8, 10, 5, 4, 0, -16, 0, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 8, 10, 6, 5, 0, -15]
|
||||
]);
|
||||
|
||||
export const kissFlyBugBody = createBodyAnimation('kiss-fly-bug-body', 24, false, [
|
||||
[1, 1, 3, 0, 8, 10, 6, 5, 0, -16],
|
||||
[1, 1, 4, 0, 8, 10, 6, 5, 0, -16],
|
||||
[1, 1, 5, 0, 8, 10, 6, 5, 0, -15],
|
||||
[1, 1, 4, 0, 8, 10, 6, 5, 0, -15],
|
||||
[1, 1, 3, 0, 8, 10, 6, 5, -1, -14],
|
||||
[1, 1, 4, 0, 9, 10, 5, 5, -1, -14],
|
||||
[1, 1, 5, 0, 9, 10, 4, 4, -1, -14, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -14, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 3, 0, 9, 10, 4, 4, -1, -15, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -15, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 5, 0, 9, 10, 4, 4, -1, -16, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -17, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 3, 0, 9, 10, 4, 4, -1, -17, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 5, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 3, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -17, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 5, 0, 9, 10, 4, 4, -1, -17, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -17, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 3, 0, 9, 10, 4, 4, -1, -16, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -16, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 5, 0, 9, 10, 4, 4, -1, -15, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -15, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 3, 0, 9, 10, 4, 4, -1, -14, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -14, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 5, 0, 9, 10, 4, 4, -1, -14, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -14, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 3, 0, 9, 10, 4, 4, -1, -15, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -15, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 5, 0, 9, 10, 4, 4, -1, -16, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -17, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 3, 0, 9, 10, 4, 4, -1, -17, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 5, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 3, 0, 9, 10, 4, 4, -1, -18, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 9, 10, 4, 4, 0, -17, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 5, 0, 8, 10, 5, 4, 0, -17, 0, 0, 0, 0, 0, -1],
|
||||
[1, 1, 4, 0, 8, 10, 6, 5, 0, -17]
|
||||
]);
|
||||
|
||||
export const kissLieBody = createBodyAnimation('kiss-lie-body', 24, false, [
|
||||
...repeat(3, [14, 1, 0, 2, 38, 38, 26, 26]),
|
||||
...repeat(2, [15, 1, 0, 2, 38, 38, 26, 26]),
|
||||
[13, 1, 0, 2, 38, 38, 26, 26, 0, 0, -1],
|
||||
...repeat(2, [13, 1, 0, 2, 38, 38, 26, 26, -1, 0, -1, 0, 1, 0, 1, 0, 1, 0, 1]),
|
||||
...repeat(57, [13, 1, 0, 2, 38, 38, 26, 26, -1, 0, -2, 0, 1, 0, 1, 0, 1, 0, 1]),
|
||||
...repeat(2, [13, 1, 0, 2, 38, 38, 26, 26, 0, 0, -2]),
|
||||
[13, 1, 0, 2, 38, 38, 26, 26, 0, 0, -1],
|
||||
...repeat(2, [14, 1, 0, 2, 38, 38, 26, 26, 0, 0, -1]),
|
||||
...repeat(2, [14, 1, 0, 2, 38, 38, 26, 26])
|
||||
], [...repeat(72, [3, 3])]);
|
||||
|
||||
export const kissSitBody = createBodyAnimation('kiss-sit-body', 24, false, [
|
||||
...repeat(3, [8, 1, 2, 2, 34, 34, 25, 25]),
|
||||
...repeat(2, [9, 1, 2, 2, 34, 34, 26, 26]),
|
||||
[9, 1, 2, 2, 34, 34, 26, 26, 0, -1, -1, 0, 0, 1, 0, 1, 0, 1, 0, 1],
|
||||
...repeat(2, [9, 1, 2, 2, 39, 39, 26, 26, -1, -1, -1, 0, 0, 1, 0, 1, 1, 1, 1, 1]),
|
||||
...repeat(60, [9, 1, 2, 2, 39, 39, 26, 26, -1, -1, -2, 0, 0, 1, 0, 1, 1, 1, 1, 1]),
|
||||
...repeat(2, [9, 1, 2, 2, 34, 34, 26, 26, 0, -1, -2, 0, 0, 1, 0, 1, 0, 1, 0, 1]),
|
||||
...repeat(2, [9, 1, 2, 2, 34, 34, 26, 26, 0, 0, -1])
|
||||
], [...repeat(72, [0, 6])]);
|
||||
|
||||
export const kissSwimBody = createBodyAnimation('kiss-swim-body', 8, false, [
|
||||
...repeat(2, [1, 1, 0, 0, 8, 10, 6, 5, 0, 14]),
|
||||
[1, 1, 0, 0, 9, 10, 5, 5, -1, 13],
|
||||
[1, 1, 0, 0, 9, 10, 4, 4, -1, 13, -1, 0, 0, 0, 0, -1],
|
||||
...repeat(2, [1, 1, 0, 0, 9, 10, 4, 4, -1, 12, -1, 0, 0, 0, 0, -1]),
|
||||
...repeat(2, [1, 1, 0, 0, 9, 10, 4, 4, -1, 13, -1, 0, 0, 0, 0, -1]),
|
||||
...repeat(2, [1, 1, 0, 0, 9, 10, 4, 4, -1, 14, -1, 0, 0, 0, 0, -1]),
|
||||
...repeat(2, [1, 1, 0, 0, 9, 10, 4, 4, -1, 13, -1, 0, 0, 0, 0, -1]),
|
||||
...repeat(2, [1, 1, 0, 0, 9, 10, 4, 4, -1, 12, -1, 0, 0, 0, 0, -1]),
|
||||
...repeat(2, [1, 1, 0, 0, 9, 10, 4, 4, -1, 13, -1, 0, 0, 0, 0, -1]),
|
||||
...repeat(2, [1, 1, 0, 0, 9, 10, 4, 4, -1, 14, -1, 0, 0, 0, 0, -1]),
|
||||
...repeat(2, [1, 1, 0, 0, 9, 10, 4, 4, -1, 13, -1, 0, 0, 0, 0, -1]),
|
||||
...repeat(2, [1, 1, 0, 0, 9, 10, 4, 4, -1, 12, -1, 0, 0, 0, 0, -1]),
|
||||
[1, 1, 0, 0, 8, 10, 4, 4, 0, 13, -1, 0, 0, 0, 0, -1],
|
||||
[1, 1, 0, 0, 8, 10, 5, 5, 0, 13]
|
||||
]);
|
||||
|
||||
export const kissToTrot = createBodyAnimation('kiss-to-trot-body', 24, false, [
|
||||
[2, 1, 0, 0, 8, 4, 19, 4, -1, 0, -1, 1, 0, 0, 0, 0, 1, -1],
|
||||
[1, 1, 0, 0, 12, 5, 13, 5, 0, -2],
|
||||
[1, 1, 0, 0, 14, 6, 14, 6, 0, -2],
|
||||
[1, 1, 0, 0, 15, 7, 15, 7, 0, -2],
|
||||
[1, 1, 0, 0, 16, 8, 16, 8, 0, -1],
|
||||
[1, 1, 0, 0, 17, 9, 17, 9]
|
||||
]);
|
||||
|
||||
export const flyAnims = [undefined, fly, fly, fly, flyBug, kissFlyBody, kissFlyBugBody];
|
||||
export const flyUpAnims = [undefined, flyUp, flyUp, flyUp, flyUpBug];
|
||||
export const flyDownAnims = [undefined, flyDown, flyDown, flyDown, flyDownBug];
|
||||
|
||||
export const animations = [
|
||||
stand, trot, boop, boopSit, boopLie, boopSwim, boopFly, boopFlyBug, sit, sitDown, standUp, lie, lieDown, sitUp,
|
||||
fly, flyBug, flyUp, flyUpBug, flyDown, flyDownBug, sitToTrot, lieToTrot, flyToTrot, flyToTrotBug,
|
||||
swim, trotToSwim, swimToTrot, flyToSwim, swimToFly,
|
||||
swim, trotToSwim, swimToTrot, flyToSwim, swimToFly, kissBody, kissLiftHoofBody, kissFlyBody, kissFlyBugBody, kissLieBody,
|
||||
kissSitBody, kissSwimBody, kissToTrot
|
||||
];
|
||||
|
||||
export const sitDownUp = mergeAnimations('sit', 24, false, [...repeat(12, stand), sitDown, ...repeat(12, sit), standUp]);
|
||||
@@ -488,8 +637,12 @@ export function createHeadFrame([headX = 0, headY = 0, left = 0, right = 0, mout
|
||||
return { headX, headY, left, right, mouth };
|
||||
}
|
||||
|
||||
export function createHeadAnimation(name: string, fps: number, loop: boolean, frames: number[][]): HeadAnimation {
|
||||
return { name, fps, loop, frames: frames.map(createHeadFrame) };
|
||||
export function createHeadAnimation(name: string, fps: number, loop: boolean, frames: number[][],
|
||||
properties?: HeadAnimationProperties): HeadAnimation {
|
||||
if (!properties) {
|
||||
properties = HeadAnimationProperties.None;
|
||||
}
|
||||
return { name, fps, loop, properties, frames: frames.map(createHeadFrame) };
|
||||
}
|
||||
|
||||
export const smile = createHeadAnimation('smile', 24, true, [
|
||||
@@ -510,7 +663,7 @@ export const yawn = createHeadAnimation('yawn', 12, false, [
|
||||
...repeat(18, [1, -1, 12, 12, 16]),
|
||||
...repeat(8, [0, 0, 12, 12, 12]),
|
||||
[0, 0, 18, 18, 2],
|
||||
]);
|
||||
], HeadAnimationProperties.DontIncreaseEyeOpenness);
|
||||
|
||||
export const surprise = createHeadAnimation('surprise', 8, false, [
|
||||
[0, 1, 6, 6, 1],
|
||||
@@ -538,7 +691,7 @@ export const sneeze = createHeadAnimation('sneeze', 12, false, [
|
||||
...repeat(2, [1, -1, 18, 18, 16]),
|
||||
...repeat(8, [-1, 1, 23, 23, 13]),
|
||||
...repeat(4, [0, 0, 18, 18, 7]),
|
||||
]);
|
||||
], HeadAnimationProperties.DontIncreaseEyeOpenness);
|
||||
|
||||
export const happy_tongue = createHeadAnimation('happy_tongue', 12, false, [
|
||||
...repeat(3, [0, 0, 1, 1, 0]),
|
||||
@@ -558,8 +711,32 @@ export const happy_tongue_meno_2 = createHeadAnimation('happy_tongue_meno_2', 12
|
||||
...repeat(8, [0, 0, 11, 11, 4]),
|
||||
]);
|
||||
|
||||
export const kiss = createHeadAnimation('kiss', 24, false, [
|
||||
...repeat(2, [0, 0, 1, 1, 0]),
|
||||
...repeat(2, [0, 0, 3, 3, 0]),
|
||||
...repeat(63, [0, 0, 6, 6, 13]),
|
||||
[0, 0, 3, 3, 17],
|
||||
[0, 0, 1, 1, 0]
|
||||
], HeadAnimationProperties.DontIncreaseEyeOpenness);
|
||||
|
||||
export const kissFly = createHeadAnimation('kiss-fly', 24, false, [
|
||||
...repeat(2, [0, 0, 1, 1, 0]),
|
||||
...repeat(2, [0, 0, 3, 3, 0]),
|
||||
...repeat(38, [0, 0, 6, 6, 13]),
|
||||
[0, 0, 3, 3, 17],
|
||||
[0, 0, 1, 1, 0]
|
||||
], HeadAnimationProperties.DontIncreaseEyeOpenness);
|
||||
|
||||
export const kissFlyBug = createHeadAnimation('kiss-fly-bug', 24, false, [
|
||||
...repeat(2, [0, 0, 1, 1, 0]),
|
||||
...repeat(2, [0, 0, 3, 3, 0]),
|
||||
...repeat(35, [0, 0, 6, 6, 13]),
|
||||
[0, 0, 3, 3, 17],
|
||||
[0, 0, 1, 1, 0]
|
||||
], HeadAnimationProperties.DontIncreaseEyeOpenness);
|
||||
|
||||
export const headAnimations = [
|
||||
smile, nom, laugh, yawn, surprise, surpriseSad, sneeze, excite,
|
||||
smile, nom, laugh, yawn, surprise, surpriseSad, sneeze, excite, kiss, kissFly, kissFlyBug
|
||||
];
|
||||
|
||||
// default animations
|
||||
|
||||
+44
-17
@@ -1,7 +1,8 @@
|
||||
import {
|
||||
PonyEye, PonyState, PalettePonyInfo, PaletteSpriteSet, Palette, HeadAnimationFrame,
|
||||
Eye, Iris, ColorExtraSets, ExpressionExtra, BodyAnimationFrame, DrawPonyOptions, Muzzle, BodyShadow, DrawOptions,
|
||||
NoDraw, PaletteSpriteBatch, defaultDrawOptions, PonyStateFlags, PaletteManager, isEyeSleeping, Matrix2D,
|
||||
NoDraw, PaletteSpriteBatch, defaultDrawOptions, PonyStateFlags, PaletteManager, Matrix2D, HeadAnimationProperties,
|
||||
getEyeOpenness, Expression, getMuzzleOpenness,
|
||||
} from '../common/interfaces';
|
||||
import { WHITE, SHINES_COLOR, FAR_COLOR, TRANSPARENT, fillToOutlineColor } from '../common/colors';
|
||||
import { toInt, hasFlag, repeat, flatten, point } from '../common/utils';
|
||||
@@ -232,6 +233,7 @@ function getWakeIndex(info: Info) {
|
||||
export function drawPony(batch: Batch, info: Info, state: State, ponyX: number, ponyY: number, options: Options) {
|
||||
const frame = getPonyAnimationFrame(state.animation, state.animationFrame, defaultBodyFrame);
|
||||
const headFrame = getPonyAnimationFrame(state.headAnimation || defaultHeadAnimation, state.headAnimationFrame, defaultHeadFrame);
|
||||
const headAnimationProperties = (state.headAnimation || defaultHeadAnimation).properties;
|
||||
const baseX = ponyX - PONY_WIDTH / 2;
|
||||
const baseY = ponyY - PONY_HEIGHT;
|
||||
const x = baseX + frame.bodyX;
|
||||
@@ -502,7 +504,7 @@ export function drawPony(batch: Batch, info: Info, state: State, ponyX: number,
|
||||
drawSet(batch, sprites.behindManes, info.mane, 0, maneBehindOffsetY, WHITE);
|
||||
}
|
||||
|
||||
drawHead(batch, info, 0, 0, headSprite, headFrame, state, options, headFlip, maneOffsetY);
|
||||
drawHead(batch, info, 0, 0, headSprite, headFrame, headAnimationProperties, state, options, headFlip, maneOffsetY);
|
||||
drawSet(batch, sprites.headAccessories, info.headAccessory, hatOffset.x, hatOffset.y + hatOffsetY, WHITE);
|
||||
|
||||
batch.restore();
|
||||
@@ -514,7 +516,7 @@ export function drawPony(batch: Batch, info: Info, state: State, ponyX: number,
|
||||
|
||||
export function drawHead(
|
||||
batch: Batch, info: Info, x: number, y: number, headSprites: ColorExtraSets, headFrame: HeadAnimationFrame,
|
||||
{ blinkFrame, expression, holding, blushColor, drawFaceExtra }: State,
|
||||
animationProperties: HeadAnimationProperties, { blinkFrame, expression, holding, blushColor, drawFaceExtra }: State,
|
||||
options: Options, flip: boolean, maneOffsetY: number,
|
||||
) {
|
||||
const extraOffset = at(EXTRA_ACCESSORY_OFFSETS, info.mane && info.mane.type) || pointZero;
|
||||
@@ -550,18 +552,18 @@ export function drawHead(
|
||||
|
||||
// make sure eyes are closed if sleeping
|
||||
if (hasFlag(expression.extra, ExpressionExtra.Zzz)) {
|
||||
if (!isEyeSleeping(eyeLeftBase)) {
|
||||
if (getEyeOpenness(eyeLeftBase) !== 0) {
|
||||
eyeLeftBase = Eye.Closed;
|
||||
}
|
||||
|
||||
if (!isEyeSleeping(eyeRightBase)) {
|
||||
if (getEyeOpenness(eyeRightBase) !== 0) {
|
||||
eyeRightBase = Eye.Closed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const eyeRight = getEyeFrame(info.eyeOpennessRight || 1, eyeRightBase, headFrame.right, blinkFrame);
|
||||
const eyeLeft = getEyeFrame(info.eyeOpennessLeft || 1, eyeLeftBase, headFrame.left, blinkFrame);
|
||||
const eyeRight = getEyeFrame(info.eyeOpennessRight || 1, eyeRightBase, headFrame.right, animationProperties, blinkFrame);
|
||||
const eyeLeft = getEyeFrame(info.eyeOpennessLeft || 1, eyeLeftBase, headFrame.left, animationProperties, blinkFrame);
|
||||
const eyeFrameLeft = flip ? eyeRight : eyeLeft;
|
||||
const eyeFrameRight = flip ? eyeLeft : eyeRight;
|
||||
const eyeColorLeft = flip ? info.eyeColorRight : info.eyeColorLeft;
|
||||
@@ -613,12 +615,7 @@ export function drawHead(
|
||||
}
|
||||
|
||||
if (draw(options, NoDraw.Body) && draw(options, NoDraw.Nose)) {
|
||||
const muzzle = holding ?
|
||||
Muzzle.Smile :
|
||||
headFrame.mouth === -1 ?
|
||||
(expression ? expression.muzzle : info.muzzle) :
|
||||
headFrame.mouth;
|
||||
|
||||
const muzzle = getMouthFrame(!!holding, expression, headFrame.mouth, info.muzzle, animationProperties);
|
||||
const noses = at(sprites.noses, muzzle);
|
||||
const nose = att(noses, info.nose && info.nose.type)![0];
|
||||
|
||||
@@ -723,11 +720,18 @@ function drawLeg(
|
||||
}
|
||||
}
|
||||
|
||||
function getEyeFrame(base: Eye, expression: Eye, anim: Eye, blinkFrame: number) {
|
||||
if (anim !== -1)
|
||||
return anim;
|
||||
|
||||
function getEyeFrame(base: Eye, expression: Eye, anim: Eye, animationProperties: HeadAnimationProperties, blinkFrame: number) {
|
||||
const frame = expression === -1 ? base : expression;
|
||||
|
||||
if (anim !== -1) {
|
||||
if (hasFlag(animationProperties, HeadAnimationProperties.DontIncreaseEyeOpenness)) {
|
||||
if (getEyeOpenness(anim) > getEyeOpenness(frame)) {
|
||||
return frame;
|
||||
}
|
||||
}
|
||||
return anim;
|
||||
}
|
||||
|
||||
const blink = blinkFrames[frame];
|
||||
|
||||
if (blinkFrame > 1 && blink) {
|
||||
@@ -741,6 +745,29 @@ function getEyeFrame(base: Eye, expression: Eye, anim: Eye, blinkFrame: number)
|
||||
return frame;
|
||||
}
|
||||
|
||||
function getMouthFrame(holding: boolean, expression: Expression | undefined, headFrameMuzzle: Muzzle,
|
||||
currentMuzzle: Muzzle | undefined, properties: HeadAnimationProperties) {
|
||||
if (holding) {
|
||||
return Muzzle.Smile;
|
||||
}
|
||||
|
||||
let applyMuzzle = currentMuzzle;
|
||||
if (expression) {
|
||||
applyMuzzle = expression.muzzle;
|
||||
}
|
||||
|
||||
if (headFrameMuzzle !== -1) {
|
||||
if (applyMuzzle && hasFlag(properties, HeadAnimationProperties.DontDecreaseMouthOpenness)) {
|
||||
if (getMuzzleOpenness(headFrameMuzzle) < getMuzzleOpenness(applyMuzzle)) {
|
||||
return applyMuzzle;
|
||||
}
|
||||
}
|
||||
return headFrameMuzzle;
|
||||
}
|
||||
|
||||
return applyMuzzle;
|
||||
}
|
||||
|
||||
function drawEye(
|
||||
batch: Batch, eye: PonyEye | undefined, iris: Iris, info: Info, palette: Palette | undefined, eyePalette: Palette,
|
||||
x: number, y: number
|
||||
|
||||
@@ -2,7 +2,8 @@ import { animatorState as state, animatorTransition as transition, anyState, Ani
|
||||
import {
|
||||
stand, sit, sitDown, standUp, lie, lieDown, sitUp, flyBug, fly, flyUp, flyDown, flyUpBug, flyDownBug,
|
||||
trot, boop, boopSit, swim, sitToTrot, lieToTrot, boopLie, trotToFly, trotToFlyBug, boopFly, boopFlyBug,
|
||||
flyToTrot, flyToTrotBug, swing, swimToTrot, trotToSwim, swimToFly, flyToSwim, boopSwim, swimToFlyBug, flyToSwimBug
|
||||
flyToTrot, flyToTrotBug, swing, swimToTrot, trotToSwim, swimToFly, flyToSwim, boopSwim, swimToFlyBug, flyToSwimBug,
|
||||
kissBody, kissLiftHoofBody, kissFlyBody, kissFlyBugBody, kissLieBody, kissSitBody, kissSwimBody, kissToTrot
|
||||
} from './ponyAnimations';
|
||||
import { BodyAnimation } from '../common/interfaces';
|
||||
|
||||
@@ -25,6 +26,14 @@ export const boopingLying = state(n('booping-lying'), boopLie);
|
||||
export const boopingFlying = state(n('booping-flying'), boopFly, { bug: boopFlyBug });
|
||||
export const boopingSwimming = state(n('booping-swimming'), boopSwim);
|
||||
|
||||
export const kissing = state(n('kissing'), kissBody);
|
||||
export const kissingHoof = state(n('kissing'), kissLiftHoofBody);
|
||||
export const kissingFlying = state(n('kissing-flying'), kissFlyBody, { bug: kissFlyBugBody });
|
||||
export const kissingLying = state(n('kissing-lying'), kissLieBody);
|
||||
export const kissingSitting = state(n('kissing-sitting'), kissSitBody);
|
||||
export const kissingSwimming = state(n('kissing-swimming'), kissSwimBody);
|
||||
export const kissingToTrotting = state(n('sitting-to-trotting'), kissToTrot);
|
||||
|
||||
export const sitting = state(n('sitting'), sit);
|
||||
export const sittingDown = state(n('sitting-down'), sitDown);
|
||||
export const standingUp = state(n('standing-up'), standUp);
|
||||
@@ -51,7 +60,8 @@ export const ponyStates = [
|
||||
sitting, sittingDown, standingUp, sittingToTrotting,
|
||||
lying, lyingDown, sittingUp, lyingToTrotting,
|
||||
hovering, flying, flyingUp, flyingDown, trottingToFlying, flyingToTrotting,
|
||||
swinging, swimmingToFlying, flyingToSwimming, boopingSwimming,
|
||||
swinging, swimmingToFlying, flyingToSwimming, boopingSwimming, kissing, kissingHoof,
|
||||
kissingFlying, kissingLying, kissingSitting, kissingSwimming, kissingToTrotting
|
||||
];
|
||||
|
||||
transition(hovering, flyingDown, { exitAfter: 0 });
|
||||
@@ -101,7 +111,6 @@ transition(flying, hovering, { exitAfter: 0, keepTime: true });
|
||||
|
||||
transition(boopingSwimming, swimming);
|
||||
transition(swimming, boopingSwimming, { exitAfter: 0 });
|
||||
|
||||
transition(booping, standing);
|
||||
transition(standing, booping, { exitAfter: 0 });
|
||||
transition(boopingSitting, sitting);
|
||||
@@ -111,7 +120,27 @@ transition(lying, boopingLying, { exitAfter: 0 });
|
||||
transition(boopingFlying, hovering, { enterTime: 1.1 / 10 });
|
||||
transition(hovering, boopingFlying, { exitAfter: 0 });
|
||||
|
||||
// transition(anyState, trottingToSwimming, { exitAfter: 0 });
|
||||
transition(kissingSwimming, swimming);
|
||||
transition(swimming, kissingSwimming, { exitAfter: 0 });
|
||||
transition(kissing, standing);
|
||||
transition(standing, kissing, { exitAfter: 0 });
|
||||
transition(kissingHoof, standing);
|
||||
transition(standing, kissingHoof, { exitAfter: 0 });
|
||||
transition(kissingFlying, hovering, { enterTime: 1.1 / 10 });
|
||||
transition(hovering, kissingFlying, { exitAfter: 0 });
|
||||
transition(kissingLying, lying);
|
||||
transition(lying, kissingLying, { exitAfter: 0 });
|
||||
transition(kissingSitting, sitting);
|
||||
transition(sitting, kissingSitting, { exitAfter: 0 });
|
||||
|
||||
transition(kissing, kissingToTrotting, { exitAfter: 0, onlyDirectTo: trotting });
|
||||
transition(kissingToTrotting, trotting);
|
||||
|
||||
transition(kissingSitting, sittingToTrotting, { exitAfter: 0, onlyDirectTo: trotting });
|
||||
transition(sittingToTrotting, standing);
|
||||
|
||||
transition(kissingLying, lyingToTrotting, { exitAfter: 0, onlyDirectTo: trotting });
|
||||
transition(lyingToTrotting, standing);
|
||||
|
||||
transition(anyState, trotting, { exitAfter: 0, keepTime: true });
|
||||
transition(anyState, flying, { exitAfter: 0, keepTime: true });
|
||||
@@ -129,7 +158,8 @@ export function isFlyingDown(state: AnimatorState<BodyAnimation> | undefined) {
|
||||
|
||||
export function isSwimmingState(state: AnimatorState<BodyAnimation> | undefined) {
|
||||
return state === swimming || state === trottingToSwimming || state === swimmingToTrotting ||
|
||||
state === flyingToSwimming || state === swimmingToFlying || state === boopingSwimming;
|
||||
state === flyingToSwimming || state === swimmingToFlying || state === boopingSwimming ||
|
||||
state === kissingSwimming;
|
||||
}
|
||||
|
||||
export function isFlyingUpOrDown(state: AnimatorState<BodyAnimation> | undefined) {
|
||||
@@ -153,3 +183,14 @@ export function toBoopState(state: AnimatorState<BodyAnimation>) {
|
||||
default: return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function toKissState(state: AnimatorState<BodyAnimation>) {
|
||||
switch (state) {
|
||||
case standing: return (Math.random() < 0.5 ? kissing : kissingHoof);
|
||||
case sitting: return kissingSitting;
|
||||
case lying: return kissingLying;
|
||||
case hovering: return kissingFlying;
|
||||
case swimming: return kissingSwimming;
|
||||
default: return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user