mirror of
https://github.com/Terncode/pixel.horse.git
synced 2026-09-25 22:25:53 +02:00
244 lines
7.3 KiB
TypeScript
244 lines
7.3 KiB
TypeScript
import { isCommand, processCommand, hasFlag, includes, point } from '../common/utils';
|
|
import { canPonyLie, canPonyFlyUp, canPonyStand, canPonySit, doBoopPonyAction } from '../common/pony';
|
|
import { PonyTownGame } from './game';
|
|
import {
|
|
setPonyState, canBoop, isPonyLying, isPonyFlying, isPonyStanding, isPonySitting, getInteractBounds,
|
|
isFacingRight, closestEntity, entityInRange
|
|
} from '../common/entityUtils';
|
|
import { EntityState, Action, Pony, ChatType, EntityFlags, Point, TileType } from '../common/interfaces';
|
|
import { FLY_DELAY } from '../common/constants';
|
|
import { randomString } from '../common/stringUtils';
|
|
import { pickEntitiesByRect, pickAnyEntities } from '../common/worldMap';
|
|
import { centerPoint } from '../common/rect';
|
|
import { pointToWorld, roundPositionX, roundPositionY } from '../common/positionUtils';
|
|
import { hammer, shovel } from '../common/entities';
|
|
|
|
export function handleActionCommand(message: string, game: PonyTownGame): boolean {
|
|
if (isCommand(message)) {
|
|
const { command = '' } = processCommand(message);
|
|
const player = game.player;
|
|
|
|
if (DEVELOPMENT) {
|
|
if (command === 'spammessages') {
|
|
let i = 0;
|
|
setInterval(() => game.send(server => server.say(0, randomString(5) + ` #${i++}`, ChatType.Say)), 100);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
switch (command.toLowerCase()) {
|
|
case 'testerrorreporting':
|
|
throw new Error('test error');
|
|
case 'disablepixelratio':
|
|
game.togglePixelRatio();
|
|
return true;
|
|
case 'lie':
|
|
case 'lay':
|
|
if (player) {
|
|
if (isPonyLying(player)) {
|
|
sitAction(player, game);
|
|
} else {
|
|
lieAction(player, game);
|
|
}
|
|
}
|
|
return true;
|
|
case 'sit':
|
|
if (player) {
|
|
if (isPonyFlying(player)) {
|
|
standAction(player, game);
|
|
} else {
|
|
sitAction(player, game);
|
|
}
|
|
}
|
|
return true;
|
|
case 'stand':
|
|
if (player) {
|
|
standAction(player, game);
|
|
}
|
|
return true;
|
|
case 'fly':
|
|
if (player) {
|
|
if (isPonyFlying(player)) {
|
|
standAction(player, game);
|
|
} else {
|
|
flyAction(player, game);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
export function upAction(game: PonyTownGame) {
|
|
const player = game.player;
|
|
|
|
if (player) {
|
|
if (isPonyLying(player)) {
|
|
sitAction(player, game);
|
|
} else if (isPonySitting(player)) {
|
|
standAction(player, game);
|
|
} else if (isPonyStanding(player)) {
|
|
flyAction(player, game);
|
|
}
|
|
}
|
|
}
|
|
|
|
export function downAction(game: PonyTownGame) {
|
|
const player = game.player;
|
|
|
|
if (player) {
|
|
if (isPonySitting(player)) {
|
|
lieAction(player, game);
|
|
} else if (isPonyStanding(player)) {
|
|
sitAction(player, game);
|
|
} else if (isPonyFlying(player)) {
|
|
standAction(player, game);
|
|
}
|
|
}
|
|
}
|
|
|
|
export function sitAction(player: Pony, game: PonyTownGame) {
|
|
if (canPonySit(player, game.map) && game.send(server => server.action(Action.Sit))) {
|
|
player.state = setPonyState(player.state, EntityState.PonySitting);
|
|
game.stateOverride = EntityState.PonySitting;
|
|
game.onActionsUpdate.next();
|
|
}
|
|
}
|
|
|
|
export function standAction(player: Pony, game: PonyTownGame) {
|
|
if (canPonyStand(player, game.map) && game.send(server => server.action(Action.Stand))) {
|
|
player.state = setPonyState(player.state, EntityState.PonyStanding);
|
|
game.stateOverride = EntityState.PonyStanding;
|
|
game.onActionsUpdate.next();
|
|
}
|
|
}
|
|
|
|
export function lieAction(player: Pony, game: PonyTownGame) {
|
|
if (canPonyLie(player, game.map) && game.send(server => server.action(Action.Lie))) {
|
|
player.state = setPonyState(player.state, EntityState.PonyLying);
|
|
game.stateOverride = EntityState.PonyLying;
|
|
game.onActionsUpdate.next();
|
|
}
|
|
}
|
|
|
|
export function flyAction(player: Pony, game: PonyTownGame) {
|
|
if (canPonyFlyUp(player) && game.send(server => server.action(Action.Fly))) {
|
|
player.state = setPonyState(player.state, EntityState.PonyFlying);
|
|
player.inTheAirDelay = FLY_DELAY;
|
|
game.stateOverride = EntityState.PonyFlying;
|
|
game.onActionsUpdate.next();
|
|
}
|
|
}
|
|
|
|
export function boopAction(game: PonyTownGame) {
|
|
if (game.player && canBoop(game.player) && game.send(server => server.action(Action.Boop))) {
|
|
doBoopPonyAction(game, game.player);
|
|
}
|
|
}
|
|
|
|
export function turnHeadAction(game: PonyTownGame) {
|
|
if (!game.player) {
|
|
return;
|
|
}
|
|
|
|
if (game.player.animator.state) {
|
|
const disabledFrames = game.player.animator.state.animation.disableHeadTurnFrames;
|
|
if (disabledFrames > 0) {
|
|
const disabledTime = disabledFrames / game.player.animator.state.animation.fps;
|
|
if (disabledTime >= game.player.animator.time) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (game.send(server => server.action(Action.TurnHead))) {
|
|
game.player.state = game.player.state ^ EntityState.HeadTurned;
|
|
game.headTurnedOverride = hasFlag(game.player.state, EntityState.HeadTurned);
|
|
game.onActionsUpdate.next();
|
|
}
|
|
}
|
|
|
|
export function interact(game: PonyTownGame, shift: boolean) {
|
|
const player = game.player;
|
|
|
|
if (player) {
|
|
const bounds = getInteractBounds(player);
|
|
const entities = pickEntitiesByRect(game.map, bounds, true, false);
|
|
const center = centerPoint(bounds);
|
|
center.x += (bounds.w / 4) * (isFacingRight(player) ? -1 : 1);
|
|
const entity = closestEntity(pointToWorld(center), entities);
|
|
|
|
if (entity && entityInRange(entity, player)) {
|
|
game.send(server => server.interact(entity.id));
|
|
} else if (player.hold === hammer.type) {
|
|
game.changePlaceEntity(shift);
|
|
} else if (player.hold === shovel.type) {
|
|
game.changePlaceTile(shift);
|
|
} else if (player.ponyState.holding && hasFlag(player.ponyState.holding.flags, EntityFlags.Usable)) {
|
|
game.send(server => server.use());
|
|
}
|
|
}
|
|
}
|
|
|
|
export function toggleWall(game: PonyTownGame, hover: Point) {
|
|
const x = hover.x | 0;
|
|
const y = hover.y | 0;
|
|
const dx = hover.x - x;
|
|
const dy = hover.y - y;
|
|
|
|
if (dx > dy) {
|
|
if ((dx + dy) < 1) {
|
|
game.send(server => server.changeTile(x, y, TileType.WallH));
|
|
} else {
|
|
game.send(server => server.changeTile(x + 1, y, TileType.WallV));
|
|
}
|
|
} else {
|
|
if ((dx + dy) < 1) {
|
|
game.send(server => server.changeTile(x, y, TileType.WallV));
|
|
} else {
|
|
game.send(server => server.changeTile(x, y + 1, TileType.WallH));
|
|
}
|
|
}
|
|
}
|
|
|
|
export function editorSelectEntities(game: PonyTownGame, hover: Point, shift: boolean) {
|
|
game.apply(() => {
|
|
const entities = pickAnyEntities(game.map, hover);
|
|
|
|
if (shift) {
|
|
const entity = entities.filter(e => !includes(game.editor.selectedEntities, e))[0];
|
|
entity && game.editor.selectedEntities.push(entity);
|
|
} else {
|
|
const index = entities.findIndex(e => includes(game.editor.selectedEntities, e));
|
|
const entity = entities[(index + 1) % entities.length];
|
|
game.editor.selectedEntities = entity ? [entity] : [];
|
|
}
|
|
});
|
|
}
|
|
|
|
export function editorDragEntities(game: PonyTownGame, hover: Point, buttonPressed: boolean) {
|
|
if (buttonPressed) {
|
|
const dx = hover.x - game.editor.draggingStart.x;
|
|
const dy = hover.y - game.editor.draggingStart.y;
|
|
|
|
game.editor.selectedEntities.forEach(e => {
|
|
e.x = roundPositionX(e.draggingStart!.x + dx);
|
|
e.y = roundPositionY(e.draggingStart!.y + dy);
|
|
});
|
|
} else {
|
|
game.apply(() => game.editor.draggingEntities = false);
|
|
game.send(server => server.editorAction({
|
|
type: 'move',
|
|
entities: game.editor.selectedEntities.map(({ id, x, y }) => ({ id, x, y })),
|
|
}));
|
|
}
|
|
}
|
|
|
|
export function editorMoveEntities(game: PonyTownGame, hover: Point) {
|
|
game.editor.draggingEntities = true;
|
|
game.editor.draggingStart = hover;
|
|
game.editor.selectedEntities.forEach(e => e.draggingStart = point(e.x, e.y));
|
|
}
|