diff --git a/CHANGELOG.md b/CHANGELOG.md index f65a340d3a..8321bc2488 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -125,6 +125,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Wolf AI will no longer circle into walls and will instead use the power of raycasts to stop early - Squirrels are no longer immune to arrows at some angles. - /spawn command's auto-complete now works for species names +- Mindflayer AI now correctly summons husks at certain HP thresholds. ## [0.9.0] - 2021-03-20 diff --git a/Cargo.lock b/Cargo.lock index a66b55e18c..c3cf499305 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2399,15 +2399,6 @@ dependencies = [ "serde", ] -[[package]] -name = "inline_tweak" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7033e97b20277cc0d043226d1940fa7719ff08d2305d1fc7421e53066d00eb4b" -dependencies = [ - "lazy_static", -] - [[package]] name = "inotify" version = "0.7.1" @@ -5523,7 +5514,6 @@ name = "veloren-common" version = "0.9.0" dependencies = [ "approx 0.4.0", - "assets_manager", "bitflags", "criterion", "crossbeam-channel", @@ -5532,7 +5522,6 @@ dependencies = [ "dot_vox", "enum-iterator", "hashbrown", - "image", "indexmap", "lazy_static", "num-derive", @@ -5540,10 +5529,8 @@ dependencies = [ "ordered-float 2.1.1", "rand 0.8.3", "rayon", - "ron", "roots", "serde", - "serde_json", "serde_repr", "slab", "slotmap", @@ -5557,9 +5544,22 @@ dependencies = [ "tracing-subscriber", "uuid", "vek", + "veloren-common-assets", "veloren-common-base", ] +[[package]] +name = "veloren-common-assets" +version = "0.9.0" +dependencies = [ + "assets_manager", + "dot_vox", + "image", + "lazy_static", + "ron", + "tracing", +] + [[package]] name = "veloren-common-base" version = "0.9.0" @@ -5652,6 +5652,19 @@ dependencies = [ "veloren-common-net", ] +[[package]] +name = "veloren-i18n" +version = "0.9.0" +dependencies = [ + "deunicode", + "git2", + "hashbrown", + "ron", + "serde", + "tracing", + "veloren-common-assets", +] + [[package]] name = "veloren-network" version = "0.3.0" @@ -5736,7 +5749,6 @@ dependencies = [ "crossbeam-channel", "futures-util", "hashbrown", - "inline_tweak", "itertools 0.10.0", "lazy_static", "num_cpus", @@ -5805,7 +5817,6 @@ dependencies = [ "cpal", "criterion", "crossbeam", - "deunicode", "directories-next", "dispatch 0.1.4", "dot_vox", @@ -5815,7 +5826,6 @@ dependencies = [ "gfx_device_gl", "gfx_gl", "gilrs", - "git2", "glsl-include", "glutin", "glyph_brush", @@ -5853,6 +5863,7 @@ dependencies = [ "veloren-common-net", "veloren-common-state", "veloren-common-systems", + "veloren-i18n", "veloren-server", "veloren-voxygen-anim", "veloren-world", diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index 53e20f0b40..456471c106 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -280,7 +280,8 @@ pub struct Agent { pub struct ActionState { pub timer: f32, pub counter: f32, - pub condition: u8, + pub condition: bool, + pub int_counter: u8, } impl Agent { diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 3f0d010252..1547bc9838 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -577,33 +577,27 @@ fn handle_ability(data: &JoinData, update: &mut StateUpdate, input: InputKind) { .inventory .equipped(equip_slot) .map(|i| &i.item_config_expect().abilities) - .and_then(|abilities| { - tracing::info!("ability: {:?} {:?}", input, abilities); - match input { - InputKind::Primary => Some(abilities.primary.clone()), - InputKind::Secondary => Some(abilities.secondary.clone()), - InputKind::Ability(0) => abilities.abilities.get(0).cloned().and_then(unlocked), - InputKind::Ability(skill_index) => abilities - .abilities - .get(skill_index) - .cloned() - .and_then(unlocked), - InputKind::Roll | InputKind::Jump | InputKind::Fly | InputKind::Block => None, - } + .and_then(|abilities| match input { + InputKind::Primary => Some(abilities.primary.clone()), + InputKind::Secondary => Some(abilities.secondary.clone()), + InputKind::Ability(0) => abilities.abilities.get(0).cloned().and_then(unlocked), + InputKind::Ability(i) => abilities + .abilities + .get(if i < 2 { skill_index } else { i }) + .cloned() + .and_then(unlocked), + InputKind::Roll | InputKind::Jump | InputKind::Fly | InputKind::Block => None, }) .map(|a| { let tool = unwrap_tool_data(data, equip_slot).map(|t| t.kind); - tracing::info!("ability tool: {:?} {:?}", input, tool); a.adjusted_by_skills(&data.skill_set, tool) }) .filter(|ability| ability.requirements_paid(data, update)) { - tracing::info!("ability before setting state: {:?} {:?}", input, ability); update.character = CharacterState::from(( &ability, AbilityInfo::from_input(data, matches!(equip_slot, EquipSlot::Offhand), input), )); - tracing::info!("ability setting state: {:?} {:?}", input, update.character); } } } @@ -807,14 +801,12 @@ impl AbilityInfo { tool_data.map(|t| HandInfo::from_main_tool(t, from_offhand)), ); - let ret = Self { + Self { tool, hand, input, input_attr: data.controller.queued_inputs.get(&input).copied(), - }; - tracing::info!("AbilityInfo::from_input: {:?} {:?}", input, ret); - ret + } } } diff --git a/server/Cargo.toml b/server/Cargo.toml index 3cfce9de29..7d81585259 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -22,7 +22,7 @@ common-net = { package = "veloren-common-net", path = "../common/net" } world = { package = "veloren-world", path = "../world" } network = { package = "veloren-network", path = "../network", features = ["metrics", "compression"], default-features = false } -inline_tweak = "1.0.8" +# inline_tweak = "1.0.8" specs = { git = "https://github.com/amethyst/specs.git", features = ["shred-derive"], rev = "5a9b71035007be0e3574f35184acac1cd4530496" } specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git", rev = "b65fb220e94f5d3c9bc30074a076149763795556" } diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index 1631dc3fa5..55cb98b8f9 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -2996,18 +2996,12 @@ impl<'a> AgentData<'a> { ) { const MINDFLAYER_ATTACK_DIST: f32 = 16.0; const MINION_SUMMON_THRESHOLD: f32 = 0.20; - // Bit index of action_state.condition for whether the mindflayer initialized - // minion summoning state - const MINDFLAYER_INITIALIZED_THRESHOLD: usize = 0; - // Bit index of action_state.condition for how many fireballs left to shoot - // before blinking (this is a 2 bit number, from 0-3) - const MINDFLAYER_NUM_FIREBALLS_LO: usize = 1; - const MINDFLAYER_NUM_FIREBALLS_MASK: usize = 0b110; let health_fraction = self.health.map_or(0.5, |h| h.fraction()); - // Sets counter at start of combat - if (agent.action_state.condition & (1 << MINDFLAYER_INITIALIZED_THRESHOLD)) == 0 { + // Sets counter at start of combat, using `condition` to keep track of whether + // it was already intitialized + if !agent.action_state.condition { agent.action_state.counter = 1.0 - MINION_SUMMON_THRESHOLD; - agent.action_state.condition |= 1 << MINDFLAYER_INITIALIZED_THRESHOLD; + agent.action_state.condition = true; } agent.action_state.timer = (agent.action_state.timer - read_data.dt.0 as f32).max(0.0); if agent.action_state.timer > 0.0 { @@ -3020,7 +3014,6 @@ impl<'a> AgentData<'a> { .actions .push(ControlAction::basic_input(InputKind::Ability(2))); - //tracing::info!("Pushing summon state: {:?}", agent); if matches!(self.char_state, CharacterState::BasicSummon(c) if matches!(c.stage_section, StageSection::Recover)) { agent.action_state.counter -= MINION_SUMMON_THRESHOLD; @@ -3029,16 +3022,14 @@ impl<'a> AgentData<'a> { self.char_state, CharacterState::BasicSummon(_) | CharacterState::Blink(_) ) { - // Deliberately do nothing here to prevent overwriting summon/blink state with another - // input + // Deliberately do nothing here to prevent overwriting summon/blink + // state with another input } else if mindflayer_is_far { - // If too far from target, throw a random number of necrotic spheres at them and then - // blink to them. - let num_fireballs = (agent.action_state.condition & 0b110) >> 1; - if num_fireballs == 0 { - let new_num_fireballs = rand::random::() % 4; - agent.action_state.condition &= !0b110; - agent.action_state.condition |= new_num_fireballs << 1; + // If too far from target, throw a random number of necrotic spheres at them and + // then blink to them. + let num_fireballs = &mut agent.action_state.int_counter; + if *num_fireballs == 0 { + *num_fireballs = rand::random::() % 4; controller.actions.push(ControlAction::StartInput { input: InputKind::Ability(0), target_entity: agent @@ -3049,9 +3040,7 @@ impl<'a> AgentData<'a> { select_pos: None, }); } else { - let new_num_fireballs = num_fireballs - 1; - agent.action_state.condition &= !0b110; - agent.action_state.condition |= new_num_fireballs << 1; + *num_fireballs -= 1; controller.actions.push(ControlAction::StartInput { input: InputKind::Ability(1), target_entity: agent @@ -3393,9 +3382,6 @@ impl<'a> AgentData<'a> { const MINOTAUR_FRENZY_THRESHOLD: f32 = 0.5; const MINOTAUR_ATTACK_RANGE: f32 = 5.0; const MINOTAUR_CHARGE_DISTANCE: f32 = 15.0; - // Bit index of the action_state.condition if the minotaur should use secondary - // instead of primary - const MINOTAUR_STATE_SECONDARY: usize = 0; let minotaur_attack_distance = self.body.map_or(0.0, |b| b.radius()) + MINOTAUR_ATTACK_RANGE; let health_fraction = self.health.map_or(1.0, |h| h.fraction()); @@ -3434,20 +3420,18 @@ impl<'a> AgentData<'a> { .push(ControlAction::basic_input(InputKind::Ability(0))); } } else if attack_data.dist_sqrd < minotaur_attack_distance.powi(2) { - if (agent.action_state.condition & (1 << MINOTAUR_STATE_SECONDARY)) != 0 - && !self.char_state.is_attack() - { + if agent.action_state.condition && !self.char_state.is_attack() { // Cripple target if not just used cripple controller .actions .push(ControlAction::basic_input(InputKind::Secondary)); - agent.action_state.condition &= !(1 << MINOTAUR_STATE_SECONDARY); + agent.action_state.condition = false; } else if !self.char_state.is_attack() { // Cleave target if not just used cleave controller .actions .push(ControlAction::basic_input(InputKind::Primary)); - agent.action_state.condition |= 1 << MINOTAUR_STATE_SECONDARY; + agent.action_state.condition = true; } } // Make minotaur move towards target