Merge remote-tracking branch 'upstream/archive' into archive-update-v0.55.0

This commit is contained in:
Eliot Partridge
2019-10-01 18:04:54 -05:00
39 changed files with 2998 additions and 2486 deletions
+10 -7
View File
@@ -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);
+2
View File
@@ -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'] },
],
},
];
+19 -2
View File
@@ -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}`);
}
+186 -9
View File
@@ -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
View File
@@ -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
+46 -5
View File
@@ -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;
}
}