Sword AI structure

This commit is contained in:
Sam 2023-01-17 21:32:12 -05:00
parent 7365fcb530
commit 99f6312e59
5 changed files with 214 additions and 37 deletions

View File

@ -2807,7 +2807,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
meta: _, meta: _,
} => CharacterState::DiveMelee(dive_melee::Data { } => CharacterState::DiveMelee(dive_melee::Data {
static_data: dive_melee::StaticData { static_data: dive_melee::StaticData {
buildup_duration: buildup_duration.map(|b| Duration::from_secs_f32(b)), buildup_duration: buildup_duration.map(Duration::from_secs_f32),
movement_duration: Duration::from_secs_f32(*movement_duration), movement_duration: Duration::from_secs_f32(*movement_duration),
swing_duration: Duration::from_secs_f32(*swing_duration), swing_duration: Duration::from_secs_f32(*swing_duration),
recover_duration: Duration::from_secs_f32(*recover_duration), recover_duration: Duration::from_secs_f32(*recover_duration),

View File

@ -80,12 +80,10 @@ impl CharacterBehavior for Data {
c.timer = Duration::default(); c.timer = Duration::default();
} }
} }
} else { } else if let CharacterState::ChargedMelee(c) = &mut update.character {
if let CharacterState::ChargedMelee(c) = &mut update.character {
c.stage_section = StageSection::Charge; c.stage_section = StageSection::Charge;
c.timer = Duration::default(); c.timer = Duration::default();
} }
}
}, },
StageSection::Charge => { StageSection::Charge => {
if input_is_pressed(data, self.static_data.ability_info.input) if input_is_pressed(data, self.static_data.ability_info.input)

View File

@ -62,18 +62,14 @@ impl CharacterBehavior for Data {
if let CharacterState::DiveMelee(c) = &mut update.character { if let CharacterState::DiveMelee(c) = &mut update.character {
c.timer = tick_attack_or_default(data, self.timer, None); c.timer = tick_attack_or_default(data, self.timer, None);
} }
} else { } else if let CharacterState::DiveMelee(c) = &mut update.character {
if let CharacterState::DiveMelee(c) = &mut update.character {
c.timer = Duration::default(); c.timer = Duration::default();
c.stage_section = StageSection::Action; c.stage_section = StageSection::Action;
} }
} } else if let CharacterState::DiveMelee(c) = &mut update.character {
} else {
if let CharacterState::DiveMelee(c) = &mut update.character {
c.timer = Duration::default(); c.timer = Duration::default();
c.stage_section = StageSection::Action; c.stage_section = StageSection::Action;
} }
}
}, },
StageSection::Movement => { StageSection::Movement => {
handle_move(data, &mut update, 1.0); handle_move(data, &mut update, 1.0);

View File

@ -70,11 +70,9 @@ impl CharacterBehavior for Data {
} }
// At end of state logic so an interrupt isn't overwritten // At end of state logic so an interrupt isn't overwritten
if !input_is_pressed(data, self.static_data.ability_info.input) { if !input_is_pressed(data, self.static_data.ability_info.input) && input_is_pressed(data, InputKind::Roll) {
if input_is_pressed(data, InputKind::Roll) {
handle_input(data, output_events, &mut update, InputKind::Roll); handle_input(data, output_events, &mut update, InputKind::Roll);
} }
}
update update
} }

View File

@ -512,6 +512,7 @@ impl<'a> AgentData<'a> {
enum IntCounters { enum IntCounters {
Tactics = 0, Tactics = 0,
ActionMode = 1,
} }
if !agent.action_state.initialized { if !agent.action_state.initialized {
@ -589,15 +590,185 @@ impl<'a> AgentData<'a> {
.unwrap_or(SwordTactics::Unskilled); .unwrap_or(SwordTactics::Unskilled);
agent.action_state.int_counters[IntCounters::Tactics as usize] = tactic as u8; agent.action_state.int_counters[IntCounters::Tactics as usize] = tactic as u8;
let auxiliary_key = ActiveAbilities::active_auxiliary_key(Some(self.inventory));
let mut set_sword_ability = |slot, skill| {
controller.push_event(ControlEvent::ChangeAbility {
slot,
auxiliary_key,
new_ability: AuxiliaryAbility::MainWeapon(skill),
})
};
match tactic {
SwordTactics::Unskilled => {},
SwordTactics::Basic => {
// Crescent slash
set_sword_ability(0, 0);
// Fell strike
set_sword_ability(1, 1);
// Skewer
set_sword_ability(2, 2);
// Cascade
set_sword_ability(3, 3);
// Cross cut
set_sword_ability(4, 4);
},
SwordTactics::HeavySimple => {
// Finisher
set_sword_ability(0, 5);
// Crescent slash
set_sword_ability(1, 0);
// Cascade
set_sword_ability(2, 3);
// Windmill slash
set_sword_ability(3, 6);
// Pommel strike
set_sword_ability(4, 7);
},
SwordTactics::AgileSimple => {
// Finisher
set_sword_ability(0, 5);
// Skewer
set_sword_ability(1, 2);
// Cross cut
set_sword_ability(2, 4);
// Quick draw
set_sword_ability(3, 8);
// Feint
set_sword_ability(4, 9);
},
SwordTactics::DefensiveSimple => {
// Finisher
set_sword_ability(0, 5);
// Crescent slash
set_sword_ability(1, 0);
// Fell strike
set_sword_ability(2, 1);
// Riposte
set_sword_ability(3, 10);
// Disengage
set_sword_ability(4, 11);
},
SwordTactics::CripplingSimple => {
// Finisher
set_sword_ability(0, 5);
// Fell strike
set_sword_ability(1, 1);
// Skewer
set_sword_ability(2, 2);
// Gouge
set_sword_ability(3, 12);
// Hamstring
set_sword_ability(4, 13);
},
SwordTactics::CleavingSimple => {
// Finisher
set_sword_ability(0, 5);
// Cascade
set_sword_ability(1, 3);
// Cross cut
set_sword_ability(2, 4);
// Whirlwind slice
set_sword_ability(3, 14);
// Earth splitter
set_sword_ability(4, 15);
},
SwordTactics::HeavyAdvanced => {
// Finisher
set_sword_ability(0, 5);
// Windmill slash
set_sword_ability(1, 6);
// Pommel strike
set_sword_ability(2, 7);
// Fortitude
set_sword_ability(3, 16);
// Pillar Thrust
set_sword_ability(4, 17);
},
SwordTactics::AgileAdvanced => {
// Finisher
set_sword_ability(0, 5);
// Quick draw
set_sword_ability(1, 8);
// Feint
set_sword_ability(2, 9);
// Dancing edge
set_sword_ability(3, 18);
// Flurry
set_sword_ability(4, 19);
},
SwordTactics::DefensiveAdvanced => {
// Finisher
set_sword_ability(0, 5);
// Riposte
set_sword_ability(1, 10);
// Disengage
set_sword_ability(2, 11);
// Stalwart sword
set_sword_ability(3, 20);
// Deflect
set_sword_ability(4, 21);
},
SwordTactics::CripplingAdvanced => {
// Finisher
set_sword_ability(0, 5);
// Gouge
set_sword_ability(1, 12);
// Hamstring
set_sword_ability(2, 13);
// Eviscerate
set_sword_ability(3, 22);
// Bloody gash
set_sword_ability(4, 23);
},
SwordTactics::CleavingAdvanced => {
// Finisher
set_sword_ability(0, 5);
// Whirlwind slice
set_sword_ability(1, 14);
// Earth splitter
set_sword_ability(2, 15);
// Blade fever
set_sword_ability(3, 24);
// Sky splitter
set_sword_ability(4, 25);
},
} }
// Action modes agent.action_state.int_counters[IntCounters::ActionMode as usize] =
const RECKLESS: usize = 0; ActionMode::Guarded as u8;
const GUARDED: usize = 1; }
const RETREAT: usize = 2;
match SwordTactics::from_u8(agent.action_state.int_counters[IntCounters::Tactics as usize]) enum ActionMode {
{ Reckless = 0,
Guarded = 1,
Fleeing = 2,
}
impl ActionMode {
fn from_u8(x: u8) -> Self {
match x {
0 => ActionMode::Reckless,
1 => ActionMode::Guarded,
2 => ActionMode::Fleeing,
_ => ActionMode::Guarded,
}
}
}
let attempt_attack = match ActionMode::from_u8(
agent.action_state.int_counters[IntCounters::ActionMode as usize],
) {
ActionMode::Reckless => true,
ActionMode::Guarded => true,
ActionMode::Fleeing => false,
};
let attack_failed = if attempt_attack {
match SwordTactics::from_u8(
agent.action_state.int_counters[IntCounters::Tactics as usize],
) {
SwordTactics::Unskilled => {}, SwordTactics::Unskilled => {},
SwordTactics::Basic => {}, SwordTactics::Basic => {},
SwordTactics::HeavySimple => {}, SwordTactics::HeavySimple => {},
@ -610,7 +781,21 @@ impl<'a> AgentData<'a> {
SwordTactics::DefensiveAdvanced => {}, SwordTactics::DefensiveAdvanced => {},
SwordTactics::CripplingAdvanced => {}, SwordTactics::CripplingAdvanced => {},
SwordTactics::CleavingAdvanced => {}, SwordTactics::CleavingAdvanced => {},
_ => {}, }
true
} else {
false
};
if attack_failed {
self.path_toward_target(
agent,
controller,
tgt_data.pos.0,
read_data,
Path::Separate,
None,
);
} }
} }