Skip to content

Commit 429834c

Browse files
committed
v1.0.21
1 parent 320fa4b commit 429834c

33 files changed

+920
-378
lines changed

Cargo.lock

+583-135
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.20"
3+
version = "1.0.21"
44
edition = "2021"
55
authors = ["Alessandro Ricottone <[email protected]>"]
66
license = "GPL-3.0-or-later"
@@ -9,7 +9,7 @@ readme = "README.md"
99
homepage = "https://github.com/ricott1/rebels-in-the-sky"
1010
repository = "https://github.com/ricott1/rebels-in-the-sky"
1111
keywords = ["cli", "pirates", "rebels", "game"]
12-
categories = ["games"]
12+
categories = ["games", "terminal"]
1313

1414
[profile.release]
1515
strip = true
@@ -27,19 +27,19 @@ opt-level = 3
2727
anyhow = "1.0.93"
2828
async-trait = "0.1.83"
2929
chrono = "0.4.38"
30-
clap = { version = "4.5.20", features = ["derive"] }
30+
clap = { version = "4.5.21", features = ["derive"] }
3131
crossterm = "0.28.1"
3232
directories = "5.0.1"
3333
ed25519-dalek = "2.1.1"
34-
flate2 = { version = "1.0.17", features = ["zlib-ng"], default-features = false }
34+
flate2 = { version = "1.0.35", features = ["zlib-ng"], default-features = false }
3535
futures = "0.3.30"
3636
gif = "0.13.1"
3737
glam = "0.29.2"
3838
image = "0.25.5"
3939
imageproc = "0.25.0"
4040
include_dir = "0.7.4"
4141
itertools = "0.13.0"
42-
libp2p = { version = "0.52.4", features = [
42+
libp2p = { version = "0.54.1", features = [
4343
"noise",
4444
"ping",
4545
"tcp",
@@ -60,11 +60,11 @@ ratatui = { version = "0.29.0", features = ["unstable-backend-writer"] }
6060
rodio = "0.20.1"
6161
russh = "0.46.0"
6262
russh-keys = "0.46.0"
63-
serde = { version = "1.0.214", features = ["derive", "default"] }
63+
serde = { version = "1.0.215", features = ["derive", "default"] }
6464
serde_json = "1.0.132"
6565
serde_repr = "0.1.19"
6666
sha2 = "0.10.8"
67-
stream-download = { version = "0.11.2", features = ["reqwest-rustls"] }
67+
stream-download = { version = "0.12.0", features = ["reqwest-rustls"] }
6868
strum = { version = "0.26.3", features = ["derive"] }
6969
strum_macros = "0.26.4"
7070
tokio = { version = "1.41.1", features = ["full"] }

src/app.rs

+27-6
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ use crossterm::event::{KeyCode, KeyModifiers};
1515
use futures::StreamExt;
1616
use libp2p::{gossipsub, swarm::SwarmEvent};
1717
use log::{error, info, warn};
18+
use rand::SeedableRng;
19+
use rand_chacha::ChaCha8Rng;
1820
use stream_download::storage::temp::TempStorageProvider;
1921
use stream_download::StreamDownload;
2022
use tokio::select;
21-
use void::Void;
2223

2324
const NETWORK_HANDLER_INIT_INTERVAL: Tick = 10 * SECONDS;
2425

@@ -138,7 +139,7 @@ impl App {
138139

139140
pub async fn conditional_network_event(
140141
network_handler: &mut Option<NetworkHandler>,
141-
) -> Option<SwarmEvent<gossipsub::Event, Void>> {
142+
) -> Option<SwarmEvent<gossipsub::Event>> {
142143
match network_handler.as_mut() {
143144
Some(handler) => Some(handler.swarm.select_next_some().await),
144145
None => None,
@@ -155,6 +156,26 @@ impl App {
155156
Ok(())
156157
}
157158

159+
pub fn test_default() -> AppResult<Self> {
160+
let mut app = App::new(None, true, true, true, false, None, None, None);
161+
app.new_world();
162+
let home_planet_id = app
163+
.world
164+
.planets
165+
.keys()
166+
.next()
167+
.expect("There should be at elast one planet")
168+
.clone();
169+
app.world.own_team_id = app.world.generate_random_team(
170+
&mut ChaCha8Rng::from_entropy(),
171+
home_planet_id,
172+
"own team".into(),
173+
"ship_name".into(),
174+
)?;
175+
176+
Ok(app)
177+
}
178+
158179
pub fn new(
159180
seed: Option<u64>,
160181
disable_network: bool,
@@ -244,9 +265,9 @@ impl App {
244265
},
245266
TerminalEvent::Mouse(mouse_event) => {
246267
self.handle_mouse_events(mouse_event)?;
247-
if let Err(e) = tui.draw(&mut self.ui, &self.world, self.audio_player.as_ref()).await {
248-
error!("Drawing error: {e}");
249-
}
268+
// if let Err(e) = tui.draw(&mut self.ui, &self.world, self.audio_player.as_ref()).await {
269+
// error!("Drawing error: {e}");
270+
// }
250271
},
251272
TerminalEvent::Resize(w, h) => tui.resize((w, h))?,
252273
TerminalEvent::Quit => self.quit()?,
@@ -445,7 +466,7 @@ impl App {
445466

446467
pub fn handle_network_events(
447468
&mut self,
448-
network_event: SwarmEvent<gossipsub::Event, Void>,
469+
network_event: SwarmEvent<gossipsub::Event>,
449470
) -> AppResult<()> {
450471
if let Some(network_handler) = &mut self.network_handler {
451472
if let Some(callback) = network_handler.handle_network_events(network_event) {

src/network/handler.rs

+19-23
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,15 @@ use crate::types::{PlayerId, TeamId};
1010
use crate::types::{SystemTimeTick, Tick};
1111
use crate::world::world::World;
1212
use anyhow::anyhow;
13-
use libp2p::core::upgrade::Version;
1413
use libp2p::gossipsub::{self, IdentTopic, MessageId};
15-
use libp2p::swarm::{Config, SwarmEvent};
16-
use libp2p::{identity, noise, tcp, yamux, PeerId, Transport};
14+
use libp2p::swarm::SwarmEvent;
15+
use libp2p::{identity, noise, tcp, yamux, PeerId};
1716
use libp2p::{Multiaddr, Swarm};
1817
use log::{error, info};
1918
use std::collections::hash_map::DefaultHasher;
2019
use std::fmt::Debug;
2120
use std::hash::{Hash, Hasher};
2221
use std::time::Duration;
23-
use void::Void;
2422

2523
pub struct NetworkHandler {
2624
pub swarm: Swarm<gossipsub::Behaviour>,
@@ -39,14 +37,6 @@ impl Debug for NetworkHandler {
3937
impl NetworkHandler {
4038
pub fn new(seed_ip: Option<String>, tcp_port: u16) -> AppResult<Self> {
4139
let local_key = identity::Keypair::generate_ed25519();
42-
let local_peer_id = PeerId::from(local_key.public());
43-
44-
let tcp_transport = tcp::tokio::Transport::default()
45-
.upgrade(Version::V1Lazy)
46-
.authenticate(noise::Config::new(&local_key)?)
47-
.multiplex(yamux::Config::default())
48-
.timeout(std::time::Duration::from_secs(20))
49-
.boxed();
5040

5141
// To content-address message, we can take the hash of message and use it as an ID.
5242
let message_id_fn = |message: &gossipsub::Message| {
@@ -72,12 +62,18 @@ impl NetworkHandler {
7262

7363
gossipsub.subscribe(&IdentTopic::new(TOPIC))?;
7464

75-
let mut swarm = Swarm::new(
76-
tcp_transport,
77-
gossipsub,
78-
local_peer_id,
79-
Config::with_tokio_executor(),
80-
);
65+
let mut swarm = libp2p::SwarmBuilder::with_new_identity()
66+
.with_tokio()
67+
.with_tcp(
68+
tcp::Config::default(),
69+
noise::Config::new,
70+
yamux::Config::default,
71+
)?
72+
.with_behaviour(|_| gossipsub)?
73+
.with_swarm_config(|cfg| {
74+
cfg.with_idle_connection_timeout(Duration::from_secs(u64::MAX))
75+
})
76+
.build();
8177

8278
swarm.listen_on(format!("/ip4/0.0.0.0/tcp/{tcp_port}").parse()?)?;
8379

@@ -108,17 +104,17 @@ impl NetworkHandler {
108104
Ok(msg_id)
109105
}
110106

111-
pub fn dial_seed(&mut self) -> AppResult<()> {
112-
self.dial(self.seed_address.clone())
113-
}
114-
115107
fn dial(&mut self, address: Multiaddr) -> AppResult<()> {
116108
if address != self.address {
117109
self.swarm.dial(address)?;
118110
}
119111
Ok(())
120112
}
121113

114+
pub fn dial_seed(&mut self) -> AppResult<()> {
115+
self.dial(self.seed_address.clone())
116+
}
117+
122118
pub fn send_msg(&mut self, msg: String) -> AppResult<MessageId> {
123119
self._send(NetworkData::Message(Tick::now(), msg))
124120
}
@@ -337,7 +333,7 @@ impl NetworkHandler {
337333

338334
pub fn handle_network_events(
339335
&mut self,
340-
event: SwarmEvent<gossipsub::Event, Void>,
336+
event: SwarmEvent<gossipsub::Event>,
341337
) -> Option<NetworkCallback> {
342338
match event {
343339
SwarmEvent::NewListenAddr { address, .. } => {

src/network/trade.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,12 @@ mod tests {
5555
#[ignore]
5656
#[test]
5757
fn test_trade() -> AppResult<()> {
58-
let mut app = App::new(None, true, true, true, false, None, None, None);
59-
app.new_world();
58+
let mut app = App::test_default()?;
6059

6160
let world = &mut app.world;
6261
let rng = &mut ChaCha8Rng::from_entropy();
6362

6463
let home_planet_id = world.planets.keys().next().unwrap().clone();
65-
world.own_team_id = world.generate_random_team(
66-
rng,
67-
home_planet_id,
68-
"own team".into(),
69-
"ship_name".into(),
70-
)?;
7164

7265
let target_team_id = world.generate_random_team(
7366
rng,

src/relayer.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use itertools::Itertools;
1111
use libp2p::gossipsub::IdentTopic;
1212
use libp2p::{gossipsub, swarm::SwarmEvent};
1313
use tokio::select;
14-
use void::Void;
1514

1615
const SEED_INFO_INTERVAL_MILLIS: Tick = 60 * SECONDS;
1716

@@ -115,7 +114,7 @@ impl Relayer {
115114

116115
pub fn handle_network_events(
117116
&mut self,
118-
network_event: SwarmEvent<gossipsub::Event, Void>,
117+
network_event: SwarmEvent<gossipsub::Event>,
119118
) -> AppResult<()> {
120119
println!("Received network event: {:?}", network_event);
121120
match network_event {

src/space_adventure/asteroid.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl AsteroidSize {
9595
match self {
9696
AsteroidSize::Small => 0.2,
9797
AsteroidSize::Big => 1.0,
98-
AsteroidSize::Huge => 3.0,
98+
AsteroidSize::Huge => 4.0,
9999
AsteroidSize::Planet => 0.0,
100100
}
101101
}

src/space_adventure/constants.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::ui::UI_SCREEN_SIZE;
44

55
pub(crate) const FRICTION_COEFF: f32 = 0.1;
66
pub(crate) const THRUST_MOD: f32 = 1.5;
7-
pub(crate) const FUEL_CONSUMPTION_MOD: f32 = 115_000.0;
7+
pub(crate) const FUEL_CONSUMPTION_MOD: f32 = 215_000.0;
88
pub(crate) const MAX_SPACESHIP_SPEED_MOD: f32 = 0.135;
99

1010
pub(crate) const ASTEROID_GENERATION_PROBABILITY: f64 = 0.05;

src/space_adventure/space.rs

+34-22
Original file line numberDiff line numberDiff line change
@@ -387,12 +387,12 @@ impl SpaceAdventure {
387387
self.stop_space_adventure();
388388

389389
return Ok(vec![
390-
UiCallback::PushUiPopup { popup_message:
391-
PopupMessage::Ok{
392-
message: "Danger! There's a breach in the hull.\nAll the resources in the stiva have been lost,\nyou need to go back to the base...".to_string()
393-
, is_skippable:true, tick:Tick::now()}
394-
}
395-
]);
390+
UiCallback::PushUiPopup { popup_message:
391+
PopupMessage::Ok {
392+
message: "Danger! There's a breach in the hull.\nAll the resources in the stiva have been lost,\nyou need to go back to the base...".to_string(),
393+
is_skippable:true, tick:Tick::now()}
394+
}
395+
]);
396396
}
397397
}
398398
time
@@ -417,24 +417,29 @@ impl SpaceAdventure {
417417
}
418418
}
419419

420-
// Resolve collisions
421-
for layer in 0..MAX_LAYER {
422-
let layer_entities = self.entities[layer].keys().collect_vec();
423-
if layer_entities.len() == 0 {
424-
continue;
425-
}
420+
// Resolve collisions (only if state is running)
421+
match self.state {
422+
SpaceAdventureState::Running { .. } => {
423+
for layer in 0..MAX_LAYER {
424+
let layer_entities = self.entities[layer].keys().collect_vec();
425+
if layer_entities.len() == 0 {
426+
continue;
427+
}
426428

427-
for idx in 0..layer_entities.len() - 1 {
428-
let entity = self.entities[layer]
429-
.get(layer_entities[idx])
430-
.expect("Entity should exist.");
431-
for other_idx in idx + 1..layer_entities.len() {
432-
let other = self.entities[layer]
433-
.get(layer_entities[other_idx])
434-
.expect("Entity should exist.");
435-
callbacks.append(&mut resolve_collision_between(entity, other));
429+
for idx in 0..layer_entities.len() - 1 {
430+
let entity = self.entities[layer]
431+
.get(layer_entities[idx])
432+
.expect("Entity should exist.");
433+
for other_idx in idx + 1..layer_entities.len() {
434+
let other = self.entities[layer]
435+
.get(layer_entities[other_idx])
436+
.expect("Entity should exist.");
437+
callbacks.append(&mut resolve_collision_between(entity, other));
438+
}
439+
}
436440
}
437441
}
442+
_ => {}
438443
}
439444

440445
// Execute callbacks
@@ -451,6 +456,8 @@ impl SpaceAdventure {
451456
self.insert_entity(Box::new(asteroid));
452457
}
453458

459+
let mut ui_callbacks = vec![];
460+
454461
if difficulty_level > DIFFICULTY_FOR_ASTEROID_PLANET_GENERATION {
455462
match self.asteroid_planet_state {
456463
AsteroidPlanetState::NotSpawned {
@@ -462,14 +469,19 @@ impl SpaceAdventure {
462469
self.asteroid_planet_state = AsteroidPlanetState::Spawned {
463470
image_number: id % MAX_ASTEROID_PLANET_IMAGE_TYPE,
464471
};
472+
ui_callbacks.push(UiCallback::PushUiPopup { popup_message:
473+
PopupMessage::Ok {
474+
message: "You've found an asteroid! Bring the spaceship in touch with it to claim it.".to_string(),
475+
is_skippable:true, tick:Tick::now()}
476+
});
465477
}
466478
}
467479
_ => {}
468480
}
469481
}
470482

471483
// TODO: spawn enemy ship
472-
Ok(vec![])
484+
Ok(ui_callbacks)
473485
}
474486

475487
pub fn image(&self, width: u32, height: u32, debug_view: bool) -> AppResult<RgbaImage> {

src/space_adventure/spaceship.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ impl SpaceshipEntity {
605605
let mut shooter_img = spaceship.shooter.image(size)?;
606606
shooter_img = rotate90(&shooter_img);
607607

608-
let y_offset = (shooter_img.height() - gif[0].height()) / 2;
608+
let y_offset = shooter_img.height().saturating_sub(gif[0].height()) / 2;
609609
let mut shooter_positions = vec![];
610610
for x in 0..shooter_img.width() {
611611
for y in 0..shooter_img.height() {
@@ -635,8 +635,8 @@ impl SpaceshipEntity {
635635
hit_boxes,
636636
current_durability: spaceship.current_durability() as f32,
637637
durability: spaceship.durability() as f32,
638-
base_thrust: spaceship.speed(0) * THRUST_MOD,
639-
base_speed: spaceship.speed(0) * MAX_SPACESHIP_SPEED_MOD * team_speed_bonus,
638+
base_thrust: spaceship.speed(0) * THRUST_MOD * team_speed_bonus,
639+
base_speed: spaceship.speed(0) * MAX_SPACESHIP_SPEED_MOD,
640640
maneuverability: 0.0,
641641
fuel: fuel as f32,
642642
fuel_capacity: spaceship.fuel_capacity(),

src/space_adventure/traits.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,7 @@ pub fn resolve_collision_between(
402402
id: one.id(),
403403
damage: other.collision_damage(),
404404
},
405-
SpaceCallback::DamageEntity {
406-
id: other.id(),
407-
damage: one.collision_damage(),
408-
},
405+
SpaceCallback::DestroyEntity { id: other.id() },
409406
];
410407
}
411408
(ColliderType::Asteroid, ColliderType::Spaceship) => resolve_collision_between(other, one),

0 commit comments

Comments
 (0)