Skip to content

Commit

Permalink
feat: introduce quick adventure groups
Browse files Browse the repository at this point in the history
  • Loading branch information
RakuJa committed Jul 24, 2024
1 parent 463910f commit 949d574
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 17 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ validator = {version="0.18.1", features = ["derive"]}
utoipa = { version = "5.0.0-alpha.0", features = ["actix_extras"] }
utoipa-swagger-ui = { version = "7.1.1-alpha.0", features = ["actix-web"] }

sqlx = { version = "0.7.4", features = ["runtime-async-std", "sqlite"] }
cached = { version = "0.52.0", features = ["async"] }
sqlx = { version = "0.8.0", features = ["runtime-async-std", "sqlite"] }
cached = { version = "0.53.1", features = ["async"] }

anyhow = "1.0.86"
serde = { version = "1.0.204", features = ["derive"] }
Expand All @@ -46,12 +46,12 @@ regex = "1.10.5"

dotenvy = "0.15.7"

env_logger = "0.11.3"
env_logger = "0.11.4"
log = "0.4.22"
once_cell = "1.19.0"

[build-dependencies]
tokio = { version = "1", features = ["macros", "rt-multi-thread", "rt"] }
anyhow = "1.0.86"
sqlx = {version = "0.7.4", features = ["runtime-async-std", "sqlite"]}
sqlx = {version = "0.8.0", features = ["runtime-async-std", "sqlite"]}
dotenvy = "0.15.7"
51 changes: 51 additions & 0 deletions src/models/encounter_structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub struct RandomEncounterData {
pub creature_types: Option<Vec<CreatureTypeEnum>>,
pub creature_roles: Option<Vec<CreatureRoleEnum>>,
pub challenge: Option<EncounterChallengeEnum>,
pub adventure_group: Option<AdventureGroupEnum>,
#[validate(range(min = 1, max = 30))]
pub min_creatures: Option<u8>,
#[validate(range(min = 1, max = 30))]
Expand Down Expand Up @@ -77,6 +78,56 @@ impl Distribution<EncounterChallengeEnum> for Standard {
}
}

#[derive(
Serialize, Deserialize, ToSchema, Default, EnumIter, Eq, PartialEq, Hash, Ord, PartialOrd, Clone,
)]
pub enum AdventureGroupEnum {
#[serde(alias = "boss_and_lackeys", alias = "BOSS_AND_LACKEYS", alias = "BALA")]
//(120 XP): One creature of party level + 2, four creatures of party level – 4
BossAndLackeys,
#[serde(
alias = "boss_and_lieutenant",
alias = "BOSS_AND_LIEUTENANT",
alias = "BALI"
)]
//(120 XP): One creature of party level + 2, one creature of party level
BossAndLieutenant,
#[default]
#[serde(alias = "elite_enemies", alias = "ELITE_ENEMIES", alias = "EE")]
//(120 XP): Three creatures of party level
EliteEnemies,
#[serde(
alias = "lieutenant_and_lackeys",
alias = "LIEUTENANT_AND_LACKEYS",
alias = "LAL"
)]
//(80 XP): One creature of party level, four creatures of party level – 4
LieutenantAndLackeys,
#[serde(alias = "mated_pair", alias = "MATED_PAIR", alias = "MP")]
//(80 XP): Two creatures of party level
MatedPair,
#[serde(alias = "troop", alias = "TROOP", alias = "T")]
//(80 XP): One creature of party level, two creatures of party level – 2
Troop,
#[serde(alias = "mook_squad", alias = "MOOK_SQUAD", alias = "MS")]
//(60 XP): Six creatures of party level – 4
MookSquad,
}

impl Distribution<AdventureGroupEnum> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> AdventureGroupEnum {
match rng.gen_range(0..7) {
0 => AdventureGroupEnum::BossAndLackeys,
1 => AdventureGroupEnum::BossAndLieutenant,
2 => AdventureGroupEnum::EliteEnemies,
3 => AdventureGroupEnum::LieutenantAndLackeys,
4 => AdventureGroupEnum::MatedPair,
5 => AdventureGroupEnum::Troop,
_ => AdventureGroupEnum::MookSquad,
}
}
}

pub struct ExpRange {
pub lower_bound: i64,
pub upper_bound: i64,
Expand Down
3 changes: 2 additions & 1 deletion src/routes/encounter.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::models::encounter_structs::{
EncounterChallengeEnum, EncounterParams, RandomEncounterData,
AdventureGroupEnum, EncounterChallengeEnum, EncounterParams, RandomEncounterData,
};
use crate::services::encounter_service;
use crate::services::encounter_service::EncounterInfoResponse;
Expand All @@ -25,6 +25,7 @@ pub fn init_docs(doc: &mut utoipa::openapi::OpenApi) {
RandomEncounterData,
EncounterParams,
EncounterChallengeEnum,
AdventureGroupEnum,
RandomEncounterGeneratorResponse,
))
)]
Expand Down
90 changes: 78 additions & 12 deletions src/services/encounter_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::models::creature::creature_component::filter_struct::FilterStruct;
use crate::models::creature::creature_filter_enum::CreatureFilter;
use crate::models::creature::creature_struct::Creature;
use crate::models::encounter_structs::{
EncounterChallengeEnum, EncounterParams, RandomEncounterData,
AdventureGroupEnum, EncounterChallengeEnum, EncounterParams, RandomEncounterData,
};
use crate::models::response_data::ResponseCreature;
use crate::services::encounter_handler::encounter_calculator;
Expand Down Expand Up @@ -78,18 +78,8 @@ async fn calculate_random_encounter(
enc_data: RandomEncounterData,
party_levels: Vec<i64>,
) -> Result<RandomEncounterGeneratorResponse> {
let enc_diff = enc_data.challenge.unwrap_or(rand::random());
let is_pwl_on = enc_data.is_pwl_on;
let lvl_combinations = encounter_calculator::calculate_lvl_combination_for_encounter(
&enc_diff,
&party_levels,
is_pwl_on,
);
let filtered_lvl_combinations = encounter_calculator::filter_combinations_outside_range(
lvl_combinations,
enc_data.min_creatures,
enc_data.max_creatures,
);
let filtered_lvl_combinations = get_lvl_combinations(&enc_data, &party_levels);
let unique_levels = HashSet::from_iter(
filtered_lvl_combinations
.clone()
Expand Down Expand Up @@ -278,3 +268,79 @@ async fn get_filtered_creatures(
) -> Result<Vec<Creature>> {
get_creatures_passing_all_filters(app_state, filter_map, allow_weak, allow_elite).await
}

fn get_lvl_combinations(enc_data: &RandomEncounterData, party_levels: &[i64]) -> HashSet<Vec<i64>> {
if let Some(adv_group) = enc_data.adventure_group.as_ref() {
get_adventure_group_lvl_combinations(adv_group, party_levels)
} else {
get_standard_lvl_combinations(enc_data, party_levels)
}
}

fn get_standard_lvl_combinations(
enc_data: &RandomEncounterData,
party_levels: &[i64],
) -> HashSet<Vec<i64>> {
let enc_diff = enc_data.challenge.clone().unwrap_or(rand::random());
let lvl_combinations = encounter_calculator::calculate_lvl_combination_for_encounter(
&enc_diff,
party_levels,
enc_data.is_pwl_on,
);
encounter_calculator::filter_combinations_outside_range(
lvl_combinations,
enc_data.min_creatures,
enc_data.max_creatures,
)
}

fn get_adventure_group_lvl_combinations(
adv_group: &AdventureGroupEnum,
party_levels: &[i64],
) -> HashSet<Vec<i64>> {
let party_avg = party_levels.iter().sum::<i64>() / party_levels.len() as i64;
let mut result = HashSet::new();
result.insert(match adv_group {
AdventureGroupEnum::BossAndLackeys => {
//One creature of party level + 2, four creatures of party level – 4
vec![
party_avg + 2,
party_avg - 4,
party_avg - 4,
party_avg - 4,
party_avg - 4,
]
}
AdventureGroupEnum::BossAndLieutenant => {
//One creature of party level + 2, one creature of party level
vec![party_avg + 2, party_avg]
}
AdventureGroupEnum::EliteEnemies => {
//Three creatures of party level
vec![party_avg; 3]
}
AdventureGroupEnum::LieutenantAndLackeys => {
//One creature of party level, four creatures of party level – 4
vec![
party_avg,
party_avg - 4,
party_avg - 4,
party_avg - 4,
party_avg - 4,
]
}
AdventureGroupEnum::MatedPair => {
//Two creatures of party level
vec![party_avg; 2]
}
AdventureGroupEnum::Troop => {
//One creature of party level, two creatures of party level – 2
vec![party_avg, party_avg - 2, party_avg - 2]
}
AdventureGroupEnum::MookSquad => {
//Six creatures of party level – 4
vec![party_avg - 4; 6]
}
});
result
}

0 comments on commit 949d574

Please sign in to comment.