Use yellow-orange star icon to mark favorite servers in the server browser instead of using the heart icon. The heart icon is now only used for servers with friends.
Tweak color of the star icon used for skin favorites so it's slightly more orange instead of pure yellow.
Free up space for up to three more server browser tabs of the same size (on 5:4 resolutions), i.e. tabs for configurable communities.
Remove the additional server browser icon tab on the right side. Remove the purely visual Demo and News tabs which were only shown when the respective page is already active. Instead, always show all server browser tabs when offline.
The `IClient::Disconnect` function is always called at the beginning of the `IClient::Connect` function. The `IClient::Disconnect` function calls `IClient::DisconnectWithReason`, if the client is not already offline, which performs cleanup of temporary commands and demo recorders already, so the same cleanup in the `Connect` function is unnecessary. An assertion is added to ensure that the client was properly disconnected before connecting. Connecting while the client is already quitting or restarting is now prevented, as the client state cannot be changed once set to quitting or restarting.
By adding `CDataFileWriter::ECompressionLevel` to replace usage of zlib internal compression levels in the `CDataFileWriter` API.
Use `std::numeric_limits<int>::max()` instead of `INT_MAX` in one case where the latter was only declared by the transitive zlib include. The `limits` header is already included and its use is more fitting for C++ code.
The server community was only initialized when receiving server info. This caused servers for which no server info is received to be hidden when using the community filter. Now the community filter also works correctly for servers for which no ordinary server info is received, by initializing the community already when adding server entries to the list.
Closes#7776.
Adapt the `CDataFileReader::GetItem` function so it optionally also returns a `CUuid` for UUID-based map items, including for items with unknown UUIDs where the item type will be `-1`. Adapt the `CDataFileWriter::AddItem` function so it optionally also accepts a `CUuid` which will be used if the item type is `-1`.
The additional checks for invalid map item types in the map tools are removed again and instead the new UUID parameters are used so map items with unknown UUIDs are written back to maps correctly.
Closes#7701.
Files were not being truncated on Windows anymore when using `io_open` with `IOFLAG_WRITE` due to a regression from #7254. Instead, the existing file contents were kept and the file pointer was set to the beginning of the file.
This caused broken demo files to be created (#7349) when recording a shorter demo with the same filename as an existing longer demo. It also caused the map tools to produce maps with additional junk data at the end, if an existing map is overridden by a smaller map.
This is fixed by using the creation disposition `CREATE_ALWAYS` instead of `OPEN_EXISTING` with [`CreateFileW`](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew), which ensures that a file is always created and truncated.
A regression test case is added, which fails without this change.
Add separate `IGraphics::LoadTextureRawMove` function with non-`const` `void *pData` argument in addition to existing `LoadTextureRaw` function with `const void *pData` argument. The former function takes ownership of the data and avoids copying the texture data into an additional buffer, if the texture data is already in RGBA format. Non-RGBA texture data always needs to be converted and therefore also copied.
The `LoadTextureRaw` function is split into smaller functions to share common code with the `LoadTextureRawMove` function. Alternatively to this, a flag `TEXLOAD_MOVE_DATA` could have been added to the existing `LoadTextureRaw` function, which would have required the use of `const_cast` to free the texture data.
Unset the assertion handler before shutting down the kernel (including graphics) and client. Otherwise the assertion handler itself crashes when assertion errors happen after the graphics/client have been destroyed.
The selection in the kickvote/specvote menu was reset to the first player when the previously selected player leaves or if the filter string does not match it. Now the selection is cleared in these cases, to prevent players from accidentally starting kickvotes/specvotes on the wrong player.
Remove unnecessary `static` variable. Improve readability by not nesting post-increment in another statement.
Add color palette with up to 8 colors to editor toolbar. The palette colors work like regular color picker buttons, so they open a color picker popup on click and the value can be copied and pasted with Ctrl+Right click and Ctrl+Left click respectively. Less palette colors are shown when not enough space is available (with 5:4 resolutions).
Add color pipette which allows selecting any color displayed on the screen. Selecting a color with the pipette adds the new color to the palette and shifts the other colors to the right. The selected color is also copied to the clipboard immediately. The hotkey Ctrl+Shift+C is added to toggle the color pipette, which allows using the color pipette in popups and dialogs.
The implement this, the function `IGraphics::ReadPixel` and the command `SCommand_TrySwapAndReadPixel` are added to read a specified pixel's color from the backbuffer. Like the screenshot command, this command also requires a swap operation to be performed before the correct pixel color can be read with the Vulkan backend. The `ReadPixel` function therefore accepts a pointer to a `ColorRGBA` that will be filled after the next swap operation.
Closes#7430.
Replace linear search for free sample index with free list. This brings sound sample index allocation down to constant complexity independent of the number of allocated sounds. On average the time to allocate sound samples is reduced by around 75% (843µs down to 223µs). For perspective, the time to load all default sounds on client launch is reduced by around 15ms (although this does not significantly affect launch time due to threaded loading).
The lock needs to be owned when accessing the sound voices. Calling `IsPlaying` is redundant, as the loops effectively check whether the sample is playing.
Ensure that the UI mouse position stays inside the UI screen rect. Previously, the mouse was not considered to be inside the UI screen when all the way at the right or bottom edge. This caused the map editor tooltip to not be shown when the mouse is all the way at the right side of the map editor view. This is a cleaner fix for #4553 which reverts the previous workaround from #6423.
Add dropdown menus for changing animation and grid settings (i.e. animation speed and grid size) instead of conditionally showing more buttons for this directly in the menu bar. This frees up space in the menu bar, which is currently full on 5:4 resolutions.
The icons previously used for the default animation/grid buttons are now used for the main buttons that toggle animation/grid instead of using text.
Support setting lower animation speeds with the plus and minus buttons by adjusting the step size when the animation speed is low.
Support setting arbitrary animation speed by text input.
Render one quad for each line of the text selection instead of rendering one quad per selected character.
This increases the average FPS when the console is open and all text is selected by around 10% (from around 849 to around 943 FPS) (on my machine, in release mode).
When normalizing color components in the engine graphics, round the components to the nearest integer instead of rounding down. Otherwise the color that is rendered in color pickers may be off by 1 in any of its RGB components from the color that the color picker displays as text (hex string and individual components). The slightly incorrect color can be confirmed by creating a screenshot or otherwise reading the backbuffer (planned editor pipette feature).
This should not change map rendering, since maps already store quantized RGBA values on which the rounding mode should have no effect. It may however slightly change appearance of colors in all other places (at most +1 in every RGB component).
The individual color components were rounded down when being displayed on their own in color pickers, whereas the components are rounded to the nearest integer when packing the colors into the hex string. This was causing minor discrepancies between the color being displayed/saved as hex and the individual components. Rounding the components when packing is necessary to reduce the error when converting between color spaces.
Add tabs to player and tee settings pages to switch between player (main) and dummy settings instead of using a checkbox for this, to improve the usability.
Improve layout of tee settings page, especially with 5:4 resolutions, where the eye selector previously overlapped with other UI elements. Decrease size of eye selector and make better use of empty space overall. Use more space for skin selector instead of showing empty space when "Use custom colors" is disabled.
Show favorite skin buttons also when hovering list items to make it easier to discover the feature. Add small highlight color to favorite skin buttons when hovering them.
The text color was previously set and reset for every individual number being rendered for non-empty tele, speedup, switch and tune tiles. The color is the same for all tiles from each entities layer, so most of these `TextColor` calls are unnecessary. Now the text color is only set and reset once when rendering each entities layer.
Let's say you have this bind:
```bind x +toggle cl_dummy_hammer 1 0```
and you set cl_dummy_control to 1.
When you press the bind i mentioned above, and then release, the dummy will hammer where he is looking (not at you). So, in total, there will be two hammers. One hammer when you press down the button and the dummy hammers towards you, and then another hammer when you release the button and the dummy hammers where he is looking.
This fixes it, and also makes sure it does not conflict with cl_dummy_copy_moves (as if it is enabled and cl_dummy_control is enabled, the dummy will not copy fire, hook, or jump) so I made sure it keeps this functionality as it's pretty cool.
This does not fix any other bugs yet, maybe I will fix those in the future but we'll see. Any bug you may encounter with this change is also probably present in the main branch, such as resetonswitch not working perfectly with dummy_control, but if you do find something different then let me know.
According to the Vulkan specification, the struct `VkBufferImageCopy` is used only for `vkCmdCopyBufferToImage` and `vkCmdCopyImageToBuffer`. The variable `Region` is only initialized but not passed to either of those functions.
- Use existing functions from `system.h`
- Use sorting from `<algorithm>`
- Don't recall `ListDirectory` for every removal, which caused the client to hang previously with a lot of files.
Consider line spacing to belong to the previous line when calculating and rendering text selection. Instead of handling spacing between entries separately in the console, also include line spacing for the last line in the height calculation. Pixel align the line spacing in addition to the font size, as previously some gaps between the entries were larger than others due to missing pixel alignment. This allows rendering the text selection in the console smoothly without any gaps between the console entries/lines.
Closes#7617.
Reduce duplicate code.
Replace `clampf` function with `NormalizeColorComponent` function that convert color component from `float` to `unsigned char`.
Use `size_t` instead of `int`.
The `mem_copy` function does not respect zero termination so it reads beyond the size of the source buffer, if it's smaller than the destination buffer.
Favorite skin names were previously not escaped as intended when saving, as the variable `aNameEscaped` was unused so the original skin name was saved instead of the escaped one. Escaping is not really necessary, as skins should not contain `\` and `"` anyway and it was only possible to add such favorites through the console or config files. Instead of escaping the favorite skin names when saving, now favorite skin names are validated when they are added so no escaping is necessary. Skins names are considered valid when they have a length of 1-23 bytes and don't contain the characters `/`, `\` and `"`.
All `map_*` tools were crashing with the assertion `Invalid type` when used on maps that contain unknown UUID-based map items. When the UUID cannot be resolved, the type `-1` is returned by the `GetItem` function. The assertion predates UUID map items, so this crash has likely existed since the introduction of UUID map items. The editor was not affected and has instead always discarded map items that it does not support. The tools will now also discard map items with unknown UUIDs.
See #7669.
The current mouse-based console selection was not being adjusted anymore when new lines are added to the console, as the `m_NewLineCounter` variable was decremented to `0` before the relevant check for `m_NewLineCounter > 0`.
The selection is only cleared because it would be incorrect after scrolling, but it doesn't need to be cleared if the scroll position does not change, e.g. when pressing Home while already at the top of the backlog.
Do not use the `CMapItemSound::m_SoundDataSize` value as it is redundant. This value could also be incorrect because it can be freely set by the map creator (tool).
Instead, use the map/datafile function `GetDataSize` to get the true size of the sound data in the file.
The `m_SoundDataSize` value is still written to map files for compatibility with old versions.
Replace unnecessary `gameclient.h` include with more specific includes.
Fix storage creation error message not being logged as the logger was initialized after checking for the failed storage creation. However, in this case we want to avoid non-error log messages so the tool's output is only the extracted demo chat, except in error cases.
Rename `Process` function to `ExtractDemoChat` and make it `static` to avoid exporting it.
Use `log_error` instead of `dbg_msg`.
Add a proper kernel interface `INotifications` for the notifications component instead of using a C style interface.
Add parameter for the application name when initializing notifications to avoid hardcoding the application name.
The implementation for macOS is kept in Objective-C and a TODO is added, as the API we are currently using appears to be deprecated.
Fix Ctrl+C not working to copy text in console when the command input already contains text, as the changed flag was never reset properly.
Fix scroll position of UI editboxes not being updated when moving cursor without changing text.
Fix lineinput selection change being detected as content change, causing the editor modified state to be set incorrectly.
Fix cursor blinking not being disabled correctly after changing text without changing cursor position.
/home/deen/isos/ddnet/ddnet-source/src/engine/client/discord.cpp: In member function ‘bool CDiscord::Init(FDiscordCreate)’:
/home/deen/isos/ddnet/ddnet-source/src/engine/client/discord.cpp:39:17: error: ‘mem_zero’ was not declared in this scope
39 | mem_zero(&m_ActivityEvents, sizeof(m_ActivityEvents));
| ^~~~~~~~
Now `CGameContext` no longer assumes the `IGameController`
declined the team join due to slots.
This enables custom gametypes to disallow joining the game if the player
died, an active tournament is running or the player is not logged in
yet. And then the controller can print the correct error message
accordingly.