Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
/research
/out

# Local build logs
/_build_exit.txt
/_build_release.log

# Visual Studio
*.sln
*.VC.*
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Most important:

Multiplayer:
* Increased (and configurable) tick rate
* TOML-based `ADS` dedicated server configuration with per-level rules, on-demand reloading, rule presets, and on-the-fly game type switching
* TOML-based `ADS` dedicated server configuration with per-level rules, on-demand reloading, and on-the-fly game type switching
* "GunGame" game mode
* Competitive match framework including "ready up" system and overtime
* Improved gaussian distribution method for bullet spread
Expand Down
6 changes: 6 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Version 1.4.0 (Lupin): Not yet released
- Servers describe their votable levels, game types, and mutator options to clients
- `Level` and `Match` can now select a game type and any number of mutators (with their options) for the voted level
- Add a vote panel for calling any vote the server allows, opened during gameplay with the bindable `Call Vote Menu` control (`F4` by default)
- The vote panel pre-selects the chosen level's game type and the server's currently active mutator set, with buttons to reset the game type and restore the `Base` or `Current` mutator set
- Vote HUD notification now shows live tally, time remaining, and whether you have already voted
- Add FactionFiles-integrated multiplayer statistics tracking
- Dedicated servers with a configured `fflink_gsk` report a gameplay event stream to FactionFiles
Expand Down Expand Up @@ -114,6 +115,7 @@ Version 1.4.0 (Lupin): Not yet released
- Add `spectate_cameras` console command to toggle showing camera meshes at static camera locations while free look spectating
- Deprecated and removed legacy GunGame dedicated server config items now that `GG` is an actual gametype
- Deprecated and removed legacy critical hits dedicated server config items now that it is a mutator
- Deprecated and removed the `rules_presets` dedicated server config item and its `rules_preset_aliases` table
- Default inactivity tracking for players in dedicated servers to `true`, but kicking inactive players to `false`
- Add `-debug` command line switch to enable additional debug logging, intended to help identify long-standing netcode issues that are difficult to nail down.
- Add automatic team balance option which handles unbalanced teams mid-game and stops players from switching teams if it would unbalance them
Expand Down Expand Up @@ -145,6 +147,8 @@ Version 1.4.0 (Lupin): Not yet released
- Support af://demo/ID on the af protocol to play demos from FactionFiles
- Set client netfps to 40, server default netfps to 40 (configurable)
- Make color pickers in the level editor open at the current color instead of black
- A voted level now derives its rules from the server's base rules plus the voted mutator set, rather than inheriting the rules of whichever rotation slot happens to name that level
- `sv_gametype` against a level in the rotation now rebuilds the rules from the base rules for the new game type instead of retargeting the old game type's rules in place

[@is-this-c](https://github.com/is-this-c)
- Rewrite `VArray` to fix crashes due to MinGW
Expand Down Expand Up @@ -226,6 +230,8 @@ Version 1.4.0 (Lupin): Not yet released
- Fix particle emitters created from `emitters.tbl` templates inheriting uninitialized UID and `Active Distance` values that could make their particles silently fail to spawn in rare cases
- Fix spacebar (when bound to `Jump`) moving freelook camera upward when typing in chat
- Fix crash risk when leaving a match or changing levels by keeping animation skeletons loaded while animation instances are still playing them, instead of unloading as soon as no character references them
- Fix dedicated servers not loading `alpinefaction.vpp`, which prevented `af_level_quirks.tbl` from loading and left known run maps unrecognized
- Fix potential crash when an Alpine options `.tbl` file contains an unrecognized option name

[@is-this-c](https://github.com/is-this-c)
- Clear cached server config output after a shuffle of a server's rotation
Expand Down
9 changes: 4 additions & 5 deletions game_patch/graphics/gr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,10 +618,9 @@ ConsoleCommand2 pow2_tex_cmd{
void evaluate_pow2tex(const rf::String& level_filename) {
// if dbg_pow2tex is active, use manual override instead of level filename lookup
if (!override_pow2tex) {
bool should_p2t_fix = false;

if (is_p2t_fix_level(level_filename)) {
should_p2t_fix = true;
const bool should_p2t_fix = is_p2t_fix_level(level_filename);
// Renderer-only, so a dedicated server has nothing to report.
if (!rf::is_dedicated_server && should_p2t_fix) {
rf::console::print("Applying power of 2 texture fix to known affected level {}", level_filename);
}

Expand All @@ -631,7 +630,7 @@ void evaluate_pow2tex(const rf::String& level_filename) {
// Always sync D3D11 state with current p2t value at level load
if (g_game_config.renderer == GameConfig::Renderer::d3d11) {
gr::d3d11::set_pow2_tex_active(rf::gr::d3d::p2t != 0);
if (is_sky_fix_level(level_filename)) {
if (!rf::is_dedicated_server && is_sky_fix_level(level_filename)) {
rf::console::print("Applying sky fix to known affected level {}", level_filename);
}
}
Expand Down
9 changes: 6 additions & 3 deletions game_patch/hud/multi_spectate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1637,9 +1637,12 @@ void multi_spectate_process_bind_input()
const bool player_mode = g_spectate_mode_enabled; // first/third person
const bool static_mode = g_spectate_static_active; // static cameras
const bool bindable = player_mode || static_mode;
// Still consume the numpad counters while typing (so they don't queue up), but don't act on
// them - the console/chat-say box uses the separate character buffer for typing.
const bool typing = rf::console::console_is_visible() || rf::multi_chat_is_say_visible();
// Still consume the numpad counters while an overlay owns input (so they don't queue up), but
// don't act on them - the console/chat-say box reads the separate character buffer, and the
// vote panel's own rows sit under the numpad keys whether or not a text box has focus.
const bool typing = rf::console::console_is_visible() ||
rf::multi_chat_is_say_visible() ||
vote_panel_is_gameplay_overlay_active();

if (rf::key_get_and_reset_down_counter(rf::KEY_PADENTER) > 0 && !typing) {
g_spectate_bind_dialog_open = bindable && !g_spectate_bind_dialog_open;
Expand Down
6 changes: 4 additions & 2 deletions game_patch/input/control_input_filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ ControlInputInjection resolve_injection(rf::ControlConfig* ccp, rf::ControlConfi
FunHook<bool(rf::ControlConfig*, rf::ControlConfigAction, bool*)> control_config_check_pressed_hook{
0x0043D4F0,
[](rf::ControlConfig* ccp, rf::ControlConfigAction action, bool* just_pressed) {
// A veto owns the action completely: the engine is not consulted and no
// injection can lift it.
// A veto owns the action completely: no injection can lift it. The engine is
// still called, for every veto participant, so the press is consumed rather
// than piling up and firing all at once when the veto lifts.
if (action_is_vetoed(ccp, action)) {
control_input_filter_check_pressed_unfiltered(ccp, action, nullptr);
if (just_pressed) {
*just_pressed = false;
}
Expand Down
6 changes: 4 additions & 2 deletions game_patch/input/key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,9 +524,11 @@ CodeInjection controls_process_chat_menu_patch{
const bool chat_menu_numeric_capture_active =
get_chat_menu_is_active()
&& !rf::console::console_is_visible()
&& !rf::multi_chat_is_say_visible();
&& !rf::multi_chat_is_say_visible()
&& !vote_panel_is_capturing_text();
const bool waypoint_link_numeric_capture_active =
waypoints_utils_link_editor_text_input_active();
waypoints_utils_link_editor_text_input_active()
&& !vote_panel_is_capturing_text();

// Consume top-row number keys for active overlay input modes so they do
// not trigger gameplay bindings.
Expand Down
9 changes: 5 additions & 4 deletions game_patch/misc/alpine_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -848,12 +848,13 @@ void load_single_af_options_file(const std::string& file_name)
}

auto meta_it = option_metadata.find(option_name);
const bool meta_found = meta_it != option_metadata.end();

// Allow any af_client*.tbl file for options designated to af_client.tbl
bool is_af_client_variant = (meta_it->second.filename == "af_client.tbl" &&
file_name.rfind("af_client", 0) == 0 && file_name.ends_with(".tbl"));
const bool is_af_client_variant = (meta_found && meta_it->second.filename == "af_client.tbl" &&
file_name.rfind("af_client", 0) == 0 && file_name.ends_with(".tbl"));

if (meta_it != option_metadata.end() &&
if (meta_found &&
(meta_it->second.filename == file_name || is_af_client_variant) &&
(!rf::is_dedicated_server || meta_it->second.apply_on_server)) {

Expand All @@ -866,7 +867,7 @@ void load_single_af_options_file(const std::string& file_name)
xlog::debug("Option ID {} marked as loaded", static_cast<std::size_t>(metadata.id));
}
}
else if (meta_it != option_metadata.end()) {
else if (meta_found) {
if (meta_it->second.filename != file_name && !is_af_client_variant) {
xlog::warn("Option {} in {} skipped (wrong alpine tbl file)", option_name, file_name);
}
Expand Down
2 changes: 1 addition & 1 deletion game_patch/misc/alpine_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1625,7 +1625,7 @@ void alpine_player_settings_save(rf::Player* player)
const std::vector<std::string>& unreadable_saved_votes = saved_votes_unparsed();
if (!saved_votes.empty() || !unreadable_saved_votes.empty()) {
file << "\n[SavedVotes]\n";
file << "; Format is SavedVote{N}=1|{Name}|{Type}|{Level}|{GameType}|{TeamSize}|{ExtendMinutes}|{Mutators}\n";
file << "; Format is SavedVote{N}=2|{Name}|{Type}|{Level}|{GameType}|{TeamSize}|{ExtendMinutes}|{Mutators}|{MutatorsExplicit}\n";

for (size_t i = 0; i < saved_votes.size(); ++i) {
file << "SavedVote" << i << "=" << saved_vote_encode(saved_votes[i]) << "\n";
Expand Down
Loading
Loading