mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 07:03:16 +00:00
add perma death option, make cessation nicer, fix spectator shields and cursors not appearing sometimes, make default settings transfer nicer
This commit is contained in:
parent
79e8f73d63
commit
2fc0e76f2c
10 changed files with 331 additions and 131 deletions
|
@ -99,6 +99,7 @@ local_health_desc_2 = There is a respawn mechanic.
|
|||
Health-percent-lost-on-reviving = HP percent lost on reviving
|
||||
global_hp_loss = Lose HP globally
|
||||
no_material_damage = No material damage
|
||||
perma_death = Perma death
|
||||
shared_health_desc_1 = Health is shared, but scales with player count.
|
||||
shared_health_desc_2 = Percentage-based damage and full heals are adjusted.
|
||||
shared_health_desc_3 = The original mode.
|
||||
|
|
|
@ -63,15 +63,39 @@ pub(crate) enum GameMode {
|
|||
// MestariMina, // TODO later
|
||||
}
|
||||
|
||||
#[derive(Debug, Decode, Encode, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Decode, Encode, Clone, Serialize, Deserialize, PartialEq, Default)]
|
||||
#[serde(default)]
|
||||
pub struct GameSettings {
|
||||
seed: u64,
|
||||
debug_mode: Option<bool>,
|
||||
world_sync_version: Option<u32>,
|
||||
player_tether: Option<bool>,
|
||||
tether_length: Option<u32>,
|
||||
use_constant_seed: bool,
|
||||
item_dedup: Option<bool>,
|
||||
enemy_hp_mult: Option<f32>,
|
||||
world_sync_interval: Option<u32>,
|
||||
game_mode: Option<GameMode>,
|
||||
friendly_fire: Option<bool>,
|
||||
friendly_fire_team: Option<i32>,
|
||||
chunk_target: Option<u32>,
|
||||
enemy_sync_interval: Option<u32>,
|
||||
randomize_perks: Option<bool>,
|
||||
progress: Vec<String>,
|
||||
max_players: Option<u32>,
|
||||
health_per_player: Option<u32>,
|
||||
health_lost_on_revive: Option<u32>,
|
||||
no_material_damage: Option<bool>,
|
||||
global_hp_loss: Option<bool>,
|
||||
perk_ban_list: Option<String>,
|
||||
perma_death: Option<bool>,
|
||||
}
|
||||
|
||||
pub struct DefaultSettings {
|
||||
debug_mode: bool,
|
||||
world_sync_version: u32,
|
||||
player_tether: bool,
|
||||
tether_length: u32,
|
||||
use_constant_seed: bool,
|
||||
item_dedup: bool,
|
||||
enemy_hp_mult: f32,
|
||||
world_sync_interval: u32,
|
||||
|
@ -81,24 +105,22 @@ pub struct GameSettings {
|
|||
chunk_target: u32,
|
||||
enemy_sync_interval: u32,
|
||||
randomize_perks: bool,
|
||||
progress: Vec<String>,
|
||||
max_players: u32,
|
||||
health_per_player: u32,
|
||||
health_lost_on_revive: u32,
|
||||
no_material_damage: bool,
|
||||
global_hp_loss: bool,
|
||||
perk_ban_list: String,
|
||||
perma_death: bool,
|
||||
}
|
||||
|
||||
impl Default for GameSettings {
|
||||
impl Default for DefaultSettings {
|
||||
fn default() -> Self {
|
||||
GameSettings {
|
||||
seed: 0,
|
||||
DefaultSettings {
|
||||
debug_mode: false,
|
||||
world_sync_version: 2,
|
||||
player_tether: true,
|
||||
tether_length: 2048,
|
||||
use_constant_seed: false,
|
||||
item_dedup: true,
|
||||
randomize_perks: true,
|
||||
enemy_hp_mult: 1.0,
|
||||
|
@ -108,13 +130,13 @@ impl Default for GameSettings {
|
|||
friendly_fire_team: 0,
|
||||
chunk_target: 24,
|
||||
enemy_sync_interval: 3,
|
||||
progress: Vec::new(),
|
||||
max_players: 250,
|
||||
health_per_player: 100,
|
||||
health_lost_on_revive: 0,
|
||||
no_material_damage: false,
|
||||
global_hp_loss: false,
|
||||
perk_ban_list: String::new(),
|
||||
perk_ban_list: "GLOBAL_GORE,GLASS_CANNON,REVENGE_RATS,PLAGUE_RATS,VOMIT_RATS,CORDYCEPS,MOLD,FUNGAL_DISEASE,HOMUNCULUS,LUKKI_MINION".to_string(),
|
||||
perma_death: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -498,7 +520,7 @@ impl App {
|
|||
let peer = net::steam_networking::SteamPeer::new_host(
|
||||
steamworks::LobbyType::Private,
|
||||
self.steam_state.as_ref().unwrap().client.clone(),
|
||||
self.app_saved_state.game_settings.max_players,
|
||||
self.app_saved_state.game_settings.max_players.unwrap_or(DefaultSettings::default().max_players),
|
||||
);
|
||||
let netman = net::NetManager::new(PeerVariant::Steam(peer), self.get_netman_init());
|
||||
self.set_netman_settings(&netman);
|
||||
|
@ -720,56 +742,93 @@ impl App {
|
|||
}
|
||||
|
||||
fn show_game_settings(&mut self, ui: &mut Ui, show_local: bool) {
|
||||
let def = DefaultSettings::default();
|
||||
heading_with_underline(ui, tr("connect_settings"));
|
||||
let game_settings = &mut self.app_saved_state.game_settings;
|
||||
ui.label(tr("Game-mode"));
|
||||
ui.radio_value(
|
||||
&mut game_settings.game_mode,
|
||||
GameMode::SharedHealth,
|
||||
tr("Shared-health"),
|
||||
);
|
||||
ui.radio_value(
|
||||
&mut game_settings.game_mode,
|
||||
GameMode::LocalHealth,
|
||||
tr("Local-health"),
|
||||
);
|
||||
{
|
||||
let mut temp = game_settings.game_mode.unwrap_or(def.game_mode);
|
||||
ui.label(tr("Game-mode"));
|
||||
if ui.radio_value(
|
||||
&mut temp,
|
||||
GameMode::SharedHealth,
|
||||
tr("Shared-health"),
|
||||
).changed() || ui.radio_value(
|
||||
&mut temp,
|
||||
GameMode::LocalHealth,
|
||||
tr("Local-health"),
|
||||
).changed() {
|
||||
game_settings.game_mode = Some(temp)
|
||||
}
|
||||
}
|
||||
|
||||
ui.scope(|ui| {
|
||||
ui.set_height(100.0);
|
||||
|
||||
match game_settings.game_mode {
|
||||
match game_settings.game_mode.unwrap_or(def.game_mode) {
|
||||
GameMode::SharedHealth => {
|
||||
ui.label(tr("shared_health_desc_1"));
|
||||
ui.label(tr("shared_health_desc_2"));
|
||||
ui.label(tr("shared_health_desc_3"));
|
||||
ui.add_space(5.0);
|
||||
ui.label(tr("Health-per-player"));
|
||||
ui.add(Slider::new(&mut game_settings.health_per_player, 0..=100));
|
||||
let mut temp = game_settings.health_per_player.unwrap_or(def.health_per_player);
|
||||
if ui.add(Slider::new(&mut temp, 0..=100)).changed() {
|
||||
game_settings.health_per_player = Some(temp)
|
||||
}
|
||||
}
|
||||
GameMode::LocalHealth => {
|
||||
ui.label(tr("local_health_desc_1"));
|
||||
ui.label(tr("local_health_desc_2"));
|
||||
ui.add_space(5.0);
|
||||
ui.label(tr("Health-percent-lost-on-reviving"));
|
||||
ui.add(Slider::new(
|
||||
&mut game_settings.health_lost_on_revive,
|
||||
0..=100,
|
||||
));
|
||||
ui.checkbox(&mut game_settings.global_hp_loss, tr("global_hp_loss"));
|
||||
ui.checkbox(
|
||||
&mut game_settings.no_material_damage,
|
||||
tr("no_material_damage"),
|
||||
);
|
||||
{
|
||||
let mut temp = game_settings.health_lost_on_revive.unwrap_or(def.health_lost_on_revive);
|
||||
if ui.add(Slider::new(
|
||||
&mut temp,
|
||||
0..=100,
|
||||
)).changed() {
|
||||
game_settings.health_lost_on_revive = Some(temp)
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.global_hp_loss.unwrap_or(def.global_hp_loss);
|
||||
if ui.checkbox(&mut temp, tr("global_hp_loss")).changed() {
|
||||
game_settings.global_hp_loss = Some(temp)
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.no_material_damage.unwrap_or(def.no_material_damage);
|
||||
if ui.checkbox(
|
||||
&mut temp,
|
||||
tr("no_material_damage"),
|
||||
).changed() {
|
||||
game_settings.no_material_damage = Some(temp)
|
||||
}
|
||||
}
|
||||
ui.add_space(1.0);
|
||||
{
|
||||
let mut temp = game_settings.perma_death.unwrap_or(def.perma_death);
|
||||
if ui.checkbox(
|
||||
&mut temp,
|
||||
tr("perma_death"),
|
||||
).changed() {
|
||||
game_settings.perma_death = Some(temp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ui.add_space(10.0);
|
||||
ui.label(tr("connect_settings_debug"));
|
||||
ui.checkbox(
|
||||
&mut game_settings.debug_mode,
|
||||
tr("connect_settings_debug_en"),
|
||||
);
|
||||
{
|
||||
let mut temp = game_settings.debug_mode.unwrap_or(def.debug_mode);
|
||||
if ui.checkbox(
|
||||
&mut temp,
|
||||
tr("connect_settings_debug_en"),
|
||||
).changed() {
|
||||
game_settings.debug_mode = Some(temp)
|
||||
}
|
||||
}
|
||||
ui.checkbox(
|
||||
&mut game_settings.use_constant_seed,
|
||||
tr("connect_settings_debug_fixed_seed"),
|
||||
|
@ -780,40 +839,87 @@ impl App {
|
|||
});
|
||||
ui.add_space(10.0);
|
||||
ui.label(tr("connect_settings_max_players"));
|
||||
ui.add(Slider::new(&mut game_settings.max_players, 2..=250));
|
||||
{
|
||||
let mut temp = game_settings.max_players.unwrap_or(def.max_players);
|
||||
if ui.add(Slider::new(&mut temp, 2..=250)).changed()
|
||||
{
|
||||
game_settings.max_players = Some(temp)
|
||||
}
|
||||
}
|
||||
ui.add_space(10.0);
|
||||
ui.label(tr("Amount-of-chunks-host-has-loaded-at-once-synced-enemies-and-physics-objects-need-to-be-loaded-in-by-host-to-be-rendered-by-clients"));
|
||||
ui.add(Slider::new(&mut game_settings.chunk_target, 12..=64));
|
||||
|
||||
{
|
||||
let mut temp = game_settings.chunk_target.unwrap_or(def.chunk_target);
|
||||
if ui.add(Slider::new(&mut temp, 12..=64)).changed() {
|
||||
game_settings.chunk_target = Some(temp)
|
||||
}
|
||||
}
|
||||
ui.add_space(20.0);
|
||||
ui.label(tr("connect_settings_player_tether_desc"));
|
||||
ui.checkbox(
|
||||
&mut game_settings.player_tether,
|
||||
tr("connect_settings_player_tether"),
|
||||
);
|
||||
ui.add(
|
||||
Slider::new(&mut game_settings.tether_length, 10..=5000)
|
||||
.text(tr("connect_settings_player_tether_length")),
|
||||
);
|
||||
{
|
||||
let mut temp = game_settings.player_tether.unwrap_or(def.player_tether);
|
||||
if ui.checkbox(
|
||||
&mut temp,
|
||||
tr("connect_settings_player_tether"),
|
||||
).changed()
|
||||
{
|
||||
game_settings.player_tether = Some(temp)
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.tether_length.unwrap_or(def.tether_length);
|
||||
if ui.add(
|
||||
Slider::new(&mut temp, 10..=5000)
|
||||
.text(tr("connect_settings_player_tether_length")),
|
||||
).changed() {
|
||||
game_settings.tether_length = Some(temp)
|
||||
}
|
||||
}
|
||||
ui.add_space(20.0);
|
||||
ui.checkbox(
|
||||
&mut game_settings.item_dedup,
|
||||
tr("connect_settings_item_dedup"),
|
||||
);
|
||||
ui.checkbox(
|
||||
&mut game_settings.randomize_perks,
|
||||
tr("Have-perk-pools-be-independent-of-each-other"),
|
||||
);
|
||||
ui.horizontal(|ui| {
|
||||
ui.text_edit_singleline(&mut game_settings.perk_ban_list);
|
||||
ui.label("perk ban list, comma seperated");
|
||||
});
|
||||
ui.add(
|
||||
Slider::new(&mut game_settings.enemy_hp_mult, 1.0..=1000.0)
|
||||
.logarithmic(true)
|
||||
.text(tr("connect_settings_enemy_hp_scale")),
|
||||
);
|
||||
ui.checkbox(&mut game_settings.friendly_fire, tr("Enable-friendly-fire"));
|
||||
{
|
||||
let mut temp = game_settings.item_dedup.unwrap_or(def.item_dedup);
|
||||
if ui.checkbox(
|
||||
&mut temp,
|
||||
tr("connect_settings_item_dedup"),
|
||||
).changed() {
|
||||
game_settings.item_dedup = Some(temp)
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.randomize_perks.unwrap_or(def.randomize_perks);
|
||||
if ui.checkbox(
|
||||
&mut temp,
|
||||
tr("Have-perk-pools-be-independent-of-each-other"),
|
||||
).changed() {
|
||||
game_settings.randomize_perks = Some(temp)
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.perk_ban_list.clone().unwrap_or(def.perk_ban_list);
|
||||
ui.horizontal(|ui| {
|
||||
if ui.text_edit_singleline(&mut temp)
|
||||
.changed() {
|
||||
game_settings.perk_ban_list = Some(temp)
|
||||
}
|
||||
ui.label("perk ban list, comma seperated");
|
||||
});
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.enemy_hp_mult.unwrap_or(def.enemy_hp_mult);
|
||||
if ui.add(
|
||||
Slider::new(&mut temp, 1.0..=1000.0)
|
||||
.logarithmic(true)
|
||||
.text(tr("connect_settings_enemy_hp_scale")),
|
||||
).changed() {
|
||||
game_settings.enemy_hp_mult = Some(temp)
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.friendly_fire.unwrap_or(def.friendly_fire);
|
||||
if ui.checkbox(&mut temp, tr("Enable-friendly-fire")).changed() {
|
||||
game_settings.friendly_fire = Some(temp)
|
||||
}
|
||||
}
|
||||
if show_local {
|
||||
heading_with_underline(ui, tr("connect_settings_local"));
|
||||
ui.checkbox(
|
||||
|
@ -1097,10 +1203,14 @@ impl eframe::App for App {
|
|||
ui.add_space(15.0);
|
||||
if netman.friendly_fire.load(Ordering::Relaxed) {
|
||||
let last = self.app_saved_state.game_settings.friendly_fire_team;
|
||||
ui.add(Slider::new(&mut self.app_saved_state.game_settings.friendly_fire_team, -1..=16));
|
||||
let def = DefaultSettings::default();
|
||||
let mut temp = self.app_saved_state.game_settings.friendly_fire_team.unwrap_or(def.friendly_fire_team);
|
||||
if ui.add(Slider::new(&mut temp, -1..=16)).changed() {
|
||||
self.app_saved_state.game_settings.friendly_fire_team = Some(temp);
|
||||
}
|
||||
if last != self.app_saved_state.game_settings.friendly_fire_team
|
||||
|| netman.friendly_fire_team.load(Ordering::Relaxed) == -2 {
|
||||
netman.friendly_fire_team.store(self.app_saved_state.game_settings.friendly_fire_team, Ordering::Relaxed);
|
||||
netman.friendly_fire_team.store(temp, Ordering::Relaxed);
|
||||
}
|
||||
ui.label("what team number you are on, 0 means no team, -1 means friendly");
|
||||
ui.add_space(15.0);
|
||||
|
@ -1462,4 +1572,4 @@ pub fn host_cli(port: u16) {
|
|||
let player_path = netmaninit.player_path.clone();
|
||||
let netman = net::NetManager::new(varient, netmaninit);
|
||||
netman.start_inner(player_path, true).unwrap();
|
||||
}
|
||||
}
|
|
@ -26,11 +26,7 @@ use tungstenite::{accept, WebSocket};
|
|||
|
||||
use crate::mod_manager::ModmanagerSettings;
|
||||
use crate::player_cosmetics::{create_player_png, PlayerPngDesc};
|
||||
use crate::{
|
||||
bookkeeping::save_state::{SaveState, SaveStateEntry},
|
||||
recorder::Recorder,
|
||||
GameSettings, PlayerColor,
|
||||
};
|
||||
use crate::{bookkeeping::save_state::{SaveState, SaveStateEntry}, recorder::Recorder, DefaultSettings, GameSettings, PlayerColor};
|
||||
pub mod messages;
|
||||
mod proxy_opt;
|
||||
pub mod steam_networking;
|
||||
|
@ -133,6 +129,7 @@ pub struct NetManager {
|
|||
pub friendly_fire: AtomicBool,
|
||||
pub ban_list: Mutex<Vec<OmniPeerId>>,
|
||||
pub kick_list: Mutex<Vec<OmniPeerId>>,
|
||||
pub no_more_players: AtomicBool,
|
||||
}
|
||||
|
||||
impl NetManager {
|
||||
|
@ -155,6 +152,7 @@ impl NetManager {
|
|||
friendly_fire: AtomicBool::new(false),
|
||||
ban_list: Default::default(),
|
||||
kick_list: Default::default(),
|
||||
no_more_players: AtomicBool::new(false),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
@ -472,6 +470,7 @@ impl NetManager {
|
|||
.expect("can set write timeout");
|
||||
|
||||
let settings = self.settings.lock().unwrap();
|
||||
let def = DefaultSettings::default();
|
||||
state.try_ws_write(ws_encode_proxy("seed", settings.seed));
|
||||
let my_id = self.peer.my_id();
|
||||
state.try_ws_write(ws_encode_proxy("peer_id", format!("{:016x}", my_id.0)));
|
||||
|
@ -485,25 +484,27 @@ impl NetManager {
|
|||
} else {
|
||||
info!("No nickname chosen");
|
||||
}
|
||||
self.friendly_fire
|
||||
.store(settings.friendly_fire, atomic::Ordering::Relaxed);
|
||||
state.try_ws_write_option("friendly_fire", settings.friendly_fire);
|
||||
state.try_ws_write_option("debug", settings.debug_mode);
|
||||
state.try_ws_write_option("world_sync_version", settings.world_sync_version);
|
||||
state.try_ws_write_option("player_tether", settings.player_tether);
|
||||
state.try_ws_write_option("tether_length", settings.tether_length);
|
||||
state.try_ws_write_option("item_dedup", settings.item_dedup);
|
||||
state.try_ws_write_option("randomize_perks", settings.randomize_perks);
|
||||
state.try_ws_write_option("enemy_hp_scale", settings.enemy_hp_mult);
|
||||
state.try_ws_write_option("world_sync_interval", settings.world_sync_interval);
|
||||
state.try_ws_write_option("game_mode", settings.game_mode);
|
||||
state.try_ws_write_option("chunk_target", settings.chunk_target);
|
||||
state.try_ws_write_option("health_per_player", settings.health_per_player);
|
||||
state.try_ws_write_option("enemy_sync_interval", settings.enemy_sync_interval);
|
||||
state.try_ws_write_option("global_hp_loss", settings.global_hp_loss);
|
||||
state.try_ws_write_option("perk_ban_list", settings.perk_ban_list.as_str());
|
||||
state.try_ws_write_option("no_material_damage", settings.no_material_damage);
|
||||
state.try_ws_write_option("health_lost_on_revive", settings.health_lost_on_revive);
|
||||
let ff = settings.friendly_fire.unwrap_or(def.friendly_fire);
|
||||
self.friendly_fire.store(ff, atomic::Ordering::Relaxed);
|
||||
state.try_ws_write_option("friendly_fire", ff);
|
||||
state.try_ws_write_option("debug", settings.debug_mode.unwrap_or(def.debug_mode));
|
||||
state.try_ws_write_option("world_sync_version", settings.world_sync_version.unwrap_or(def.world_sync_version));
|
||||
state.try_ws_write_option("player_tether", settings.player_tether.unwrap_or(def.player_tether));
|
||||
state.try_ws_write_option("tether_length", settings.tether_length.unwrap_or(def.tether_length));
|
||||
state.try_ws_write_option("item_dedup", settings.item_dedup.unwrap_or(def.item_dedup));
|
||||
state.try_ws_write_option("randomize_perks", settings.randomize_perks.unwrap_or(def.randomize_perks));
|
||||
state.try_ws_write_option("enemy_hp_scale", settings.enemy_hp_mult.unwrap_or(def.enemy_hp_mult));
|
||||
state.try_ws_write_option("world_sync_interval", settings.world_sync_interval.unwrap_or(def.world_sync_interval));
|
||||
state.try_ws_write_option("game_mode", settings.game_mode.unwrap_or(def.game_mode));
|
||||
state.try_ws_write_option("chunk_target", settings.chunk_target.unwrap_or(def.chunk_target));
|
||||
state.try_ws_write_option("health_per_player", settings.health_per_player.unwrap_or(def.health_per_player));
|
||||
state.try_ws_write_option("enemy_sync_interval", settings.enemy_sync_interval.unwrap_or(def.enemy_sync_interval));
|
||||
state.try_ws_write_option("global_hp_loss", settings.global_hp_loss.unwrap_or(def.global_hp_loss));
|
||||
state.try_ws_write_option("perma_death", settings.perma_death.unwrap_or(def.perma_death));
|
||||
let lst = settings.clone();
|
||||
state.try_ws_write_option("perk_ban_list", lst.perk_ban_list.unwrap_or(def.perk_ban_list).as_str());
|
||||
state.try_ws_write_option("no_material_damage", settings.no_material_damage.unwrap_or(def.no_material_damage));
|
||||
state.try_ws_write_option("health_lost_on_revive", settings.health_lost_on_revive.unwrap_or(def.health_lost_on_revive));
|
||||
let rgb = self.init_settings.player_color.player_main;
|
||||
state.try_ws_write_option(
|
||||
"mina_color",
|
||||
|
@ -670,4 +671,4 @@ impl Drop for NetManager {
|
|||
info!("Skip saving run info: not a host");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue