mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 15:13:16 +00:00
add notplayer icon to map
This commit is contained in:
parent
8520764e10
commit
6b4acf244c
7 changed files with 103 additions and 28 deletions
BIN
noita-proxy/assets/notplayer.png
Normal file
BIN
noita-proxy/assets/notplayer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
BIN
noita-proxy/notplayer.png
Normal file
BIN
noita-proxy/notplayer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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>),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue