Symmetrical Drawing Mode in the Map Editor#19
Conversation
| } | ||
|
|
||
| mirror( | ||
| mapSize: SizeVector, |
There was a problem hiding this comment.
There is some repetition in this function, so maybe just destructure like { height, width }: SizeVector?
There was a problem hiding this comment.
Actually, since this function is only used sparely, I would probably prefer making it a standalone function in athena/lib or hera/editor/lib as like mirrorVector(vector: Vector, mirrorType: MirrorType).
| @@ -1,4 +1,6 @@ | |||
| import sortBy from '@deities/hephaestus/sortBy.tsx'; | |||
| import { DrawingMode } from '../../hera/editor/Types.tsx'; | |||
There was a problem hiding this comment.
We can't import from hera in the athena package since athena also runs on the server without access to React. I think we need to define a VectorMirror (?) type with just 'horizontal' | 'vertical' | 'diagonal' and then use that as a base for DrawingMode in the editor types.
There was a problem hiding this comment.
This should be solved, since I moved vector.mirror inside hera: 349ef4c
| import MenuBehavior from './behavior/Menu.tsx'; | ||
| import NullBehavior from './behavior/NullBehavior.tsx'; | ||
| import Cursor from './Cursor.tsx'; | ||
| import MapEditorExtraCursors from './editor/MapEditorExtraCursors.tsx'; |
There was a problem hiding this comment.
What about calling it MapEditorMirrorCursors.tsx?
| private putMultiple( | ||
| vectors: Vector[], | ||
| state: State, | ||
| actions: Actions, | ||
| editor: EditorState, | ||
| ): StateLike | null { | ||
| let result: StateLike | null = null; | ||
| const players = Array.from( | ||
| new Set([...state.map.active, ...PlayerIDs]), | ||
| ).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 | ||
| ]; | ||
|
|
||
| const tempResult = this.put( | ||
| vector, | ||
| { ...state, ...result }, | ||
| actions, | ||
| editor, | ||
| playerId, | ||
| ); | ||
| result = { | ||
| ...(result ?? {}), | ||
| ...tempResult, | ||
| }; | ||
| }); | ||
| return result; | ||
| } |
There was a problem hiding this comment.
This is why more elegant than what I could have come up with. Nice!
| } | ||
|
|
||
| return vectors.map((vector) => ( | ||
| <Cursor key={vector.toString()} {...props} position={vector} /> |
There was a problem hiding this comment.
You can just pass vector, toString is implicitly called.
There was a problem hiding this comment.
TypeScript doesn't like that:
Type 'Vector' is not assignable to type 'Key | null | undefined'.ts(2322)
| drawingMode: DrawingMode, | ||
| mapSize: SizeVector, | ||
| ) { | ||
| const vectors: Vector[] = []; |
There was a problem hiding this comment.
Nit: Code style.
| const vectors: Vector[] = []; | |
| const vectors: Array<Vector> = []; |
| } | ||
| } | ||
|
|
||
| return vectors.filter((v) => !vector.equals(v)); |
There was a problem hiding this comment.
Nit: I'm always trying to have descriptive variable names, even if it's obvious. In this case, I would probably rename vector to origin, and then rename v here to vector. That makes the code just slightly easier to read overall.
| const playerId = | ||
| players[ | ||
| ((currentPlayerIndex >= 0 ? currentPlayerIndex : 0) + index) % | ||
| players.length | ||
| ]; |
There was a problem hiding this comment.
This should not include 0 as 0 is the neutral unit type that can be rescued. Can you update it so it only uses one of the valid player ids except 0?
| const tempResult = this.put( | ||
| vector, | ||
| { ...state, ...result }, | ||
| actions, | ||
| editor, | ||
| playerId, | ||
| ); | ||
| result = { | ||
| ...(result ?? {}), | ||
| ...tempResult, | ||
| }; |
There was a problem hiding this comment.
You shouldn't need the ?? {} as you can spread null.
| const tempResult = this.put( | |
| vector, | |
| { ...state, ...result }, | |
| actions, | |
| editor, | |
| playerId, | |
| ); | |
| result = { | |
| ...(result ?? {}), | |
| ...tempResult, | |
| }; | |
| const newState = this.put( | |
| vector, | |
| { ...state, ...result }, | |
| actions, | |
| editor, | |
| playerId, | |
| ); | |
| result = { | |
| ...(newState), | |
| ...tempResult, | |
| }; |
|
Thank you for the contribution, the implementation is so elegant and it feels magical already. Apologies that it took me a bit to get back to you as I'm at a conference right now. I left a few comments, but it's just small nits. Replying to your comment on the issue here:
I think that would look best too. I still need to think about the exact icons, but if you can get the layout ready I'll take another look and push some icons. |
| <Tick animationConfig={AnimationConfig}> | ||
| <Stack gap={24} vertical verticalPadding> | ||
| <Box center gap={32}> | ||
| {/* TODO(dkratz): Remove text and add selected state to buttons */} |
There was a problem hiding this comment.
You can either use selected or selectedText on InlineLink. They are different active states for links. You can use the editor's drawing mode to compare the state.
This seems to happen in the |
| // TODO: adjust color | ||
| color="red" |
There was a problem hiding this comment.
I think I'm just gong to leave them all red for now. It's easier to parse. Might change it in the future.
|
The problem with the "stuck" cursors was that |
0056017 to
9210f69
Compare
|
Thank you, this is awesome, I'm very excited about this feature! The funds were sent to you. I'd love to see more contributions if you are working on any! |
|
Nice, excited to have my first open source contribution merged :) |


Description
Adds symmetrical drawing mode in the map editor.
Resolves #7