Editor improvements: creature levels, help window, wave portal editing and more - #22
Conversation
The level file format has carried a creature's level since forever, and the game reads it back, but the editor always wrote 1: it spawned every creature straight from its definition and offered no way to say otherwise. Levelling a creature in a map meant editing the file by hand. L now raises the level the editor gives to creatures, shift L lowers it, both wrapping around the thirty levels a creature can have, and the status bar shows it next to the class the way it already shows the fullness, the seat and the class themselves. The level applies to the creatures spawned from then on, and also to whatever the hand is holding when it changes, which is what makes it possible to change a creature that is already placed: pick it up, set the level, drop it. Only the server knows what a hand holds, so the client sends the level and lets the server decide what it lands on. An empty hand is not a mistake, it just means the editor is setting the level of the creatures to come. Placing a creature also heals it. Levelling raises the maximum HP without healing, which is what levelling up in a game should do but not what an author placing a level 20 hero means, and the difference would have been saved into the map as a wounded creature. The status bar field is 20 pixels wider so that the longest class name and a two digit level still fit within it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> (cherry picked from commit efd537c)
C cycles forward through the creature definitions and wraps around, so reaching the class just before the current one means pressing it as many times as there are classes. Shift C now steps back the same way shift L lowers the level. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> (cherry picked from commit 4202bd7)
…iting Shift Y walks the seats backwards, the way shift C and shift L already walk the creature classes and the creature levels, so GameMap gains previousSeatId next to nextSeatId. None of that is discoverable. The status bar names the key next to each thing it shows, which is how anyone finds T, Y, C and L in the first place, but there is nowhere it could say that holding shift reverses them, and nothing at all mentions the camera keys or the point of view hotkeys. Help then Controls now opens a window listing all of them, grouped by what they act on. The Help menu had one entry, About, which is not connected to anything. The editor also never said which level it was editing. A new level is given a name in the dialog that creates it and then never shown again, and loading one from the recently used list gives no confirmation of what was opened. The name now sits under the menu bar. It is read every frame rather than once, because the client only learns it when the server sends the level over, which happens after the editor is on screen, and it changes again on saving under a new name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> (cherry picked from commit 9b79128)
Entering the editor a second time in one session kills the game:
CEGUI::AlreadyExistsException ... Failed to add Element named: Adventurer
to element at: EDITORGUI/Menubar/Creatures/PopupMenu4 since an Element with
that name is already attached.
EditorMode is built anew every time the editor is entered, and its constructor
fills the Creatures menu with one item per creature definition, the recently
used files menu and the Seats menu. The window it fills them into belongs to the
Gui and lives as long as the game does, so the second visit finds all of them
already there. CEGUI refuses a second child of the same name by throwing, and
nothing catches that before it reaches main().
Two of those three menus already had a function to empty them, used when their
contents change while the editor is running, but it was never called on the way
in. The creature list had none, so it moves out of the constructor into the same
install and uninstall pair as the others, and all three are now emptied before
being filled. GameMode has the same kind of list, of the seats in the game, and
already removes it in its destructor, which is why only the editor is affected.
Emptying detaches the old items without destroying them, which is what the
existing functions do: one of them is called from the click handler of an item
it is removing, and destroying a window in the middle of dispatching its own
event would not end well.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit 8ec6c20)
Entering the editor a second time now segfaults on its first frame, reading address 0x10 inside DebugDrawer::build() called from EditorMode::onFrameStarted. RenderManager makes the debug drawer along with the scene, in createScene(), which the ODFrameListener constructor calls once for the whole run of the game, and destroys it in its own destructor. EditorMode's destructor deleted it too, every time the editor was left. Ogre::Singleton clears its instance pointer as it goes, so the second editor session found nothing there and drew through it anyway: getSingleton() returned a null reference and build() read its manual object, which sits at offset 16 of a DebugDrawer, from address 0x10. The editor still clears the drawer of what it left behind, which is its own, and checks first, since at shutdown the render manager may already have taken it. This was hiding behind the exception fixed in the previous commit, which killed the game earlier in the same sequence, while EditorMode was still being built. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> (cherry picked from commit 893df06)
The waves of a wave portal could only be written by hand in the level file. They are now edited from the editor: point at a portal, press P, and a window shows the turns between waves, the strategy, the attack range and the target teams, along with the list of waves and the creatures of each of them. A client is never told about the rooms of a map, only about what its tiles look like, and the waves are not part of what a room sends anyway. So the editor names the portal to the server by one of its tiles and asks for the waves; the server answers with them, and sends back what the player applied. The level is saved from the server side, so that is where the change has to land. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> (cherry picked from commit a548707)
|
|
||
| // A client does not get the rooms themselves, only what its tiles look like, so this is | ||
| // as much as the editor can tell on its own. The server has the last word. | ||
| if(tile->getTileVisual() != RoomPortalWave::mRoomVisual) |
There was a problem hiding this comment.
For some reason it always enters this branch -- that is a window for "creatures waves " never opens, and at the hand it is written : "Point at a wave portal to edit its waves" regardless the cursor is over the WavePortal or not.....
There was a problem hiding this comment.
Fixed in 4db4c97 by removing that branch altogether. The check compared the client's tile visual against portalWaveRoom, and as you saw, the client's visuals cannot be trusted for this: a client is only ever told what its tiles look like, never which room covers them. So the editor now always asks the server, whatever the tile, and the server answers with the waves, or with an empty room name when the tile holds no wave portal — only then is the "Point at a wave portal" hint shown. The server checks the real room on the tile (getCoveringRoom()), so pressing P over a portal opens the window and pressing it anywhere else shows the hint, with no guessing on the client.
I also merged the current shaders-improvement into this branch (5737d2a, clean merge), so the PR now builds with the console-test fix and the other merged work; all 10 tests pass here, including the five that run against a live headless server.
The editor's P shortcut refused to ask about any tile the client did not believe looked like a wave portal, and that belief proved wrong: the check compared against the tile visual, and the window then never opened at all, with the "Point at a wave portal" hint shown even over a portal. The client is only ever told what its tiles look like, never which room covers them, so it has no reliable way to tell. The server does, and it is also the only side that knows the waves. So the editor now always asks, and the server answers with the waves, or with an empty room name when the tile holds no wave portal, in which case the editor shows the hint. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JiKh7f4nenYBTjhJfAGa3y
…editor-improvements
|
git cherry-pick ..Upabjojr/split/editor-improvements [...] I am such a lamer, why does the cherry-pick fails here and what is this -m option I should somehow use ? |
|
The bug seems to be located in here : ` //! \brief Finds the wave portal the editor is talking about. The editor names it by one of getType() seems to return RoomType::portal , not portalWave :( |
The editor offers two rooms of its own, a dungeon temple and a portal, so a wave portal could only ever be edited in a level that already had one. Add a third button for it, next to the portal, drawn with the portal's glyph in red so the two cannot be confused. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JiKh7f4nenYBTjhJfAGa3y
|
Nothing lame about it — A normal commit has one parent, so "the changes this commit made" is well defined. A merge has two, so the same phrase means nothing until you say changes with respect to which side. That is what Here you do not want it at all. The range you gave ended at 5737d2a, which is me merging your and you are done — nothing is missing. If you would rather not deal with the merge commit at all, |
|
Your screenshot is Forgotten treasures, with the cursor at x:85, y:65. In
Which leaves the real problem, and it is a fair one: the editor could not create a wave portal in the first place. The room buttons the editor shows come from the skill list, and a wave portal is not a skill, so it was only ever shown through the two hand-written buttons for a dungeon temple and a portal. There was no third one. The only way to reach the wave window was to open one of those five levels and point at a portal that was already there — which is not something anyone should have to know. 4a44d71 adds the missing button, next to the portal in the Rooms tab. It draws the portal's own glyph in red so the two are not mistaken for each other, and its tooltip says what it builds. Place it like the portal (it claims its tiles for the selected seat), then press P over it: the window opens on an empty wave list, ready to be filled in. If you would rather test on an existing level, |
|
Great, great I have look over that and don't see any errors so far and at least I know for now that a special PortalWave exisits in the game :). I now have a lot's of work in my real life but in a few days I will come back to the issue. The only remark is : we start to create a glue language to describe what the waves of creatures/monsters should be. But the glue language of choice for ODP is Python ;) .... Think about that and join our discord channel to exchange the opinions. |

Eight commits improving the map editor:
Note for merge order: trivial adjacent-lines conflicts with the user-data-folder PR (
ODServer.cpp) and the cross-platform PR (EditorMode.cpp).Split out of #16 so each topic can be reviewed on its own. Merging all of the split PRs reproduces the tree of #16 exactly.
🤖 Generated with Claude Code