Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified assets/click.ogg
Binary file not shown.
Binary file modified assets/drag.ogg
Binary file not shown.
Binary file modified assets/flick.ogg
Binary file not shown.
Binary file modified assets/respack/click.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/respack/click_mh.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/respack/drag.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/respack/drag_mh.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/respack/flick.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/respack/flick_mh.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/respack/hit_fx.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/respack/hold.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/respack/hold_mh.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 9 additions & 6 deletions assets/respack/info.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
name: "nomo"
author: 星鹿ELEC & 不会读谱的FW小赵呀
description: 星鹿ELEC负责绘制,不会读谱的FW小赵呀负责音效
hitFx: [8, 7]
name: "Live"
author: XingLuELEC
description: 打击音效来自:小赵同学
hitFx: [8, 8]
holdAtlas: [50, 50]
holdAtlasMH: [130, 130]
hitFxScale: 0.9
holdAtlasMH: [200, 200]
hitFxDuration: 0.5
hitFxScale: 1.2
hitFxRotate: true
circleParticles: true
2 changes: 1 addition & 1 deletion phira-monitor/src/launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub fn launch_task(id: i32, players: Vec<UserInfo>) -> Result<LaunchTask> {
Ok(PlayerView::new(
player,
chart,
ParticleEmitter::new(&game_scene.res.res_pack, game_scene.res.config.note_scale, game_scene.res.res_pack.info.hide_particles)?,
ParticleEmitter::new(&game_scene.res.res_pack, game_scene.res.config.note_scale)?,
))
})
.collect::<Result<_>>()?;
Expand Down
2 changes: 1 addition & 1 deletion phira/src/page/offset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl OffsetPage {
.await
.context("Failed to load resource pack")?;
let click = respack.note_style.click.clone();
let emitter = ParticleEmitter::new(&respack, get_data().config.note_scale, respack.info.hide_particles)?;
let emitter = ParticleEmitter::new(&respack, get_data().config.note_scale)?;
Ok(Self {
_audio: audio,
cali,
Expand Down
32 changes: 17 additions & 15 deletions phira/src/page/respack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use std::{
};

fn build_emitter(pack: &ResourcePack) -> Result<ParticleEmitter> {
ParticleEmitter::new(pack, get_data().config.note_scale * 0.6, pack.info.hide_particles)
ParticleEmitter::new(pack, get_data().config.note_scale * 0.6)
}

pub struct ResPackItem {
Expand Down Expand Up @@ -264,7 +264,7 @@ impl Page for ResPackPage {
s.render_fader(ui, |ui| {
ui.fill_path(&cr.rounded(0.005), semi_black(0.4));
let item = &self.items[self.index];
if let Some(pack) = &item.loaded {
if let Some(res_pack) = &item.loaded {
let width = 0.16;
let mut r = Rect::new(cr.x + 0.07, cr.y + 0.1, width, 0.);
let mut draw = |mut r: Rect, tex: Texture2D, mh: Texture2D| {
Expand All @@ -280,16 +280,16 @@ impl Page for ResPackPage {
ui.fill_rect(r, (mh, r, ScaleType::Fit));
};
let sp = (cr.h - 0.4) / 2.;
draw(r, *pack.note_style.click, *pack.note_style_mh.click);
draw(r, *res_pack.note_style.click, *res_pack.note_style_mh.click);
r.y += sp;
draw(r, *pack.note_style.drag, *pack.note_style_mh.drag);
draw(r, *res_pack.note_style.drag, *res_pack.note_style_mh.drag);
r.y += sp;
draw(r, *pack.note_style.flick, *pack.note_style_mh.flick);
draw(r, *res_pack.note_style.flick, *res_pack.note_style_mh.flick);
let mut r = Rect::new(0.1, cr.y + 0.1, width, cr.h - 0.38);
let draw = |mut r: Rect, style: &NoteStyle, width: f32| {
let conv = |r: Rect, tex: &SafeTexture| Rect::new(r.x * tex.width(), r.y * tex.height(), r.w * tex.width(), r.h * tex.height());
let tr = conv(style.hold_tail_rect(), &style.hold);
let factor = if pack.info.hold_compact { 0.5 } else { 1. };
let factor = if res_pack.info.hold_compact { 0.5 } else { 1. };
let h = tr.h / tr.w * width;
let r2 = Rect::new(r.x, r.y - h * factor, width, h);
let r2 = ui.rect_to_global(r2);
Expand Down Expand Up @@ -322,7 +322,7 @@ impl Page for ResPackPage {
r.w = width;
let r2 = ui.rect_to_global(r);
draw_texture_ex(
if pack.info.hold_repeat {
if res_pack.info.hold_repeat {
**style.hold_body.as_ref().unwrap()
} else {
*style.hold
Expand All @@ -332,7 +332,7 @@ impl Page for ResPackPage {
semi_white(ui.alpha),
DrawTextureParams {
source: Some({
if pack.info.hold_repeat {
if res_pack.info.hold_repeat {
let hold_body = style.hold_body.as_ref().unwrap();
let w = hold_body.width();
Rect::new(0., 0., w, r2.h / width / 2. * w)
Expand All @@ -345,9 +345,9 @@ impl Page for ResPackPage {
},
)
};
draw(r, &pack.note_style, width);
draw(r, &res_pack.note_style, width);
r.x += width + 0.04;
draw(r, &pack.note_style_mh, width * pack.note_style_mh.hold.width() / pack.note_style.hold.width());
draw(r, &res_pack.note_style_mh, width * res_pack.note_style_mh.hold.width() / res_pack.note_style.hold.width());
let x = cr.x + 0.05;
if let Some(emitter) = &mut self.emitter {
emitter.draw(get_frame_time());
Expand All @@ -357,15 +357,17 @@ impl Page for ResPackPage {
let rnd = t.div_euclid(inter);
let irnd = rnd as u32;
let tex = match irnd % 3 {
0 => *pack.note_style.click,
1 => *pack.note_style.drag,
2 => *pack.note_style.flick,
0 => *res_pack.note_style.click,
1 => *res_pack.note_style.drag,
2 => *res_pack.note_style.flick,
_ => unreachable!(),
};
let st = r.y + 0.06;
let cx = r.x + 0.43;
let line = 0.12;
ui.fill_rect(Rect::new(cx - 0.2, line - 0.004, 0.4, 0.008), WHITE);
let line_color = if irnd % 2 == 0 { res_pack.info.line_perfect() } else { res_pack.info.line_good() };
let fx_color = if irnd % 2 == 0 { res_pack.info.fx_perfect() } else { res_pack.info.fx_good() };
ui.fill_rect(Rect::new(cx - 0.2, line - 0.004, 0.4, 0.008), line_color);
let p = (t - inter * rnd) / 0.9;
if p <= 1. {
let y = st + (line - st) * p;
Expand All @@ -374,7 +376,7 @@ impl Page for ResPackPage {
ui.fill_rect(r, (tex, r, ScaleType::Fit));
} else if irnd != self.last_round {
if let Some(emitter) = &mut self.emitter {
emitter.emit_at(vec2(cx, line), 0., pack.info.fx_perfect());
emitter.emit_at(vec2(cx, line), 0., fx_color);
}
if let Some(sfxs) = &mut self.sfxs {
let _ = sfxs[(irnd % 3) as usize].play(PlaySfxParams::default());
Expand Down
80 changes: 65 additions & 15 deletions prpr/src/core/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
ext::{create_audio_manger, nalgebra_to_glm, SafeTexture},
fs::FileSystem,
info::ChartInfo,
particle::{AtlasConfig, ColorCurve, Emitter, EmitterConfig},
particle::{AtlasConfig, ColorCurve, Emitter, EmitterConfig, ParticleShape},
};
use anyhow::{bail, Context, Result};
use macroquad::prelude::*;
Expand Down Expand Up @@ -37,20 +37,35 @@ fn default_duration() -> f32 {
}

#[inline]
fn default_perfect() -> u32 {
0xe1ffec9f
fn default_perfect_fx() -> (f32, f32, f32, f32) {
(1.0, 0.9, 0.65, 0.9)
}

#[inline]
fn default_good() -> u32 {
0xebb4e1ff
fn default_good_fx() -> (f32, f32, f32, f32) {
(0.70, 0.9, 1.0, 0.9)
}

#[inline]
fn default_perfect_line() -> (f32, f32, f32, f32) {
(1.0, 1.0, 0.7, 1.0)
}

#[inline]
fn default_good_line() -> (f32, f32, f32, f32) {
(0.65, 0.94, 1.0, 1.0)
}

#[inline]
fn default_tinted() -> bool {
true
}

#[inline]
fn default_particle_count() -> usize {
4
}

#[allow(dead_code)]
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
Expand All @@ -67,8 +82,14 @@ pub struct ResPackInfo {
pub hit_fx_rotate: bool,
#[serde(default)]
pub hide_particles: bool,
#[serde(default)]
pub circle_particles: bool,
#[serde(default = "default_particle_count")]
pub particle_count: usize,
#[serde(default = "default_tinted")]
pub hit_fx_tinted: bool,
#[serde(default = "default_tinted")]
pub line_tinted: bool,

pub hold_atlas: (u32, u32),
#[serde(rename = "holdAtlasMH")]
Expand All @@ -81,10 +102,15 @@ pub struct ResPackInfo {
#[serde(default)]
pub hold_compact: bool,

#[serde(default = "default_perfect")]
pub color_perfect: u32,
#[serde(default = "default_good")]
pub color_good: u32,
#[serde(default = "default_perfect_fx")]
pub color_perfect_fx: (f32, f32, f32, f32),
#[serde(default = "default_good_fx")]
pub color_good_fx: (f32, f32, f32, f32),

#[serde(default = "default_perfect_line")]
pub color_perfect_line: (f32, f32, f32, f32),
#[serde(default = "default_good_line")]
pub color_good_line: (f32, f32, f32, f32),

#[serde(default)]
pub description: String,
Expand All @@ -93,15 +119,31 @@ pub struct ResPackInfo {
impl ResPackInfo {
pub fn fx_perfect(&self) -> Color {
if self.hit_fx_tinted {
Color::from_hex(self.color_perfect)
Color::new(self.color_perfect_fx.0, self.color_perfect_fx.1, self.color_perfect_fx.2, self.color_perfect_fx.3)
} else {
WHITE
}
}

pub fn fx_good(&self) -> Color {
if self.hit_fx_tinted {
Color::from_hex(self.color_good)
Color::new(self.color_good_fx.0, self.color_good_fx.1, self.color_good_fx.2, self.color_good_fx.3)
} else {
WHITE
}
}

pub fn line_perfect(&self) -> Color {
if self.line_tinted {
Color::new(self.color_perfect_line.0, self.color_perfect_line.1, self.color_perfect_line.2, self.color_perfect_line.3)
} else {
WHITE
}
}

pub fn line_good(&self) -> Color {
if self.line_tinted {
Color::new(self.color_good_line.0, self.color_good_line.1, self.color_good_line.2, self.color_good_line.3)
} else {
WHITE
}
Expand Down Expand Up @@ -271,10 +313,11 @@ pub struct ParticleEmitter {
pub emitter: Emitter,
pub emitter_square: Emitter,
pub hide_particles: bool,
pub particle_count: usize,
}

impl ParticleEmitter {
pub fn new(res_pack: &ResourcePack, scale: f32, hide_particles: bool) -> Result<Self> {
pub fn new(res_pack: &ResourcePack, scale: f32) -> Result<Self> {
let colors_curve = {
let start = WHITE;
let mut mid = start;
Expand All @@ -283,6 +326,11 @@ impl ParticleEmitter {
end.a = 0.;
ColorCurve { start, mid, end }
};
let shape = if res_pack.info.circle_particles {
ParticleShape::Circle { subdivisions: 16 }
} else {
ParticleShape::Rectangle { aspect_ratio: 1.0 }
};
let mut res = Self {
scale: res_pack.info.hit_fx_scale,
emitter: Emitter::new(EmitterConfig {
Expand All @@ -308,10 +356,12 @@ impl ParticleEmitter {
initial_velocity: 2.5 * scale,
initial_velocity_randomness: 1. / 10.,
linear_accel: -6. / 1.,
shape,
colors_curve,
..Default::default()
}),
hide_particles,
hide_particles: res_pack.info.hide_particles,
particle_count: res_pack.info.particle_count,
};
res.set_scale(scale);
Ok(res)
Expand All @@ -323,7 +373,7 @@ impl ParticleEmitter {
self.emitter.emit(pt, 1);
if !self.hide_particles {
self.emitter_square.config.base_color = color;
self.emitter_square.emit(pt, 4);
self.emitter_square.emit(pt, self.particle_count);
}
}

Expand Down Expand Up @@ -473,7 +523,7 @@ impl Resource {
let note_width = config.note_scale * NOTE_WIDTH_RATIO_BASE;
let note_scale = config.note_scale;

let emitter = ParticleEmitter::new(&res_pack, note_scale, res_pack.info.hide_particles)?;
let emitter = ParticleEmitter::new(&res_pack, note_scale)?;

let no_effect = config.disable_effect || has_no_effect;

Expand Down
10 changes: 5 additions & 5 deletions prpr/src/scene/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ macro_rules! reset {
$self.bad_notes.clear();
$self.judge.reset();
$self.chart.reset();
$res.judge_line_color = Color::from_hex($res.res_pack.info.color_perfect);
$res.judge_line_color = $res.res_pack.info.line_perfect();
$self.music.pause()?;
$self.music.seek_to(0.)?;
$tm.speed = $res.config.speed as _;
Expand Down Expand Up @@ -993,11 +993,11 @@ impl Scene for GameScene {
}
let counts = self.judge.counts();
self.res.judge_line_color = if counts[2] + counts[3] == 0 {
Color::from_hex(if counts[1] == 0 {
self.res.res_pack.info.color_perfect
if counts[1] == 0 {
self.res.res_pack.info.line_perfect()
} else {
self.res.res_pack.info.color_good
})
self.res.res_pack.info.line_good()
}
} else {
WHITE
};
Expand Down
Loading