add teams to friendly fire

This commit is contained in:
bgkillas 2024-10-13 21:33:27 -04:00
parent 0dab6ed110
commit 79f476e424
6 changed files with 52 additions and 13 deletions

View file

@ -87,7 +87,7 @@ connect_settings_autostart = Start the game automatically
## Game settings ## Game settings
Health-per-player = Health per player Health-per-player = Health per player
Enable-friendly-fire = Enable friendly fire Enable-friendly-fire = Enable friendly fire, allows picking teams in lobby
Have-perk-pools-be-independent-of-each-other = Have perk pools be independent of each other Have-perk-pools-be-independent-of-each-other = Have perk pools be independent of each other
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 = 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 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 = 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
local_health_desc_1 = Every player has their own health, run ends when all player are dead. local_health_desc_1 = Every player has their own health, run ends when all player are dead.
@ -125,7 +125,7 @@ Shift-hue = Shift hue
## Connected ## Connected
Show-debug-info = Show debug info Show-debug-info = Show debug/connection info
hint_spectate = Use [',' or d-pad-left] and ['.' or d-pad-right] keys to spectate over other players. hint_spectate = Use [',' or d-pad-left] and ['.' or d-pad-right] keys to spectate over other players.
hint_ping = [Middle mouse button or right thumb stick] spawns a ping hint_ping = [Middle mouse button or right thumb stick] spawns a ping

View file

@ -87,7 +87,7 @@ connect_settings_autostart = ゲームを自動的に開始する
## Game settings ## Game settings
Health-per-player = Health per player Health-per-player = Health per player
Enable-friendly-fire = Enable friendly fire Enable-friendly-fire = Enable friendly fire, allows picking teams in lobby
Have-perk-pools-be-independent-of-each-other = Have perk pools be independent of each other Have-perk-pools-be-independent-of-each-other = Have perk pools be independent of each other
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 = 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 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 = 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
local_health_desc_2 = There is a respawn mechanic. local_health_desc_2 = There is a respawn mechanic.
@ -125,7 +125,7 @@ Shift-hue = Shift hue
## Connected ## Connected
Show-debug-info = Show debug info Show-debug-info = Show debug/connection info
hint_spectate = Use [',' or d-pad-left] and ['.' or d-pad-right] keys to spectate over other players. hint_spectate = Use [',' or d-pad-left] and ['.' or d-pad-right] keys to spectate over other players.
hint_ping = [Middle mouse button or right thumb stick] spawns a ping hint_ping = [Middle mouse button or right thumb stick] spawns a ping

View file

@ -77,6 +77,7 @@ pub struct GameSettings {
world_sync_interval: u32, world_sync_interval: u32,
game_mode: GameMode, game_mode: GameMode,
friendly_fire: bool, friendly_fire: bool,
friendly_fire_team: i32,
chunk_target: u32, chunk_target: u32,
enemy_sync_interval: u32, enemy_sync_interval: u32,
randomize_perks: bool, randomize_perks: bool,
@ -99,6 +100,7 @@ impl Default for GameSettings {
world_sync_interval: 3, world_sync_interval: 3,
game_mode: GameMode::LocalHealth, game_mode: GameMode::LocalHealth,
friendly_fire: false, friendly_fire: false,
friendly_fire_team: 0,
chunk_target: 24, chunk_target: 24,
enemy_sync_interval: 3, enemy_sync_interval: 3,
progress: Vec::new(), progress: Vec::new(),
@ -1020,6 +1022,15 @@ impl eframe::App for App {
ui.checkbox(&mut self.app_saved_state.show_extra_debug_stuff, tr("Show-debug-info")); ui.checkbox(&mut self.app_saved_state.show_extra_debug_stuff, tr("Show-debug-info"));
ui.add_space(15.0); ui.add_space(15.0);
if self.app_saved_state.game_settings.friendly_fire {
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));
if last != self.app_saved_state.game_settings.friendly_fire_team {
netman.friendly_fire_team.store(self.app_saved_state.game_settings.friendly_fire_team, Ordering::Relaxed);
}
ui.label("what team number you are on, 0 means no team, -1 means friendly");
ui.add_space(15.0);
}
ui.label(tr("hint_ping")); ui.label(tr("hint_ping"));
ui.label(tr("hint_spectate")); ui.label(tr("hint_spectate"));
@ -1339,4 +1350,4 @@ pub fn host_cli(port: u16) {
let player_path = netmaninit.player_path.clone(); let player_path = netmaninit.player_path.clone();
let netman = net::NetManager::new(varient, netmaninit); let netman = net::NetManager::new(varient, netmaninit);
netman.start_inner(player_path, true).unwrap(); netman.start_inner(player_path, true).unwrap();
} }

View file

@ -17,6 +17,7 @@ use std::{
thread::{self, JoinHandle}, thread::{self, JoinHandle},
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use std::sync::atomic::AtomicI32;
use world::{world_info::WorldInfo, NoitaWorldUpdate, WorldManager}; use world::{world_info::WorldInfo, NoitaWorldUpdate, WorldManager};
use tangled::Reliability; use tangled::Reliability;
@ -128,6 +129,7 @@ pub struct NetManager {
pub enable_recorder: AtomicBool, pub enable_recorder: AtomicBool,
pub end_run: AtomicBool, pub end_run: AtomicBool,
pub debug_markers: Mutex<Vec<DebugMarker>>, pub debug_markers: Mutex<Vec<DebugMarker>>,
pub friendly_fire_team: AtomicI32,
} }
impl NetManager { impl NetManager {
@ -146,6 +148,7 @@ impl NetManager {
enable_recorder: AtomicBool::new(false), enable_recorder: AtomicBool::new(false),
end_run: AtomicBool::new(false), end_run: AtomicBool::new(false),
debug_markers: Default::default(), debug_markers: Default::default(),
friendly_fire_team: AtomicI32::new(-2),
} }
.into() .into()
} }
@ -186,6 +189,13 @@ impl NetManager {
if !self.init_settings.cosmetics.2 { if !self.init_settings.cosmetics.2 {
File::create(player_path.parent().unwrap().join("tmp/no_amulet_gem"))?; File::create(player_path.parent().unwrap().join("tmp/no_amulet_gem"))?;
} }
let mut last_team = -2;
if let Ok(n) = self.settings.lock() {
last_team = n.friendly_fire_team;
self.friendly_fire_team.store(last_team, atomic::Ordering::Relaxed);
}
let socket = Socket::new(Domain::IPV4, Type::STREAM, None)?; let socket = Socket::new(Domain::IPV4, Type::STREAM, None)?;
// This allows several proxies to listen on the same address. // This allows several proxies to listen on the same address.
// While this works, I couldn't get Noita to reliably connect to correct proxy instances on my os (linux). // While this works, I couldn't get Noita to reliably connect to correct proxy instances on my os (linux).
@ -237,6 +247,11 @@ impl NetManager {
cli = false cli = false
} }
} }
let team = self.friendly_fire_team.load(atomic::Ordering::Relaxed);
if team != last_team {
last_team = team;
state.try_ws_write_option("friendly_fire_team", (team + 1) as u32);
}
if self.end_run.load(atomic::Ordering::Relaxed) { if self.end_run.load(atomic::Ordering::Relaxed) {
for id in self.peer.iter_peer_ids() { for id in self.peer.iter_peer_ids() {
self.send(id, &NetMsg::EndRun, Reliability::Reliable); self.send(id, &NetMsg::EndRun, Reliability::Reliable);
@ -437,6 +452,7 @@ impl NetManager {
} else { } else {
info!("No nickname chosen"); info!("No nickname chosen");
} }
state.try_ws_write_option("friendly_fire_team", (settings.friendly_fire_team + 1) as u32);
state.try_ws_write_option("debug", settings.debug_mode); 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("world_sync_version", settings.world_sync_version);
state.try_ws_write_option("player_tether", settings.player_tether); state.try_ws_write_option("player_tether", settings.player_tether);
@ -615,4 +631,4 @@ impl Drop for NetManager {
info!("Skip saving run info: not a host"); info!("Skip saving run info: not a host");
} }
} }
} }

View file

@ -498,10 +498,6 @@ function player_fns.spawn_player_for(peer_id, x, y, existing_playerdata)
end end
end end
if ctx.proxy_opt.friendly_fire then
GenomeSetHerdId(new, "player_pvp")
end
local new_playerdata = existing_playerdata or player_fns.make_playerdata_for(new, peer_id) local new_playerdata = existing_playerdata or player_fns.make_playerdata_for(new, peer_id)
new_playerdata.entity = new new_playerdata.entity = new
-- util.tpcall(nickname.addLabel, new, new_playerdata.name, "data/fonts/font_pixel_white.xml", 1) -- util.tpcall(nickname.addLabel, new, new_playerdata.name, "data/fonts/font_pixel_white.xml", 1)

View file

@ -6,13 +6,24 @@ local rpc = net.new_rpc_namespace()
local module = {} local module = {}
function rpc.player_update(input_data, pos_data, current_slot) function rpc.player_update(input_data, pos_data, current_slot, team)
local peer_id = ctx.rpc_peer_id local peer_id = ctx.rpc_peer_id
if not player_fns.peer_has_player(peer_id) then if not player_fns.peer_has_player(peer_id) then
player_fns.spawn_player_for(peer_id, pos_data.x, pos_data.y) player_fns.spawn_player_for(peer_id, pos_data.x, pos_data.y, team)
end end
local player_data = player_fns.peer_get_player_data(peer_id) local player_data = player_fns.peer_get_player_data(peer_id)
if team ~= nil then
local my_team = ctx.proxy_opt.friendly_fire_team - 1
if my_team ~= -1 and team ~= -1 and (team == 0 or my_team == 0 or team ~= my_team) then
GenomeSetHerdId(player_data.entity, "player_pvp")
else
GenomeSetHerdId(player_data.entity, "player")
end
end
if input_data ~= nil then if input_data ~= nil then
player_fns.deserialize_inputs(input_data, player_data) player_fns.deserialize_inputs(input_data, player_data)
end end
@ -39,7 +50,12 @@ function module.on_world_update()
local pos_data = player_fns.serialize_position(ctx.my_player) local pos_data = player_fns.serialize_position(ctx.my_player)
local current_slot = player_fns.get_current_slot(ctx.my_player) local current_slot = player_fns.get_current_slot(ctx.my_player)
if input_data ~= nil and pos_data ~= nil then if input_data ~= nil and pos_data ~= nil then
rpc.player_update(input_data, pos_data, current_slot) local my_team
if ctx.proxy_opt.friendly_fire and GameGetFrameNum() % 60 == 43 then
my_team = ctx.proxy_opt.friendly_fire_team - 1
end
rpc.player_update(input_data, pos_data, current_slot, my_team)
if GameGetFrameNum() % 120 == 0 then if GameGetFrameNum() % 120 == 0 then
local n = np.GetGameModeNr() local n = np.GetGameModeNr()
rpc.check_gamemode(np.GetGameModeName(n)) rpc.check_gamemode(np.GetGameModeName(n))