add notplayer icon to map

This commit is contained in:
bgkillas 2025-03-11 16:00:32 -04:00
parent 8520764e10
commit 6b4acf244c
7 changed files with 103 additions and 28 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
noita-proxy/notplayer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -6,11 +6,12 @@ use bookkeeping::{
};
use clipboard::{ClipboardContext, ClipboardProvider};
use cpal::traits::{DeviceTrait, HostTrait};
use eframe::egui::load::TexturePoll;
use eframe::egui::{
self, Align2, Button, Color32, ComboBox, Context, DragValue, FontDefinitions, FontFamily,
ImageButton, InnerResponse, Key, Layout, Margin, OpenUrl, OutputCommand, Rect, RichText,
ScrollArea, Sense, Slider, TextureOptions, ThemePreference, Ui, UiBuilder, Vec2, Visuals,
Window, pos2,
ScrollArea, Sense, SizeHint, Slider, TextureOptions, ThemePreference, Ui, UiBuilder, Vec2,
Visuals, Window, pos2,
};
use eframe::epaint::TextureHandle;
use image::DynamicImage::ImageRgba8;
@ -844,6 +845,18 @@ impl Default for PlayerColor {
}
}
}
/*impl PlayerColor {
pub fn notplayer() -> Self {
Self {
player_main: [155.0, 111.0, 154.0, 255.0],
player_alt: [127.0, 84.0, 118.0, 255.0],
player_arm: [89.0, 67.0, 84.0, 255.0],
player_cape: [118.0, 84.0, 127.0, 255.0],
player_cape_edge: [154.0, 111.0, 155.0, 255.0],
player_forearm: [158.0, 115.0, 154.0, 255.0],
}
}
}*/
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
enum PlayerPicker {
None,
@ -1025,7 +1038,8 @@ struct ImageMap {
textures: FxHashMap<ChunkCoord, TextureHandle>,
zoom: f32,
offset: Vec2,
players: FxHashMap<OmniPeerId, (Option<WorldPos>, TextureHandle)>,
players: FxHashMap<OmniPeerId, (Option<WorldPos>, bool, bool, TextureHandle)>,
notplayer: Option<TexturePoll>,
centered_on: Option<OmniPeerId>,
dont_scale: bool,
}
@ -1036,6 +1050,7 @@ impl Default for ImageMap {
zoom: 1.0,
offset: Vec2::new(f32::MAX, f32::MAX),
players: Default::default(),
notplayer: None,
centered_on: None,
dont_scale: false,
}
@ -1065,9 +1080,9 @@ impl ImageMap {
fn update_player_textures(
&mut self,
ui: &mut Ui,
map: &FxHashMap<OmniPeerId, (Option<WorldPos>, RgbaImage)>,
map: &FxHashMap<OmniPeerId, (Option<WorldPos>, bool, bool, RgbaImage)>,
) {
for (p, (coord, img)) in map {
for (p, (coord, is_dead, does_exist, img)) in map {
if !self.players.contains_key(p) {
let name = format!("{}", p);
let size = [img.width() as usize, img.height() as usize];
@ -1078,9 +1093,14 @@ impl ImageMap {
let tex = ui
.ctx()
.load_texture(name, color_image, TextureOptions::NEAREST);
self.players.insert(*p, (*coord, tex));
self.players
.insert(*p, (*coord, *is_dead, *does_exist, tex));
}
self.players.entry(*p).and_modify(|(w, _)| *w = *coord);
self.players.entry(*p).and_modify(|(w, b, d, _)| {
*w = *coord;
*b = *is_dead;
*d = *does_exist;
});
}
}
fn ui(&mut self, ui: &mut Ui, netman: &NetManStopOnDrop, ctx: &Context) {
@ -1089,7 +1109,7 @@ impl ImageMap {
}
if netman.reset_map.load(Ordering::Relaxed) {
netman.reset_map.store(false, Ordering::Relaxed);
self.textures.clear()
self.textures.clear();
}
{
let map = &mut netman.chunk_map.lock().unwrap();
@ -1098,6 +1118,11 @@ impl ImageMap {
}
map.clear();
}
if self.notplayer.is_none() {
self.notplayer = egui::include_image!("../assets/notplayer.png")
.load(ctx, TextureOptions::NEAREST, SizeHint::Size(7, 16))
.ok();
}
self.update_player_textures(ui, &netman.players_sprite.lock().unwrap());
let response = ui.interact(
ui.available_rect_before_wrap(),
@ -1123,10 +1148,10 @@ impl ImageMap {
self.offset.y -= 16.0
}
if ui.input(|i| i.keys_down.contains(&Key::D) || i.keys_down.contains(&Key::ArrowRight)) {
self.offset.x += 16.0
self.offset.x -= 16.0
}
if ui.input(|i| i.keys_down.contains(&Key::A) || i.keys_down.contains(&Key::ArrowLeft)) {
self.offset.x -= 16.0
self.offset.x += 16.0
}
if ui.input(|i| i.keys_down.contains(&Key::X)) {
self.dont_scale = !self.dont_scale
@ -1137,7 +1162,7 @@ impl ImageMap {
let players: Vec<OmniPeerId> = self
.players
.iter()
.filter_map(|(a, (c, _))| if c.is_some() { Some(a) } else { None })
.filter_map(|(a, (c, _, d, _))| if c.is_some() && !d { Some(a) } else { None })
.cloned()
.collect();
if !players.is_empty() {
@ -1156,6 +1181,15 @@ impl ImageMap {
}
}
let mut tile_size = self.zoom * 128.0;
if let Some(peer) = self.centered_on {
if let Some((Some(pos), _, _, _)) = self.players.get(&peer) {
self.offset = Vec2::new(ui.available_width() / 2.0, ui.available_height() / 2.0)
- Vec2::new(
pos.x as f32 * tile_size / 128.0,
(pos.y - 13) as f32 * tile_size / 128.0,
)
}
}
let painter = ui.painter();
for (coord, tex) in &self.textures {
let pos =
@ -1168,7 +1202,10 @@ impl ImageMap {
Color32::WHITE,
);
}
for (pos, tex) in self.players.values() {
for (pos, is_dead, does_exist, tex) in self.players.values() {
if !does_exist {
continue;
}
if let Some(pos) = pos {
if self.dont_scale {
tile_size = 128.0
@ -1182,12 +1219,25 @@ impl ImageMap {
pos.to_pos2(),
Vec2::new(8.0 * tile_size / 128.0, 18.0 * tile_size / 128.0),
);
painter.image(
tex.id(),
rect,
Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0)),
Color32::WHITE,
);
if *is_dead {
if let Some(tex) = &self.notplayer {
if let Some(id) = tex.texture_id() {
painter.image(
id,
rect,
Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0)),
Color32::WHITE,
);
}
}
} else {
painter.image(
tex.id(),
rect,
Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0)),
Color32::WHITE,
);
}
}
}
}
@ -1606,7 +1656,7 @@ impl App {
if self.app_saved_state.times_started % 20 == 0 {
let image = egui::Image::new(egui::include_image!("../assets/longleg.png"))
.texture_options(TextureOptions::NEAREST);
image.paint_at(ui, ui.ctx().screen_rect());
image.paint_at(ui, ctx.screen_rect());
} else {
draw_bg(ui);
}

View file

@ -209,7 +209,8 @@ pub struct NetManager {
duplicate: AtomicBool,
pub back_out: AtomicBool,
pub chunk_map: Mutex<FxHashMap<ChunkCoord, RgbaImage>>,
pub players_sprite: Mutex<FxHashMap<OmniPeerId, (Option<WorldPos>, RgbaImage)>>,
#[allow(clippy::type_complexity)]
pub players_sprite: Mutex<FxHashMap<OmniPeerId, (Option<WorldPos>, bool, bool, RgbaImage)>>,
pub reset_map: AtomicBool,
colors: Mutex<FxHashMap<u16, u32>>,
}
@ -735,10 +736,13 @@ impl NetManager {
.play_audio(audio, pos, src, data, global, (tx, ty), vol);
}
}
NetMsg::PlayerPosition(x, y) => {
NetMsg::PlayerPosition(x, y, is_dead, does_exist) => {
let map = &mut self.players_sprite.lock().unwrap();
map.entry(src)
.and_modify(|(w, _)| *w = Some(WorldPos::from((x, y))));
map.entry(src).and_modify(|(w, b, d, _)| {
*w = Some(WorldPos::from((x, y)));
*b = is_dead;
*d = does_exist
});
}
NetMsg::MapData(chunks) => {
for (ch, c) in chunks {
@ -1245,13 +1249,21 @@ impl NetManager {
}
let x: Option<i32> = msg.next().and_then(|s| s.parse().ok());
let y: Option<i32> = msg.next().and_then(|s| s.parse().ok());
let b: bool = msg
.next()
.map(|s| s.parse().ok() == Some(1))
.unwrap_or(false);
let d: bool = msg
.next()
.map(|s| s.parse().ok() == Some(1))
.unwrap_or(false);
if let (Some(x), Some(y)) = (x, y) {
self.player_pos.0.store(x, Ordering::Relaxed);
self.player_pos.1.store(y, Ordering::Relaxed);
self.broadcast(&NetMsg::PlayerPosition(x, y), Reliability::Reliable);
self.broadcast(&NetMsg::PlayerPosition(x, y, b, d), Reliability::Reliable);
self.send(
self.peer.my_id(),
&NetMsg::PlayerPosition(x, y),
&NetMsg::PlayerPosition(x, y, b, d),
Reliability::Reliable,
);
}

View file

@ -33,7 +33,7 @@ pub(crate) enum NetMsg {
RespondFlagNormal(String, bool),
RespondFlagSlow(usize, bool),
RespondFlagMoon(i32, i32, bool),
PlayerPosition(i32, i32),
PlayerPosition(i32, i32, bool, bool),
RespondFlagStevari(i32, i32, OmniPeerId),
AudioData(Vec<Vec<u8>>, bool, i32, i32, f32),
MapData(FxHashMap<ChunkCoord, ChunkData>),

View file

@ -368,13 +368,14 @@ fn replace_colors_opt(path: PathBuf, save: PathBuf, rgb: &PlayerColor, inv: bool
img.save(save).unwrap();
}
#[allow(clippy::type_complexity)]
pub fn create_player_png(
peer: OmniPeerId,
mod_path: &Path,
player_path: &Path,
rgb: &PlayerPngDesc,
is_host: bool,
player_map: &mut MutexGuard<FxHashMap<OmniPeerId, (Option<WorldPos>, RgbaImage)>>,
player_map: &mut MutexGuard<FxHashMap<OmniPeerId, (Option<WorldPos>, bool, bool, RgbaImage)>>,
) {
let icon = get_player_skin(
image::open(player_path)
@ -383,7 +384,7 @@ pub fn create_player_png(
.into_rgba8(),
*rgb,
);
player_map.insert(peer, (None, icon.clone()));
player_map.insert(peer, (None, false, false, icon.clone()));
let inv = rgb.invert_border;
let id = peer.as_hex();
let cosmetics = rgb.cosmetics;

View file

@ -42,6 +42,14 @@ function module.on_world_update()
if cess then
c = 1
end
local is_dead = 0
if GameHasFlagRun("ew_flag_notplayer_active") then
is_dead = 1
end
local d = 0
if ctx.proxy_opt.no_notplayer or ctx.proxy_opt.perma_death then
d = 1
end
net.proxy_send(
"cam_pos",
math.floor(x)
@ -52,6 +60,10 @@ function module.on_world_update()
.. " "
.. math.floor(my)
.. " "
.. is_dead
.. " "
.. d
.. " "
.. ptt
.. " "
.. a