Skip to content

Commit

Permalink
Make playground maps shareable by persisting data to the URL (#18) (#32)
Browse files Browse the repository at this point in the history
Co-authored-by: Connor Lindsey <[email protected]>
GitOrigin-RevId: 80499df94c87243652a05c36fa5c43bd079fae6b
  • Loading branch information
cpojer and connorlindsey committed May 19, 2024
1 parent e893189 commit f273fa2
Show file tree
Hide file tree
Showing 13 changed files with 108 additions and 498 deletions.
1 change: 0 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ module.exports = {
],
plugins: ['@deities'],
rules: {
'@typescript-eslint/array-type': [2, { default: 'generic' }],
'@typescript-eslint/no-restricted-imports': [
2,
{
Expand Down
2 changes: 1 addition & 1 deletion apollo/lib/gameHasEnded.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ActionResponse } from '../ActionResponse.tsx';

export default function gameHasEnded(
gameState: ReadonlyArray<readonly [ActionResponse, ...Array<unknown>]> | null,
gameState: ReadonlyArray<readonly [ActionResponse, ...unknown[]]> | null,
) {
return !!(
gameState?.length &&
Expand Down
5 changes: 1 addition & 4 deletions art/Sprites.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ type Resource = Readonly<[name: string, url: string]>;
type Resources = ReadonlyArray<Resource>;
type PaletteSwapFn = typeof paletteSwap;
type PaletteSwapParameters = Parameters<PaletteSwapFn>;
type DropFirstInTuple<T extends Array<unknown>> = T extends [
unknown,
...infer Rest,
]
type DropFirstInTuple<T extends unknown[]> = T extends [unknown, ...infer Rest]
? Rest
: never;
type MaybePaletteSwapParameters = [
Expand Down
24 changes: 5 additions & 19 deletions hera/GameMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ import { resetBehavior, setBaseClass } from './behavior/Behavior.tsx';
import MenuBehavior from './behavior/Menu.tsx';
import NullBehavior from './behavior/NullBehavior.tsx';
import Cursor from './Cursor.tsx';
import MapEditorExtraCursors from './editor/MapEditorMirrorCursors.tsx';
import { EditorState } from './editor/Types.tsx';
import addEndTurnAnimations from './lib/addEndTurnAnimations.tsx';
import animateSupply from './lib/animateSupply.tsx';
Expand Down Expand Up @@ -1722,25 +1721,12 @@ export default class GameMap extends Component<Props, State> {
{(propsShowCursor || propsShowCursor == null) &&
showCursor &&
!replayState.isReplaying && (
<>
<Cursor
position={position}
size={tileSize}
zIndex={zIndex - 4}
/>
{editor?.mode === 'design' && (
<MapEditorExtraCursors
color="red"
drawingMode={editor?.drawingMode}
mapSize={map.size}
origin={position}
size={tileSize}
zIndex={zIndex}
/>
)}
</>
<Cursor
position={position}
size={tileSize}
zIndex={zIndex - 4}
/>
)}

<MapAnimations
actions={this._actions}
animationComplete={this._animationComplete}
Expand Down
1 change: 0 additions & 1 deletion hera/editor/MapEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ const getEditorBaseState = (
effects = new Map([...effects, ['Start', startScenario]]);
}
return {
drawingMode: 'regular',
effects,
isDrawing: false,
isErasing: false,
Expand Down
28 changes: 0 additions & 28 deletions hera/editor/MapEditorMirrorCursors.tsx

This file was deleted.

7 changes: 0 additions & 7 deletions hera/editor/Types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,9 @@ type UndoKey =

export type UndoEntry = readonly [UndoKey, MapData];
export type UndoStack = ReadonlyArray<UndoEntry>;
export type DrawingMode =
| 'regular'
| 'horizontal'
| 'vertical'
| 'horizontal-vertical'
| 'diagonal';

export type EditorState = Readonly<{
condition?: readonly [WinConditionsWithVectors, number];
drawingMode: DrawingMode;
effects: Effects;
isDrawing: boolean;
isErasing: boolean;
Expand Down
69 changes: 12 additions & 57 deletions hera/editor/behavior/DesignBehavior.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import verifyTiles from '@deities/athena/lib/verifyTiles.tsx';
import Building from '@deities/athena/map/Building.tsx';
import { getDecoratorLimit } from '@deities/athena/map/Configuration.tsx';
import Entity from '@deities/athena/map/Entity.tsx';
import { PlayerID, PlayerIDs } from '@deities/athena/map/Player.tsx';
import Unit from '@deities/athena/map/Unit.tsx';
import Vector from '@deities/athena/map/Vector.tsx';
import MapData from '@deities/athena/MapData.tsx';
Expand All @@ -49,7 +48,6 @@ import {
} from '../../Types.tsx';
import FlashFlyout from '../../ui/FlashFlyout.tsx';
import { FlyoutItem } from '../../ui/Flyout.tsx';
import getSymmetricPositions from '../lib/getSymmetricPositions.ts';
import updateUndoStack from '../lib/updateUndoStack.tsx';
import { EditorState } from '../Types.tsx';

Expand Down Expand Up @@ -164,11 +162,7 @@ export default class DesignBehavior {
subVector?: Vector,
): StateLike | null {
if (editor?.isDrawing && editor.selected) {
const vectors = [
vector,
...getSymmetricPositions(vector, editor.drawingMode, state.map.size),
];
return this.draw(vectors, state, actions, editor);
return this.put(vector, state, actions, editor);
}

const { animations, map } = state;
Expand Down Expand Up @@ -234,46 +228,11 @@ export default class DesignBehavior {
return null;
}

private draw(
vectors: Array<Vector>,
state: State,
actions: Actions,
editor: EditorState,
): StateLike | null {
let newState: StateLike | null = null;
const players = Array.from(
new Set([...state.map.active, ...PlayerIDs.filter((id) => id !== 0)]),
).slice(0, vectors.length);
vectors.forEach((vector, index) => {
const currentPlayerIndex = players.indexOf(
state.map.getCurrentPlayer().id,
);
const playerId =
players[
((currentPlayerIndex >= 0 ? currentPlayerIndex : 0) + index) %
players.length
];

newState = {
...newState,
...this.put(
vector,
{ ...state, ...newState },
actions,
editor,
playerId,
),
};
});
return newState;
}

private put(
vector: Vector,
state: State,
actions: Actions,
editor: EditorState,
playerId: PlayerID,
): StateLike | null {
if (shouldPlaceDecorator(editor)) {
return null;
Expand Down Expand Up @@ -340,14 +299,7 @@ export default class DesignBehavior {
);
} else if (selected.unit) {
this.previous = null;
return this.putUnit(
selected.unit,
vector,
state,
actions,
editor,
playerId,
);
return this.putUnit(selected.unit, vector, state, actions, editor);
} else if (selected.building) {
this.previous = null;
return this.putBuilding(
Expand All @@ -356,7 +308,6 @@ export default class DesignBehavior {
state,
actions,
editor,
playerId,
);
}
return null;
Expand Down Expand Up @@ -552,7 +503,6 @@ export default class DesignBehavior {
state: State,
actions: Actions,
editor: EditorState,
playerId: PlayerID,
): StateLike | null {
const { map } = state;
const { units } = map;
Expand All @@ -571,7 +521,12 @@ export default class DesignBehavior {
...spawn(
actions,
state,
[[vector, unit.removeLeader().setPlayer(playerId)]],
[
[
vector,
unit.removeLeader().setPlayer(map.getCurrentPlayer().id),
],
],
null,
({ map }) => {
updateUndoStack(actions, editor, [
Expand All @@ -596,7 +551,6 @@ export default class DesignBehavior {
state: State,
actions: Actions,
editor: EditorState,
playerId: PlayerID,
): StateLike | null {
const { animations, map } = state;
const { buildings, units } = map;
Expand All @@ -614,13 +568,14 @@ export default class DesignBehavior {
const config = map.config.copy({
blocklistedBuildings: new Set(),
});
const player = map.getCurrentPlayer();
const isAlwaysNeutral = building.info.isStructure();

const tryToPlaceBuilding = (state: State): StateLike | null => {
let { map } = state;
map = map.copy({
active: getActivePlayers(map),
buildings: map.buildings.set(vector, building.setPlayer(playerId)),
buildings: map.buildings.set(vector, building.setPlayer(player.id)),
});

const { editorPlaceOn, placeOn } = building.info.configuration;
Expand Down Expand Up @@ -663,7 +618,7 @@ export default class DesignBehavior {
return canBuild(
getTemporaryMapForBuilding(temporaryMap, vector, building),
building.info,
isAlwaysNeutral ? 0 : playerId,
isAlwaysNeutral ? 0 : player,
vector,
true,
) && !(building.info.isHQ() && map.currentPlayer === 0)
Expand All @@ -681,7 +636,7 @@ export default class DesignBehavior {
return newState;
},
type: 'createBuilding',
variant: isAlwaysNeutral ? 0 : playerId,
variant: isAlwaysNeutral ? 0 : player.id,
}),
map: state.map.copy({ buildings: buildings.delete(vector) }),
}
Expand Down
Loading

0 comments on commit f273fa2

Please sign in to comment.