From c859371ddb33d31d1d47a86a34938404892822c0 Mon Sep 17 00:00:00 2001 From: liids Date: Sat, 15 Jun 2019 09:54:47 +0200 Subject: [PATCH 1/8] Merge all spawn commands into one --- common/src/npc.rs | 15 +++++ server/src/cmd.rs | 150 ++++++++++++++++++---------------------------- 2 files changed, 72 insertions(+), 93 deletions(-) diff --git a/common/src/npc.rs b/common/src/npc.rs index b588419798..88cc0f4f18 100644 --- a/common/src/npc.rs +++ b/common/src/npc.rs @@ -3,7 +3,9 @@ use lazy_static::lazy_static; use rand::seq::SliceRandom; use serde_json; use std::sync::Arc; +use std::str::FromStr; +#[derive(Clone, Copy)] pub enum NpcKind { Humanoid, Wolf, @@ -20,6 +22,19 @@ impl NpcKind { } } +impl FromStr for NpcKind { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + "humanoid" => Ok(NpcKind::Humanoid), + "wolf" => Ok(NpcKind::Wolf), + "pig" => Ok(NpcKind::Pig), + _ => Err(()) + } + } +} + lazy_static! { static ref NPC_NAMES_JSON: Arc = assets::load_expect("common/npc_names.json"); diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 468a72e57a..dc5efc85ec 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -86,22 +86,10 @@ lazy_static! { handle_kill ), ChatCommand::new( - "pig", - "{}", - "/pig : Spawn a test pig NPC", - handle_pet_pig - ), - ChatCommand::new( - "wolf", - "{}", - "/wolf : Spawn a test wolf NPC", - handle_pet_wolf - ), - ChatCommand::new( - "enemy", - "{}", - "/enemy : Spawn a test enemy NPC", - handle_enemy + "spawn", + "{} {} {d}", + "/spawn : Spawn a test entity", + handle_spawn ), ChatCommand::new( "help", "", "/help: Display this message", handle_help) @@ -222,84 +210,41 @@ fn handle_tp(server: &mut Server, entity: EcsEntity, args: String, action: &Chat } } -fn handle_pet_pig(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) { - match server - .state - .read_component_cloned::(entity) - { - Some(mut pos) => { - pos.0.x += 1.0; // Temp fix TODO: Solve NaN issue with positions of pets - server - .create_npc( - pos, - get_npc_name(NpcKind::Pig), - comp::Body::Quadruped(comp::QuadrupedBody::random()), - ) - .with(comp::Agent::Pet { - target: entity, - offset: Vec2::zero(), - }) - .build(); - server - .clients - .notify(entity, ServerMsg::Chat("Spawned pet!".to_owned())); - } - None => server +fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { + let (opt_align, opt_id, opt_amount) = scan_fmt!(&args, action.arg_fmt, String, NpcKind, u32); + // This should probably be just an enum and be handled with scan_fmt! + let opt_agent = alignment_to_agent(&opt_align.unwrap_or(String::new()), entity); + match (opt_agent, opt_id, opt_amount) { + (Some(agent), Some(id), Some(amount)) => { + match server + .state + .read_component_cloned::(entity) + { + Some(mut pos) => { + pos.0.x += 1.0; // Temp fix TODO: Solve NaN issue with positions of pets + let body = kind_to_body(id); + for _ in 0..amount { + server + .create_npc( + pos, + get_npc_name(id), + body, + ) + .with(agent) + .build(); + } + server + .clients + .notify(entity, ServerMsg::Chat(format!("Spawned {} entities", amount).to_owned())); + } + None => server + .clients + .notify(entity, ServerMsg::Chat("You have no position!".to_owned())), + } + }, + _ => server .clients - .notify(entity, ServerMsg::Chat("You have no position!".to_owned())), - } -} - -fn handle_pet_wolf(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) { - match server - .state - .read_component_cloned::(entity) - { - Some(mut pos) => { - pos.0.x += 1.0; // Temp fix TODO: Solve NaN issue with positions of pets - server - .create_npc( - pos, - get_npc_name(NpcKind::Wolf), - comp::Body::QuadrupedMedium(comp::QuadrupedMediumBody::random()), - ) - .with(comp::Agent::Pet { - target: entity, - offset: Vec2::zero(), - }) - .build(); - server - .clients - .notify(entity, ServerMsg::Chat("Spawned pet!".to_owned())); - } - None => server - .clients - .notify(entity, ServerMsg::Chat("You have no position!".to_owned())), - } -} - -fn handle_enemy(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) { - match server - .state - .read_component_cloned::(entity) - { - Some(mut pos) => { - pos.0.x += 1.0; // Temp fix TODO: Solve NaN issue with positions of pets - server - .create_npc( - pos, - get_npc_name(NpcKind::Humanoid), - comp::Body::Humanoid(comp::HumanoidBody::random()), - ) - .with(comp::Agent::Enemy { target: None }) - .build(); - server - .clients - .notify(entity, ServerMsg::Chat("Spawned enemy!".to_owned())); - } - None => server - .clients - .notify(entity, ServerMsg::Chat("You have no position!".to_owned())), + .notify(entity, ServerMsg::Chat(String::from(action.help_string))), } } @@ -310,3 +255,22 @@ fn handle_help(server: &mut Server, entity: EcsEntity, _args: String, _action: & .notify(entity, ServerMsg::Chat(String::from(cmd.help_string))); } } + +fn alignment_to_agent(alignment: &str, target: EcsEntity) -> Option { + match alignment { + "hostile" => Some(comp::Agent::Enemy { target: None }), + "friendly" => Some ( comp::Agent::Pet { + target, + offset: Vec2::zero() } + ), + _ => None + } +} + +fn kind_to_body(kind: NpcKind) -> comp::Body { + match kind { + NpcKind::Humanoid => comp::Body::Humanoid(comp::HumanoidBody::random()), + NpcKind::Pig => comp::Body::Quadruped(comp::QuadrupedBody::random()), + NpcKind::Wolf => comp::Body::QuadrupedMedium(comp::QuadrupedMediumBody::random()), + } +} From 2cc2a36be2e8b793490078f46c8cba3bf13dca54 Mon Sep 17 00:00:00 2001 From: liids Date: Sat, 15 Jun 2019 10:15:04 +0200 Subject: [PATCH 2/8] make amount optional --- server/src/cmd.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/server/src/cmd.rs b/server/src/cmd.rs index dc5efc85ec..c3a13f7db6 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -88,7 +88,7 @@ lazy_static! { ChatCommand::new( "spawn", "{} {} {d}", - "/spawn : Spawn a test entity", + "/spawn [amount] : Spawn a test entity", handle_spawn ), ChatCommand::new( @@ -211,9 +211,15 @@ fn handle_tp(server: &mut Server, entity: EcsEntity, args: String, action: &Chat } fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { - let (opt_align, opt_id, opt_amount) = scan_fmt!(&args, action.arg_fmt, String, NpcKind, u32); - // This should probably be just an enum and be handled with scan_fmt! + let (opt_align, opt_id, opt_amount) = scan_fmt!(&args, action.arg_fmt, String, NpcKind, String); + // This should be just an enum and be handled with scan_fmt! let opt_agent = alignment_to_agent(&opt_align.unwrap_or(String::new()), entity); + + // Make sure the amount is either not provided or a valid value + let opt_amount = if let Some(amount) = opt_amount { + amount.parse().ok() + } else { Some(1) }; + match (opt_agent, opt_id, opt_amount) { (Some(agent), Some(id), Some(amount)) => { match server From cca41a3333829e107c00f6aaffb74e10171c69f9 Mon Sep 17 00:00:00 2001 From: liids Date: Sat, 15 Jun 2019 11:32:07 +0200 Subject: [PATCH 3/8] fix negative spawn amounts --- server/src/cmd.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/src/cmd.rs b/server/src/cmd.rs index c3a13f7db6..9a84471f1e 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -216,7 +216,7 @@ fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &C let opt_agent = alignment_to_agent(&opt_align.unwrap_or(String::new()), entity); // Make sure the amount is either not provided or a valid value - let opt_amount = if let Some(amount) = opt_amount { + let opt_amount: Option = if let Some(amount) = opt_amount { amount.parse().ok() } else { Some(1) }; @@ -269,6 +269,7 @@ fn alignment_to_agent(alignment: &str, target: EcsEntity) -> Option target, offset: Vec2::zero() } ), + // passive? _ => None } } From f726d755b7ac24227bdbd4b836b78193a6888418 Mon Sep 17 00:00:00 2001 From: liids Date: Sat, 15 Jun 2019 13:48:14 +0200 Subject: [PATCH 4/8] fix formatting --- common/src/npc.rs | 4 ++-- server/src/cmd.rs | 29 ++++++++++++++--------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/common/src/npc.rs b/common/src/npc.rs index 88cc0f4f18..76460b0efa 100644 --- a/common/src/npc.rs +++ b/common/src/npc.rs @@ -2,8 +2,8 @@ use crate::assets; use lazy_static::lazy_static; use rand::seq::SliceRandom; use serde_json; -use std::sync::Arc; use std::str::FromStr; +use std::sync::Arc; #[derive(Clone, Copy)] pub enum NpcKind { @@ -30,7 +30,7 @@ impl FromStr for NpcKind { "humanoid" => Ok(NpcKind::Humanoid), "wolf" => Ok(NpcKind::Wolf), "pig" => Ok(NpcKind::Pig), - _ => Err(()) + _ => Err(()), } } } diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 9a84471f1e..ed6c67b9b5 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -218,7 +218,9 @@ fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &C // Make sure the amount is either not provided or a valid value let opt_amount: Option = if let Some(amount) = opt_amount { amount.parse().ok() - } else { Some(1) }; + } else { + Some(1) + }; match (opt_agent, opt_id, opt_amount) { (Some(agent), Some(id), Some(amount)) => { @@ -231,23 +233,20 @@ fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &C let body = kind_to_body(id); for _ in 0..amount { server - .create_npc( - pos, - get_npc_name(id), - body, - ) + .create_npc(pos, get_npc_name(id), body) .with(agent) .build(); } - server - .clients - .notify(entity, ServerMsg::Chat(format!("Spawned {} entities", amount).to_owned())); + server.clients.notify( + entity, + ServerMsg::Chat(format!("Spawned {} entities", amount).to_owned()), + ); } None => server .clients .notify(entity, ServerMsg::Chat("You have no position!".to_owned())), } - }, + } _ => server .clients .notify(entity, ServerMsg::Chat(String::from(action.help_string))), @@ -265,12 +264,12 @@ fn handle_help(server: &mut Server, entity: EcsEntity, _args: String, _action: & fn alignment_to_agent(alignment: &str, target: EcsEntity) -> Option { match alignment { "hostile" => Some(comp::Agent::Enemy { target: None }), - "friendly" => Some ( comp::Agent::Pet { - target, - offset: Vec2::zero() } - ), + "friendly" => Some(comp::Agent::Pet { + target, + offset: Vec2::zero(), + }), // passive? - _ => None + _ => None, } } From 8b2b931c170d0113c0f0d94439d83cb987c70e19 Mon Sep 17 00:00:00 2001 From: liids Date: Sat, 15 Jun 2019 14:30:05 +0200 Subject: [PATCH 5/8] make minimum spawn amount higher than 0 --- server/src/cmd.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/src/cmd.rs b/server/src/cmd.rs index ed6c67b9b5..51767a6a8a 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -217,7 +217,10 @@ fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &C // Make sure the amount is either not provided or a valid value let opt_amount: Option = if let Some(amount) = opt_amount { - amount.parse().ok() + match amount.parse().ok() { + Some(x) if x == 0 => None, + x => x + } } else { Some(1) }; From 6670c2b8fa5ba4a330a3ce0c68f83ea1d7cb29b6 Mon Sep 17 00:00:00 2001 From: liids Date: Sat, 15 Jun 2019 14:55:06 +0200 Subject: [PATCH 6/8] fix formatting --- server/src/cmd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 51767a6a8a..2c5f3f2b55 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -219,7 +219,7 @@ fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &C let opt_amount: Option = if let Some(amount) = opt_amount { match amount.parse().ok() { Some(x) if x == 0 => None, - x => x + x => x, } } else { Some(1) From bcf7127736652f3bbb539a0a4092ac94d00455ea Mon Sep 17 00:00:00 2001 From: liids Date: Sat, 15 Jun 2019 15:42:39 +0200 Subject: [PATCH 7/8] make it more laconic --- server/src/cmd.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 2c5f3f2b55..5bdca48a22 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -216,14 +216,10 @@ fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &C let opt_agent = alignment_to_agent(&opt_align.unwrap_or(String::new()), entity); // Make sure the amount is either not provided or a valid value - let opt_amount: Option = if let Some(amount) = opt_amount { - match amount.parse().ok() { - Some(x) if x == 0 => None, - x => x, - } - } else { - Some(1) - }; + let opt_amount = opt_amount + .and_then(|a| a.parse().ok()) + .or(Some(1)) + .and_then(|a| if a > 0 { Some(a) } else { None }); match (opt_agent, opt_id, opt_amount) { (Some(agent), Some(id), Some(amount)) => { From e670f9b1262ec3c808d862b5d5662440b0eb5356 Mon Sep 17 00:00:00 2001 From: liids Date: Sat, 15 Jun 2019 17:23:53 +0200 Subject: [PATCH 8/8] small fixes --- server/src/cmd.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 5bdca48a22..ba8480420d 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -212,13 +212,12 @@ fn handle_tp(server: &mut Server, entity: EcsEntity, args: String, action: &Chat fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { let (opt_align, opt_id, opt_amount) = scan_fmt!(&args, action.arg_fmt, String, NpcKind, String); - // This should be just an enum and be handled with scan_fmt! + // This should be just an enum handled with scan_fmt! let opt_agent = alignment_to_agent(&opt_align.unwrap_or(String::new()), entity); // Make sure the amount is either not provided or a valid value let opt_amount = opt_amount - .and_then(|a| a.parse().ok()) - .or(Some(1)) + .map_or(Some(1), |a| a.parse().ok()) .and_then(|a| if a > 0 { Some(a) } else { None }); match (opt_agent, opt_id, opt_amount) {