Skip to content

Commit be3025b

Browse files
committed
v1.0.28
1 parent 940a046 commit be3025b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+979
-626
lines changed

Cargo.lock

+461-364
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rebels"
3-
version = "1.0.27"
3+
version = "1.0.28"
44
edition = "2021"
55
authors = ["Alessandro Ricottone <[email protected]>"]
66
license = "GPL-3.0-or-later"
@@ -30,7 +30,7 @@ async-trait = "0.1.83"
3030
chrono = "0.4.39"
3131
clap = { version = "4.5.21", features = ["derive"] }
3232
crossterm = "0.28.1"
33-
directories = "5.0.1"
33+
directories = "6.0.0"
3434
ed25519-dalek = "2.1.1"
3535
flate2 = { version = "1.0.35", features = ["zlib-ng"], default-features = false }
3636
futures = "0.3.30"
@@ -39,8 +39,8 @@ glam = "0.29.2"
3939
image = "0.25.5"
4040
imageproc = "0.25.0"
4141
include_dir = "0.7.4"
42-
itertools = "0.13.0"
43-
libp2p = { version = "0.54.1", features = [
42+
itertools = "0.14.0"
43+
libp2p = { version = "0.55.0", features = [
4444
"dns",
4545
"gossipsub",
4646
"macros",
@@ -52,8 +52,8 @@ libp2p = { version = "0.54.1", features = [
5252
"tokio",
5353
"yamux",
5454
] }
55-
libp2p-swarm-test = "0.4.0"
56-
log = "0.4.22"
55+
libp2p-swarm-test = "0.5.0"
56+
log = "0.4.25"
5757
log4rs = { version = "1.3.0", features = ["file_appender", "pattern_encoder"] }
5858
once_cell = "1.20.2"
5959
rand = "0.8.5"
@@ -75,5 +75,5 @@ tokio-util = "0.7.12"
7575
tui-textarea = "0.7.0"
7676
unicode-width = "0.2.0"
7777
url = "2.5.4"
78-
uuid = { version = "1.11.0", features = ["v4", "serde"] }
78+
uuid = { version = "1.12.0", features = ["v4", "serde"] }
7979
void = "1.0.2"

assets/game/pitch_fancy.png

6 Bytes
Loading

src/crossterm_event_handler.rs

+25-21
Original file line numberDiff line numberDiff line change
@@ -28,38 +28,42 @@ impl EventHandler for CrosstermEventHandler {
2828
impl CrosstermEventHandler {
2929
const DEFAULT_FPS: u8 = 30;
3030

31-
pub fn new(fps: Option<u8>) -> Self {
31+
pub fn new(fps: Option<u8>, with_input_reader: bool) -> Self {
3232
let fps = fps.unwrap_or(CrosstermEventHandler::DEFAULT_FPS);
3333
let time_step_millis: Tick = (1000.0 / fps as f32) as Tick;
3434
let time_step: Duration = Duration::from_millis(time_step_millis as u64);
35-
let (sender, receiver) = mpsc::channel(1);
35+
let (sender, receiver) = mpsc::channel(100);
3636
let handler = {
3737
let sender = sender.clone();
3838
let mut last_tick = Tick::now();
3939
tokio::task::spawn(async move {
4040
loop {
41-
if event::poll(time_step).expect("no events available") {
42-
let result = match event::read().expect("unable to read event") {
43-
CrosstermEvent::Key(key) => {
44-
if key.kind == KeyEventKind::Press {
45-
sender.send(TerminalEvent::Key(key)).await
46-
} else {
41+
if with_input_reader {
42+
if event::poll(time_step).expect("no events available") {
43+
let result = match event::read().expect("unable to read event") {
44+
CrosstermEvent::Key(key) => {
45+
if key.kind == KeyEventKind::Press {
46+
sender.send(TerminalEvent::Key(key)).await
47+
} else {
48+
Ok(())
49+
}
50+
}
51+
CrosstermEvent::Mouse(e) => {
52+
sender.send(TerminalEvent::Mouse(e)).await
53+
}
54+
CrosstermEvent::Resize(w, h) => {
55+
sender.send(TerminalEvent::Resize(w, h)).await
56+
}
57+
_ => {
58+
log::info!("Crossterm event not implemented");
4759
Ok(())
4860
}
49-
}
50-
CrosstermEvent::Mouse(e) => sender.send(TerminalEvent::Mouse(e)).await,
51-
CrosstermEvent::Resize(w, h) => {
52-
sender.send(TerminalEvent::Resize(w, h)).await
53-
}
54-
_ => {
55-
log::info!("Crossterm event not implemented");
56-
Ok(())
57-
}
58-
};
61+
};
5962

60-
if let Err(e) = result {
61-
log::error!("Failed to send terminal event: {e}");
62-
break;
63+
if let Err(e) = result {
64+
log::error!("Failed to send terminal event: {e}");
65+
break;
66+
}
6367
}
6468
}
6569

src/game_engine/brawl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::{
22
action::{Action, ActionOutput, EngineAction},
33
game::Game,
4-
types::GameStats,
4+
types::*,
55
};
66
use crate::world::{
77
constants::{MoraleModifier, TirednessCost},

src/game_engine/constants.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ pub enum ShotDifficulty {
1212
}
1313

1414
pub const RECOVERING_TIREDNESS_PER_SHORT_TICK: f32 = TirednessCost::LOW;
15-
pub const MIN_TIREDNESS_FOR_SUB: f32 = 10.0;
1615
pub const MIN_TIREDNESS_FOR_ROLL_DECLINE: f32 = 10.0;
16+
pub const MIN_TIREDNESS_FOR_SUB: f32 = MIN_TIREDNESS_FOR_ROLL_DECLINE;
1717

1818
pub const BASE_ATTENDANCE: u32 = 60;
1919
pub const BRAWL_ACTION_PROBABILITY: f32 = 0.06;

src/game_engine/game.rs

+45-7
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use crate::{
1313
planet::Planet,
1414
player::{Player, Trait},
1515
position::MAX_POSITION,
16-
skill::GameSkill,
16+
role::CrewRole,
17+
skill::{GameSkill, MAX_SKILL},
1718
},
1819
};
1920
use itertools::Itertools;
@@ -186,10 +187,10 @@ impl<'game> Game {
186187
let seed = game.get_rng_seed();
187188
let mut rng = ChaCha8Rng::from_seed(seed);
188189

189-
let attendance =
190-
(BASE_ATTENDANCE + total_reputation.value() as u32 * planet.total_population()) as f32
191-
* rng.gen_range(0.75..1.25)
192-
* (1.0 + bonus_attendance);
190+
let attendance = (BASE_ATTENDANCE as f32
191+
+ (total_reputation.value() as f32).powf(2.0) * planet.total_population() as f32)
192+
* rng.gen_range(0.75..1.25)
193+
* (1.0 + bonus_attendance);
193194
game.attendance = attendance as u32;
194195
let mut default_output = ActionOutput::default();
195196

@@ -424,6 +425,26 @@ impl<'game> Game {
424425
Possession::Away => (defense_stats, attack_stats),
425426
};
426427

428+
// Conditions for morale boost:
429+
// shot success, team is losing at most by a margin equal to the captain charisma.
430+
let attacking_player = self.attacking_players();
431+
let team_captain = attacking_player
432+
.iter()
433+
.find(|&p| p.info.crew_role == CrewRole::Captain);
434+
435+
let mut losing_margin = 4;
436+
437+
if let Some(captain) = team_captain {
438+
losing_margin += (captain.mental.charisma / 4.0) as u16
439+
};
440+
441+
let score = self.get_score();
442+
443+
let is_losing_by_margin = match self.possession {
444+
Possession::Home => score.0 < score.1 && score.1 - score.0 <= losing_margin,
445+
Possession::Away => score.1 < score.0 && score.0 - score.1 <= losing_margin,
446+
};
447+
427448
if let Some(updates) = &mut home_stats {
428449
for (id, player_stats) in self.home_team_in_game.stats.iter_mut() {
429450
let player = self.home_team_in_game.players.get_mut(&id).unwrap();
@@ -437,7 +458,15 @@ impl<'game> Game {
437458
if self.possession == Possession::Home {
438459
player.add_morale(MoraleModifier::SMALL_BONUS);
439460
} else {
440-
player.add_morale(MoraleModifier::SMALL_MALUS);
461+
player.add_morale(
462+
MoraleModifier::SMALL_MALUS
463+
/ (1.0 + player.mental.charisma / MAX_SKILL),
464+
);
465+
}
466+
467+
if is_losing_by_margin {
468+
player
469+
.add_morale(MoraleModifier::SMALL_BONUS + player.mental.charisma / 8.0);
441470
}
442471
}
443472
}
@@ -456,7 +485,15 @@ impl<'game> Game {
456485
if self.possession == Possession::Away {
457486
player.add_morale(MoraleModifier::SMALL_BONUS);
458487
} else {
459-
player.add_morale(MoraleModifier::SMALL_MALUS);
488+
player.add_morale(
489+
MoraleModifier::SMALL_MALUS
490+
/ (1.0 + player.mental.charisma / MAX_SKILL),
491+
);
492+
}
493+
494+
if is_losing_by_margin {
495+
player
496+
.add_morale(MoraleModifier::SMALL_BONUS + player.mental.charisma / 8.0);
460497
}
461498
}
462499
}
@@ -507,6 +544,7 @@ impl<'game> Game {
507544
} else if player.tiredness > RECOVERING_TIREDNESS_PER_SHORT_TICK
508545
&& !player.is_knocked_out()
509546
{
547+
// We don't use add_tiredness here because otherwise the stamina would have an effect.
510548
player.tiredness -= RECOVERING_TIREDNESS_PER_SHORT_TICK;
511549
}
512550
}

src/game_engine/isolation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::{
22
action::{Action, ActionOutput, ActionSituation, Advantage, EngineAction},
33
constants::*,
44
game::Game,
5-
types::{GameStats, Possession},
5+
types::*,
66
};
77
use crate::world::{
88
constants::{MoraleModifier, TirednessCost},

src/game_engine/jump_ball.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::{
22
action::{ActionOutput, ActionSituation, EngineAction},
33
game::Game,
4-
types::Possession,
4+
types::*,
55
};
66
use crate::world::{player::Player, skill::GameSkill};
77
use rand::Rng;

src/game_engine/off_the_screen.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::{
22
action::{Action, ActionOutput, ActionSituation, Advantage, EngineAction},
33
constants::*,
44
game::Game,
5-
types::{GameStats, GameStatsMap},
5+
types::*,
66
};
77
use crate::world::{
88
constants::{MoraleModifier, TirednessCost},

src/game_engine/pick_and_roll.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::{
22
action::{Action, ActionOutput, ActionSituation, Advantage, EngineAction},
33
constants::*,
44
game::Game,
5-
types::{GameStats, GameStatsMap},
5+
types::*,
66
};
77
use crate::world::{
88
constants::{MoraleModifier, TirednessCost},

src/game_engine/post.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::{
22
action::{Action, ActionOutput, ActionSituation, Advantage, EngineAction},
33
constants::*,
44
game::Game,
5-
types::GameStats,
5+
types::*,
66
};
77
use crate::world::{
88
constants::{MoraleModifier, TirednessCost},

src/game_engine/rebound.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::{
22
action::{ActionOutput, ActionSituation, EngineAction},
33
game::Game,
4-
types::GameStats,
4+
types::*,
55
};
66
use crate::{
77
game_engine::{

src/game_engine/shot.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ fn execute_shot(
350350
.map(|&idx| defending_players[idx])
351351
.collect::<Vec<&Player>>();
352352

353-
let atk_skill = match shot.clone() {
353+
let atk_skill = match shot {
354354
ShotDifficulty::Close => shooter.offense.close_range.value(),
355355
ShotDifficulty::Medium => shooter.offense.medium_range.value(),
356356
ShotDifficulty::Long => shooter.offense.long_range.value(),
@@ -378,6 +378,7 @@ fn execute_shot(
378378
};
379379

380380
let success = roll > 0;
381+
381382
let mut result = match success {
382383
false => {
383384
// Attackers and defenders will get a malus in the rebound action.

src/game_engine/substitution.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use super::{
77
use crate::{
88
types::SortablePlayerMap,
99
world::{
10-
constants::MAX_TIREDNESS,
1110
player::Player,
1211
position::{Position, MAX_POSITION},
12+
skill::MAX_SKILL,
1313
team::Team,
1414
},
1515
};
@@ -120,7 +120,7 @@ fn make_substitution(
120120
)
121121
.as_str(),
122122
);
123-
} else if tiredness > MAX_TIREDNESS / 4.0 {
123+
} else if tiredness > MAX_SKILL / 4.0 {
124124
description.push_str(
125125
format!(
126126
"{} {} a bit tired. ",

0 commit comments

Comments
 (0)