Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement basic event manipulation operations in the map editor #40

Merged
merged 32 commits into from
Sep 18, 2023

Conversation

white-axe
Copy link
Collaborator

I added a more user-friendly system for selecting a specific event on the map. When the event layer is selected in the layer dropdown, the selected event is chosen from multiple candidates (which can be changed if need be) with the following priority:

  1. If a shift key is held down, no event
  2. Otherwise, the unique event whose tile is hovered over by the mouse, if it exists
  3. Otherwise, the event with the highest ID whose graphic contains the pixel the mouse is hovering over, if it exists
  4. Otherwise, the unique event whose tile is selected on the map, if it exists
  5. Otherwise, the event with the highest ID whose graphic contains the pixel in the center of the tile selected on the map, if it exists
  6. Otherwise, no event

Using this system, this pull request implements various methods of interacting with events on the map:

  • Adds the ability to open the event editor window on an existing event by selecting it and then double-clicking with the primary mouse button or pressing enter
  • Adds the ability to create a new event by doing the same while no event is selected, with a check to make sure you can't create an event on a tile that already has one
  • Adds the ability to delete an event by selecting it and then pressing delete or backspace
  • Adds the ability to move an event on the map by selecting it and then dragging and dropping it with the primary mouse button, with a check to make sure you can't move the event so that its tile is also the tile of another event

I didn't make any changes to the actual event editor window, though. I just wanted to put these basic features into a pull request first.

If you hover over an event graphic in the map, it'll now show a magenta
outline to show that it is selected (for things like moving it around,
editing the event or deleting it).

If there are multiple overlapping graphics, the one with the highest ID
will be selected because event graphics are rendered in order of ID.

Alternatively you can also hover over the actual tile on which the event
is located, which allows you to select an event that is completely
covered by another event's graphic without having to move the covering
graphic aside. A green border is rendered around the selected event's
tile to make this user-friendly.
A slab does not support inserting elements at arbitrary positions, which
we'll need to do if we want to change the ID of an event.

Also, we already know where all of the unused IDs are since we have to
iterate through all the events every time we draw the map, so a regular
vector will not lose any performance compared to a slab.
@melody-rs
Copy link
Member

I can't seem to make or open events in the event editor, but I can delete events

@white-axe
Copy link
Collaborator Author

Does it work when you select an event and then press enter?

@melody-rs
Copy link
Member

Nevermind, git was being weird

Copy link
Member

@melody-rs melody-rs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, a couple weird UX issues:
image
There are a lot of highlights around events at the same time, which can look pretty weird (especially on 32x32 events)

luminol_apg24zfLRF
Opening events keeps them being dragged to your cursor, even when no mouse buttons are being held, which is annoying

@white-axe
Copy link
Collaborator Author

Do you have any suggestions for how the highlighting should be performed?

@melody-rs
Copy link
Member

  • Highlight the event as yellow if it is hovered over and double clicking/pressing enter would open the event editor
  • Highlight the event as pink or green if it is being edited

@melody-rs
Copy link
Member

As for the event editor, I was hoping to get new-tilemap to an mvp state (which it's pretty close to, I think? The only thing it's missing is multiple brushes and drawing rectangles of tiles) and merge it, then refactor Luminol a bit (like splitting it into multiple crates) before tackling the event editor

@white-axe white-axe requested a review from melody-rs September 18, 2023 02:47
@melody-rs melody-rs merged commit ee16d97 into Astrabit-ST:new-tilemap Sep 18, 2023
4 checks passed
@white-axe white-axe deleted the nt-event-editor branch September 18, 2023 03:40
melody-rs added a commit that referenced this pull request Sep 24, 2023
* Merge

* Outline basic tilemap code?

* feat(tilemap): 🚧 Hasty commit so I can work on my other computer

* feat(tilemap): I hate OpenGL

* feat: 🏗️ Move to wgpu

* feat(tilemap): 🚧 Tilemap work

* feat(tilemap): 🚧 Generate tileset vertices

* feat(tilemap): 🚧 Sorta works

* feat(tilemap): 🎨 Split tilemap up into multiple modules

* feat(tilemap): 🚧 Try getting autotiles working

* feat(tilemap): 🚧 Move to quad system

* feat(tilemap): 🚧 Get tiles rendering under new system

* feat(tilemap): 🚧 Scaling tilemap

* feat(tilemap): 🏗️ Use projection matrix

* feat(tilemap): 🚧 Wonky autotiles and map pan

* feat(tilemap): 🎨 Split tilemap up into components

* fix(tilemap): 🐛 Fix multiple maps

* feat(tilemap): 🚧 Add tilemap panning

* feat(tilemap): 🐛 Fix autotiles

* feat(tilemap): 🚧 Sorta functional animated autotiles

* feat(tilemap): ✨ Partially implement events

* feat(tilemap): ⚡ Move to a shared viewport uniform

* feat(tilemap): ✨ Get blend modes working

* feat(tilemap): ✨

Hue shifting events

* feat(tilemap): 🎨 Group events together

* feat(tilemap): ✨ Event opacity

* feat(tilemap): 🚧 Fail to make plane properly

* feat(tilemap): ✨ Get plane working

* feat(tilemap): ✨ Toggle layers

* feat(tilemap): ⚡ Render to texture

* feat(tilemap): ✨ Get tilemap scaling working properly

* feat(tilemap): 🔥 Use egui instead of a basic renderer

* feat(tilemap): 🐛 Fix events with tiles

* fix(tilemap): 🐛 Fix z layering and tilemap cursor being wrong

* fix(tilemap): 🐛 Fix saving tilemap as image

* feat(tilemap): ✨ Display a messagebox when crashing with a wgpu error

* feat(filesystem): 🚧 Convert data cache and filesystem into an enum

* refactor(config): 🎨 Improve seperation of concerns by storing config seperate to the data cache

* refactor(data cache): 🎨 Clean up data cache code

* refactor(filesystem): 🚧 Try a new filesystem structure

* feat(filesystem): 🚧 Completely rework filesystem

* fix(audio): 🐛 Fix audio playback issues

* feat(filesystem): 🚧 RGSSAD support

* feat(filesystem): ✨ RGSSAD archive reading

* chore: 🔥 whoops

* fix(tilemap): 🐛 Fix tile 0 drawing bug

* fix(filesystem): 🐛 Fix overlay bug

* perf(tilemap): 🚧 Rework tilemap to use instancing

* perf(tilemap): ⚡ Use instancing for tiles

* feat(tilemap): ✨ Basic tilepicker support

* refactor: 🎨 Shift code around

* refactor(RPG Maker Structs): 🎨 Begin to refactor RMXP types to make it mroe ergonomic to use

* refactor: 🎨 Change Ids to usize, refactor them to subtract and add 1 at load/save time

* refactor: 🎨 appease the compiler

* chore: ⬆️ Update alox-48 and remove it as a git submodule

* refactor: 🎨 More RMXP refactors

* refactor: 🎨 Improve rmxp struct exports

* feat(filesystem): ✨ Load from RTPs

* feat(filesystem): ✨ Load rtps on Linux

* fix(filesystem): 🐛 Fix duplication issues and general code smell

* fix(filesystem): 🐛 Apparently rgssad and rgss2a are the same

* feat(audio): ✨ Midi support (uses a public domain soundfont recommended in the mkxp readme)

* fix(audio): 🐛 FIx audio crash when unloading a project

* refactor(tilemap): 🎨 Move tilepicker to seperate struct

* refactor(tilemap): 🎨 Move blendmode to be a shared enum

* fix(audio): 🐛 Windows filepaths cause me agony

* refactor: 🎨 Use a slab instead of hashmap for tilemap resources

* feat(tilemap): ✨ Add event tooltip and refactor code

Very jank. Need to fix

* fix: 🚨 Fix dependencies

* feat(filesystem): ✨ Add rgss3a support

* feat(tilemap): ✨ Re-add tilemap layer toggling, with extra performance!!

* chore: Update pinned nightly to 08/28/2023

* ci: Bump nightly in workflows

* ci: 👷 Limit cargo jobs

* ci: 👷 Limit jobs even more

* ci: 👷 grahhh github

* feat(tilemap): ✨ Add tile snapping

* fix: 🐛 Fix event tooltip scaling

* feat: ✨ Global config window

* Slightly reduce quad size for map tiles (#35)

* Fix rendering of event graphics and the tilepicker (#36)

* Implement `calc_quad` in atlas.rs properly

This is just a stopgap to get the events with tileset graphics rendering
properly.

It's probably better to get rendering of these events to go through the
tilemap shader somehow...

* Move the "+ 1" from atlas.rs to event.rs in case it is an isolated issue

* Implement `Tiles::draw` for the tilepicker and other non-layered surfaces

* Run rustfmt on src/graphics/primitives/tiles/mod.rs

* Tilepicker no longer needs to clone or copy the atlas

* Atlas wraparound is now handled when rendering tiles

* fix(tilemap): 🐛 Fix tileset rendering with no autotiles

* Atlas wrapping handler fixes (#37)

* Replace leftover hardcoded values in `calc_quad`

* Fix rendering of tiles to the right of the autotiles

* chore: ⬇️ Change dependency optimization level

This helps with compile times on debug builds massively

* ci: 👷 Use mold and lld as linkers, bump nightly

There is apparently a regression in the pervious version of nightly, bumping it should fix it?

* ci: 💚 Install clang and mold in checks

* Tile drawing implementation and bug fixes (#38)

* Fix off-by-one when the layer number is displayed

* Basic tile drawing for non-autotiles

* Fix tilepicker default width being too small

* Fix `Table3` indexing implementation

Co-authored-by: Speak2Erase <[email protected]>

* Fix tilepicker showing incorrect autotile graphics

RPG Maker XP displays autotile index 47 for autotiles in the tilepicker,
not 0.

* Tile drawing now works with autotiles as well

* Fix bottom-right corner of map not rendering

* Blank tiles should always have ID 0

---------

Co-authored-by: Speak2Erase <[email protected]>

* perf(tilemap): ⚡ Use push constants instead of uniforms

* feat(tilemap): ✨ Add layer darkening

* Fix out-of-bounds vector access in `recompute_autotile` (#39)

* Implement basic event manipulation operations in the map editor (#40)

* `MapView.events` is now a `Slab` instead of a `HashMap`

* Add mechanism for selecting events in the map

If you hover over an event graphic in the map, it'll now show a magenta
outline to show that it is selected (for things like moving it around,
editing the event or deleting it).

If there are multiple overlapping graphics, the one with the highest ID
will be selected because event graphics are rendered in order of ID.

Alternatively you can also hover over the actual tile on which the event
is located, which allows you to select an event that is completely
covered by another event's graphic without having to move the covering
graphic aside. A green border is rendered around the selected event's
tile to make this user-friendly.

* This arm is unreachable assuming `map.events` is sorted

* Remove redundant type annotation

* Selected event is now highlighted in the hover tooltip

* Apply texture bleeding fix to events as well

* Don't interact with events if event layer isn't selected

* Event editor now opens when double-clicking events

* I was wrong; this line is not safe

* Fix name editing in the event editor

* Events can now also be selected by the yellow square cursor

* Implement event deletion when pressing delete on the map

* Event editor windows now have (mostly) unique IDs

* Use a vector to store the events instead of a slab

A slab does not support inserting elements at arbitrary positions, which
we'll need to do if we want to change the ID of an event.

Also, we already know where all of the unused IDs are since we have to
iterate through all the events every time we draw the map, so a regular
vector will not lose any performance compared to a slab.

* Double-click on map tiles without events to create one

* Enter key can now also be used for event creation/editing

* Fix incorrect serialization length for `OptionVec`

* Drag-and-drop events to move them on the map

* Remove unused variables from map_view.rs

* Event drag-and-drop now preserves the event offset from the cursor

* Apply clippy recommendations

* Apply another clippy recommendation

* Fix misleading comment in src/tabs/map.rs

* Don't move events when the mouse is not hovering over them

* Simplify deserialization implementation for OptionVec

* Remove `pub` from `event_drag_offset`

* Fix crash when adding event on a map with no events

* Prevent event from sticking to cursor after double-clicking

* Selected event border is now yellow instead of magenta

* Show magenta border around events that are being edited

* feat(tilemap): ✨ Handle keyboard for moving the cursor

* Implement the circle, rectangle and fill brushes (#41)

* Fix corner case in `OptionVec` `FromIterator` implementation

* Implement the flood fill brush

* Implement the rectangle brush

* Implement the circle/ellipse brush

* Buffer all map tile changes to reduce brush lag

* Fix arrow keys allowing map cursor to move out of bounds

* Implement drawing rectangular regions of tiles from the tilepicker (#42)

* Allow multiple tiles to be selected in the tilepicker

* Refactor the tile calculation function in tilepicker.rs

* Implement rectangle drawing for all four brushes

* Fix redundant position calculation in src/tabs/map.rs

* Fix tilepicker selection being able to extend out of bounds

* Fix pattern rectangle being shown when event layer is selected

* Fix pattern rectangle extending out of map bounds

* Pen brush needs to do bounds checking

* Floor tileset height to nearest multiple of 32

Rounding down to the nearest multiple of 32 is the correct behavior when
the tileset height in pixels is not divisible by 32.

* Fix tilepicker not showing last row of tiles

* chore: 📝 Update readme to include finished features

* refactor: 🎨 Move primitives into mod.rs

* chore: 🎨 Rustfmt

---------

Co-authored-by: white-axe <[email protected]>
@white-axe white-axe added the core functionality a feature provided in rpg maker label Jan 21, 2024
@melody-rs melody-rs added this to the v1.0 milestone Aug 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core functionality a feature provided in rpg maker
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants