diff --git a/README.md b/README.md index 7cf729ac..3f970d59 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,18 @@ Configuration example: //$DF Send Player Stats Message: true // Send a chat message to players when they join the server ($PLAYER is replaced by player name) //$DF Welcome Message: "Hello $PLAYER!" + // Reward a player for a successful kill + $DF Kill Reward: + // Increase player health or armor if health is full (armor delta is halved) + +Effective Health: 0 + // Increase player health + +Health: 0 + // Increase player armor + +Armor: 0 + // Limit health reward to 200 instead of 100 + +Health Is Super: + // Limit armor reward to 200 instead of 100 + +Armor Is Super: Building diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 420e67ef..375c7e67 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -36,7 +36,8 @@ Version 1.8.1 (not released yet) - Fix quiet 3D sounds being often skipped when EAX is enabled, e.g. first miner in L1S1 (DF bug) - Allow saving in training levels - Fix final level time left count-down in multi using wrong font (DF bug) -- Add Spawn Life/Armor settings for dedicated servers +- Add Spawn Health/Armor settings for dedicated servers +- Add Kill Reward settings for dedicated servers Version 1.8.0 (released 2022-09-17) ----------------------------------- diff --git a/game_patch/multi/kill.cpp b/game_patch/multi/kill.cpp index 70f701e0..c833bae5 100644 --- a/game_patch/multi/kill.cpp +++ b/game_patch/multi/kill.cpp @@ -9,6 +9,7 @@ #include "../rf/localize.h" #include "../rf/multi.h" #include "../rf/weapon.h" +#include "server_internal.h" bool kill_messages = true; @@ -103,6 +104,32 @@ void print_kill_message(rf::Player* killed_player, rf::Player* killer_player) rf::multi_chat_print(msg, color_id, prefix); } +void multi_apply_kill_reward(rf::Player* player) +{ + rf::Entity* ep = rf::entity_from_handle(player->entity_handle); + if (!ep) { + return; + } + + const auto& conf = server_get_df_config(); + + float max_life = conf.kill_reward_health_super ? 200.0f : ep->info->max_life; + float max_armor = conf.kill_reward_armor_super ? 200.0f : ep->info->max_armor; + + if (conf.kill_reward_health > 0.0f) { + ep->life = std::min(ep->life + conf.kill_reward_health, max_life); + } + if (conf.kill_reward_armor > 0.0f) { + ep->armor = std::min(ep->armor + conf.kill_reward_armor, max_armor); + } + if (conf.kill_reward_effective_health > 0.0f) { + float life_to_add = std::min(conf.kill_reward_effective_health, max_life - ep->life); + float armor_to_add = std::min((conf.kill_reward_effective_health - life_to_add) / 2, max_armor - ep->life); + ep->life += life_to_add; + ep->armor += armor_to_add; + } +} + void on_player_kill(rf::Player* killed_player, rf::Player* killer_player) { if (kill_messages) { @@ -121,6 +148,8 @@ void on_player_kill(rf::Player* killed_player, rf::Player* killer_player) else { rf::player_add_score(killer_player, -1); } + + multi_apply_kill_reward(killer_player); } } diff --git a/game_patch/multi/server.cpp b/game_patch/multi/server.cpp index 1bdc2fe6..f9744150 100644 --- a/game_patch/multi/server.cpp +++ b/game_patch/multi/server.cpp @@ -76,7 +76,7 @@ void load_additional_server_config(rf::Parser& parser) g_additional_server_config.spawn_protection_duration_ms = parser.parse_uint(); } - if (parser.parse_optional("$DF Spawn Life:")) { + if (parser.parse_optional("$DF Spawn Health:")) { g_additional_server_config.spawn_life = {parser.parse_float()}; } @@ -172,6 +172,24 @@ void load_additional_server_config(rf::Parser& parser) g_additional_server_config.welcome_message = welcome_message.c_str(); } + if (parser.parse_optional("$DF Kill Reward:")) { + if (parser.parse_optional("+Effective Health:")) { + g_additional_server_config.kill_reward_effective_health = {parser.parse_float()}; + } + if (parser.parse_optional("+Health:")) { + g_additional_server_config.kill_reward_health = {parser.parse_float()}; + } + if (parser.parse_optional("+Armor:")) { + g_additional_server_config.kill_reward_armor = {parser.parse_float()}; + } + if (parser.parse_optional("+Health Is Super:")) { + g_additional_server_config.kill_reward_health_super = {parser.parse_bool()}; + } + if (parser.parse_optional("+Armor Is Super:")) { + g_additional_server_config.kill_reward_armor_super = {parser.parse_bool()}; + } + } + if (!parser.parse_optional("$Name:") && !parser.parse_optional("#End")) { parser.error("end of server configuration"); } diff --git a/game_patch/multi/server_internal.h b/game_patch/multi/server_internal.h index 0cdc5894..71317375 100644 --- a/game_patch/multi/server_internal.h +++ b/game_patch/multi/server_internal.h @@ -51,6 +51,11 @@ struct ServerAdditionalConfig bool stats_message_enabled = true; std::string welcome_message; bool weapon_items_give_full_ammo = false; + float kill_reward_health = 0.0f; + float kill_reward_armor = 0.0f; + float kill_reward_effective_health = 0.0f; + bool kill_reward_health_super = false; + bool kill_reward_armor_super = false; }; extern ServerAdditionalConfig g_additional_server_config;