mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Primary and secondary abilities can now be contextual. BasicStance character state added.
This commit is contained in:
parent
9875008efa
commit
b376228d45
@ -2,20 +2,30 @@
|
||||
// A set of abilities is a primary, a secondary, and a vec of all extra abilities
|
||||
({
|
||||
Tool(Sword): (
|
||||
primary: "common.abilities.sword.balanced_combo",
|
||||
secondary: "common.abilities.sword.balanced_thrust",
|
||||
primary: Contextualized({
|
||||
None: (None, "common.abilities.sword.balanced_combo"),
|
||||
Stance(Sword(Offensive)): (Some(Sword(OffensiveStance)), "common.abilities.sword.offensive_combo"),
|
||||
Stance(Sword(Crippling)): (Some(Sword(CripplingStance)), "common.abilities.sword.crippling_combo"),
|
||||
Stance(Sword(Cleaving)): (Some(Sword(CleavingStance)), "common.abilities.sword.cleaving_combo"),
|
||||
Stance(Sword(Defensive)): (Some(Sword(DefensiveStance)), "common.abilities.sword.defensive_combo"),
|
||||
Stance(Sword(Parrying)): (Some(Sword(ParryingStance)), "common.abilities.sword.parrying_combo"),
|
||||
Stance(Sword(Heavy)): (Some(Sword(HeavyStance)), "common.abilities.sword.heavy_combo"),
|
||||
Stance(Sword(Mobility)): (Some(Sword(MobilityStance)), "common.abilities.sword.mobility_combo"),
|
||||
Stance(Sword(Reaching)): (Some(Sword(ReachingStance)), "common.abilities.sword.reaching_combo"),
|
||||
}),
|
||||
secondary: Simple(None, "common.abilities.sword.balanced_thrust"),
|
||||
abilities: [
|
||||
Simple(Some(Sword(OffensiveCombo)), "common.abilities.sword.offensive_combo"),
|
||||
Simple(Some(Sword(CripplingCombo)), "common.abilities.sword.crippling_combo"),
|
||||
Simple(Some(Sword(CleavingCombo)), "common.abilities.sword.cleaving_combo"),
|
||||
Simple(Some(Sword(DefensiveCombo)), "common.abilities.sword.defensive_combo"),
|
||||
Simple(Some(Sword(ParryingCombo)), "common.abilities.sword.parrying_combo"),
|
||||
Simple(Some(Sword(HeavyCombo)), "common.abilities.sword.heavy_combo"),
|
||||
Simple(Some(Sword(MobilityCombo)), "common.abilities.sword.mobility_combo"),
|
||||
Simple(Some(Sword(ReachingCombo)), "common.abilities.sword.reaching_combo"),
|
||||
Simple(Some(Sword(OffensiveStance)), "common.abilities.sword.offensive_stance"),
|
||||
Simple(Some(Sword(CripplingStance)), "common.abilities.sword.crippling_stance"),
|
||||
Simple(Some(Sword(CleavingStance)), "common.abilities.sword.cleaving_stance"),
|
||||
Simple(Some(Sword(DefensiveStance)), "common.abilities.sword.defensive_stance"),
|
||||
Simple(Some(Sword(ParryingStance)), "common.abilities.sword.parrying_stance"),
|
||||
Simple(Some(Sword(HeavyStance)), "common.abilities.sword.heavy_stance"),
|
||||
Simple(Some(Sword(MobilityStance)), "common.abilities.sword.mobility_stance"),
|
||||
Simple(Some(Sword(ReachingStance)), "common.abilities.sword.reaching_stance"),
|
||||
// Damagey ones
|
||||
Contextualized({
|
||||
Stance(None): (Some(Sword(BalancedFinisher)), "common.abilities.sword.balanced_finisher"),
|
||||
None: (Some(Sword(BalancedFinisher)), "common.abilities.sword.balanced_finisher"),
|
||||
Stance(Sword(Offensive)): (Some(Sword(OffensiveFinisher)), "common.abilities.sword.offensive_finisher"),
|
||||
Stance(Sword(Crippling)): (Some(Sword(CripplingFinisher)), "common.abilities.sword.crippling_finisher"),
|
||||
Stance(Sword(Cleaving)): (Some(Sword(CleavingFinisher)), "common.abilities.sword.cleaving_finisher"),
|
||||
@ -47,79 +57,79 @@
|
||||
],
|
||||
),
|
||||
Tool(Axe): (
|
||||
primary: "common.abilities.axe.doublestrike",
|
||||
secondary: "common.abilities.axe.spin",
|
||||
primary: Simple(None, "common.abilities.axe.doublestrike"),
|
||||
secondary: Simple(None, "common.abilities.axe.spin"),
|
||||
abilities: [
|
||||
Simple(Some(Axe(UnlockLeap)), "common.abilities.axe.leap"),
|
||||
],
|
||||
),
|
||||
Tool(Hammer): (
|
||||
primary: "common.abilities.hammer.singlestrike",
|
||||
secondary: "common.abilities.hammer.charged",
|
||||
primary: Simple(None, "common.abilities.hammer.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.hammer.charged"),
|
||||
abilities: [
|
||||
Simple(Some(Hammer(UnlockLeap)), "common.abilities.hammer.leap"),
|
||||
],
|
||||
),
|
||||
Tool(Bow): (
|
||||
primary: "common.abilities.bow.charged",
|
||||
secondary: "common.abilities.bow.repeater",
|
||||
primary: Simple(None, "common.abilities.bow.charged"),
|
||||
secondary: Simple(None, "common.abilities.bow.repeater"),
|
||||
abilities: [
|
||||
Simple(Some(Bow(UnlockShotgun)), "common.abilities.bow.shotgun"),
|
||||
],
|
||||
),
|
||||
Tool(Staff): (
|
||||
primary: "common.abilities.staff.firebomb",
|
||||
secondary: "common.abilities.staff.flamethrower",
|
||||
primary: Simple(None, "common.abilities.staff.firebomb"),
|
||||
secondary: Simple(None, "common.abilities.staff.flamethrower"),
|
||||
abilities: [
|
||||
Simple(Some(Staff(UnlockShockwave)), "common.abilities.staff.fireshockwave"),
|
||||
],
|
||||
),
|
||||
Tool(Sceptre): (
|
||||
primary: "common.abilities.sceptre.lifestealbeam",
|
||||
secondary: "common.abilities.sceptre.healingaura",
|
||||
primary: Simple(None, "common.abilities.sceptre.lifestealbeam"),
|
||||
secondary: Simple(None, "common.abilities.sceptre.healingaura"),
|
||||
abilities: [
|
||||
Simple(Some(Sceptre(UnlockAura)), "common.abilities.sceptre.wardingaura"),
|
||||
],
|
||||
),
|
||||
Custom("Husk"): (
|
||||
primary: "common.abilities.custom.husk.singlestrike",
|
||||
secondary: "common.abilities.custom.husk.triplestrike",
|
||||
primary: Simple(None, "common.abilities.custom.husk.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.husk.triplestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Husk Brute"): (
|
||||
primary: "common.abilities.custom.husk_brute.singlestrike",
|
||||
secondary: "common.abilities.custom.husk_brute.chargedmelee",
|
||||
primary: Simple(None, "common.abilities.custom.husk_brute.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.husk_brute.chargedmelee"),
|
||||
abilities: [],
|
||||
),
|
||||
Tool(Spear): (
|
||||
primary: "common.abilities.spear.doublestrike",
|
||||
secondary: "common.abilities.spear.dash",
|
||||
primary: Simple(None, "common.abilities.spear.doublestrike"),
|
||||
secondary: Simple(None, "common.abilities.spear.dash"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Hammer Simple"): (
|
||||
primary: "common.abilities.hammersimple.doublestrike",
|
||||
secondary: "common.abilities.hammersimple.doublestrike",
|
||||
primary: Simple(None, "common.abilities.hammersimple.doublestrike"),
|
||||
secondary: Simple(None, "common.abilities.hammersimple.doublestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
// TODO: Later investigate if we want to make this back to a simple axe when more things need a simpler axe ability set
|
||||
Custom("Gnarling Axe"): (
|
||||
primary: "common.abilities.gnarling.axe.chop",
|
||||
secondary: "common.abilities.gnarling.axe.chop",
|
||||
primary: Simple(None, "common.abilities.gnarling.axe.chop"),
|
||||
secondary: Simple(None, "common.abilities.gnarling.axe.chop"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Gnarling Dagger"): (
|
||||
primary: "common.abilities.gnarling.dagger.stab",
|
||||
secondary: "common.abilities.gnarling.dagger.stab",
|
||||
primary: Simple(None, "common.abilities.gnarling.dagger.stab"),
|
||||
secondary: Simple(None, "common.abilities.gnarling.dagger.stab"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Gnarling Blowgun"): (
|
||||
primary: "common.abilities.gnarling.blowgun.dart",
|
||||
secondary: "common.abilities.gnarling.blowgun.dart",
|
||||
primary: Simple(None, "common.abilities.gnarling.blowgun.dart"),
|
||||
secondary: Simple(None, "common.abilities.gnarling.blowgun.dart"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Gnarling Chieftain"): (
|
||||
primary: "common.abilities.gnarling.chieftain.flamestrike",
|
||||
secondary: "common.abilities.gnarling.chieftain.firebarrage",
|
||||
primary: Simple(None, "common.abilities.gnarling.chieftain.flamestrike"),
|
||||
secondary: Simple(None, "common.abilities.gnarling.chieftain.firebarrage"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.gnarling.chieftain.fireshockwave"),
|
||||
Simple(None, "common.abilities.gnarling.chieftain.redtotem"),
|
||||
@ -128,87 +138,87 @@
|
||||
],
|
||||
),
|
||||
Custom("Gnarling Totem Red"): (
|
||||
primary: "common.abilities.gnarling.totem.red",
|
||||
secondary: "common.abilities.gnarling.totem.red",
|
||||
primary: Simple(None, "common.abilities.gnarling.totem.red"),
|
||||
secondary: Simple(None, "common.abilities.gnarling.totem.red"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Gnarling Totem Green"): (
|
||||
primary: "common.abilities.gnarling.totem.green",
|
||||
secondary: "common.abilities.gnarling.totem.green",
|
||||
primary: Simple(None, "common.abilities.gnarling.totem.green"),
|
||||
secondary: Simple(None, "common.abilities.gnarling.totem.green"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Gnarling Totem White"): (
|
||||
primary: "common.abilities.gnarling.totem.white",
|
||||
secondary: "common.abilities.gnarling.totem.white",
|
||||
primary: Simple(None, "common.abilities.gnarling.totem.white"),
|
||||
secondary: Simple(None, "common.abilities.gnarling.totem.white"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Deadwood"): (
|
||||
primary: "common.abilities.custom.deadwood.lifestealbeam",
|
||||
secondary: "common.abilities.custom.deadwood.dash",
|
||||
primary: Simple(None, "common.abilities.custom.deadwood.lifestealbeam"),
|
||||
secondary: Simple(None, "common.abilities.custom.deadwood.dash"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Mandragora"): (
|
||||
primary: "common.abilities.custom.mandragora.basic",
|
||||
secondary: "common.abilities.custom.mandragora.scream",
|
||||
primary: Simple(None, "common.abilities.custom.mandragora.basic"),
|
||||
secondary: Simple(None, "common.abilities.custom.mandragora.scream"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Wood Golem"): (
|
||||
primary: "common.abilities.custom.woodgolem.strike",
|
||||
secondary: "common.abilities.custom.woodgolem.spin",
|
||||
primary: Simple(None, "common.abilities.custom.woodgolem.strike"),
|
||||
secondary: Simple(None, "common.abilities.custom.woodgolem.spin"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.woodgolem.shockwave")
|
||||
],
|
||||
),
|
||||
Custom("Simple Flying Melee"): (
|
||||
primary: "common.abilities.custom.simpleflyingmelee.singlestrike",
|
||||
secondary: "common.abilities.custom.simpleflyingmelee.singlestrike",
|
||||
primary: Simple(None, "common.abilities.custom.simpleflyingmelee.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.simpleflyingmelee.singlestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Sword Simple"): (
|
||||
primary: "common.abilities.swordsimple.doublestrike",
|
||||
secondary: "common.abilities.swordsimple.dash",
|
||||
primary: Simple(None, "common.abilities.swordsimple.doublestrike"),
|
||||
secondary: Simple(None, "common.abilities.swordsimple.dash"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Staff Simple"): (
|
||||
primary: "common.abilities.staffsimple.firebomb",
|
||||
secondary: "common.abilities.staffsimple.flamethrower",
|
||||
primary: Simple(None, "common.abilities.staffsimple.firebomb"),
|
||||
secondary: Simple(None, "common.abilities.staffsimple.flamethrower"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Bow Simple"): (
|
||||
primary: "common.abilities.bowsimple.basic",
|
||||
secondary: "common.abilities.bowsimple.basic",
|
||||
primary: Simple(None, "common.abilities.bowsimple.basic"),
|
||||
secondary: Simple(None, "common.abilities.bowsimple.basic"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Axe Simple"): (
|
||||
primary: "common.abilities.axesimple.doublestrike",
|
||||
secondary: "common.abilities.axesimple.doublestrike",
|
||||
primary: Simple(None, "common.abilities.axesimple.doublestrike"),
|
||||
secondary: Simple(None, "common.abilities.axesimple.doublestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Dagger Simple"): (
|
||||
primary: "common.abilities.daggersimple.singlestrike",
|
||||
secondary: "common.abilities.daggersimple.singlestrike",
|
||||
primary: Simple(None, "common.abilities.daggersimple.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.daggersimple.singlestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Tool(Dagger): (
|
||||
primary: "common.abilities.dagger.tempbasic",
|
||||
secondary: "common.abilities.dagger.tempbasic",
|
||||
primary: Simple(None, "common.abilities.dagger.tempbasic"),
|
||||
secondary: Simple(None, "common.abilities.dagger.tempbasic"),
|
||||
abilities: [],
|
||||
),
|
||||
Tool(Shield): (
|
||||
primary: "common.abilities.shield.tempbasic",
|
||||
secondary: "common.abilities.shield.block",
|
||||
primary: Simple(None, "common.abilities.shield.tempbasic"),
|
||||
secondary: Simple(None, "common.abilities.shield.block"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Stone Golem"): (
|
||||
primary: "common.abilities.custom.stonegolemfist.singlestrike",
|
||||
secondary: "common.abilities.custom.stonegolemfist.shockwave",
|
||||
primary: Simple(None, "common.abilities.custom.stonegolemfist.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.stonegolemfist.shockwave"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.stonegolemfist.spin"),
|
||||
],
|
||||
),
|
||||
Custom("Beast Claws"): (
|
||||
primary: "common.abilities.custom.beastclaws.basic",
|
||||
secondary: "common.abilities.custom.beastclaws.basic",
|
||||
primary: Simple(None, "common.abilities.custom.beastclaws.basic"),
|
||||
secondary: Simple(None, "common.abilities.custom.beastclaws.basic"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Tursus Claws"): (
|
||||
@ -217,50 +227,50 @@
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Wendigo Magic"): (
|
||||
primary: "common.abilities.custom.wendigomagic.frostbomb",
|
||||
secondary: "common.abilities.custom.wendigomagic.singlestrike",
|
||||
primary: Simple(None, "common.abilities.custom.wendigomagic.frostbomb"),
|
||||
secondary: Simple(None, "common.abilities.custom.wendigomagic.singlestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Tidal Warrior"): (
|
||||
primary: "common.abilities.custom.tidalwarrior.pincer",
|
||||
secondary: "common.abilities.custom.tidalwarrior.scuttle",
|
||||
primary: Simple(None, "common.abilities.custom.tidalwarrior.pincer"),
|
||||
secondary: Simple(None, "common.abilities.custom.tidalwarrior.scuttle"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.tidalwarrior.bubbles"),
|
||||
Simple(None, "common.abilities.custom.tidalwarrior.totem"),
|
||||
],
|
||||
),
|
||||
Custom("Tidal Totem"): (
|
||||
primary: "common.abilities.custom.tidalwarrior.totem_wave",
|
||||
secondary: "common.abilities.custom.tidalwarrior.totem_wave",
|
||||
primary: Simple(None, "common.abilities.custom.tidalwarrior.totem_wave"),
|
||||
secondary: Simple(None, "common.abilities.custom.tidalwarrior.totem_wave"),
|
||||
abilities: [],
|
||||
),
|
||||
// Note: Consider making a ranking system once we get more entities
|
||||
// TODO: Make all purple item droppers have purple CR and a unique skillset
|
||||
Custom("Quad Med Quick"): (
|
||||
primary: "common.abilities.custom.quadmedquick.triplestrike",
|
||||
secondary: "common.abilities.custom.quadmedquick.dash",
|
||||
primary: Simple(None, "common.abilities.custom.quadmedquick.triplestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.quadmedquick.dash"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Quad Med Jump"): (
|
||||
primary: "common.abilities.custom.quadmedjump.leap",
|
||||
secondary: "common.abilities.custom.quadmedjump.doublestrike",
|
||||
primary: Simple(None, "common.abilities.custom.quadmedjump.leap"),
|
||||
secondary: Simple(None, "common.abilities.custom.quadmedjump.doublestrike"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.quadmedjump.quickleap"),
|
||||
],
|
||||
),
|
||||
Custom("Quad Med Charge"): (
|
||||
primary: "common.abilities.custom.quadmedcharge.doublestrike",
|
||||
secondary: "common.abilities.custom.quadmedcharge.dash",
|
||||
primary: Simple(None, "common.abilities.custom.quadmedcharge.doublestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.quadmedcharge.dash"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Quad Med Hoof"): (
|
||||
primary: "common.abilities.custom.quadmedhoof.basic",
|
||||
secondary: "common.abilities.custom.quadmedhoof.basic",
|
||||
primary: Simple(None, "common.abilities.custom.quadmedhoof.basic"),
|
||||
secondary: Simple(None, "common.abilities.custom.quadmedhoof.basic"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Quad Med Basic"): (
|
||||
primary: "common.abilities.custom.quadmedbasic.singlestrike",
|
||||
secondary: "common.abilities.custom.quadmedbasic.triplestrike",
|
||||
primary: Simple(None, "common.abilities.custom.quadmedbasic.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.quadmedbasic.triplestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Roshwalr"): (
|
||||
@ -271,129 +281,129 @@
|
||||
],
|
||||
),
|
||||
Custom("Basilisk"): (
|
||||
primary: "common.abilities.custom.basilisk.petrify",
|
||||
secondary: "common.abilities.custom.basilisk.triplestrike",
|
||||
primary: Simple(None, "common.abilities.custom.basilisk.petrify"),
|
||||
secondary: Simple(None, "common.abilities.custom.basilisk.triplestrike"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.basilisk.dash"),
|
||||
],
|
||||
),
|
||||
Custom("Asp"): (
|
||||
primary: "common.abilities.custom.asp.singlestrike",
|
||||
secondary: "common.abilities.custom.asp.firebomb",
|
||||
primary: Simple(None, "common.abilities.custom.asp.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.asp.firebomb"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Maneater"): (
|
||||
primary: "common.abilities.custom.maneater.singlestrike",
|
||||
secondary: "common.abilities.custom.maneater.poisonball",
|
||||
primary: Simple(None, "common.abilities.custom.maneater.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.maneater.poisonball"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Quad Low Breathe"): (
|
||||
primary: "common.abilities.custom.quadlowbreathe.flamethrower",
|
||||
secondary: "common.abilities.custom.quadlowbreathe.triplestrike",
|
||||
primary: Simple(None, "common.abilities.custom.quadlowbreathe.flamethrower"),
|
||||
secondary: Simple(None, "common.abilities.custom.quadlowbreathe.triplestrike"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.quadlowbreathe.dash"),
|
||||
],
|
||||
),
|
||||
Custom("Quad Low Tail"): (
|
||||
primary: "common.abilities.custom.quadlowtail.charged",
|
||||
secondary: "common.abilities.custom.quadlowtail.triplestrike",
|
||||
primary: Simple(None, "common.abilities.custom.quadlowtail.charged"),
|
||||
secondary: Simple(None, "common.abilities.custom.quadlowtail.triplestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Quad Low Quick"): (
|
||||
primary: "common.abilities.custom.quadlowquick.dash",
|
||||
secondary: "common.abilities.custom.quadlowquick.quadstrike",
|
||||
primary: Simple(None, "common.abilities.custom.quadlowquick.dash"),
|
||||
secondary: Simple(None, "common.abilities.custom.quadlowquick.quadstrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Quad Low Basic"): (
|
||||
primary: "common.abilities.custom.quadlowbasic.triplestrike",
|
||||
secondary: "common.abilities.custom.quadlowbasic.singlestrike",
|
||||
primary: Simple(None, "common.abilities.custom.quadlowbasic.triplestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.quadlowbasic.singlestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Quad Low Beam"): (
|
||||
primary: "common.abilities.custom.quadlowbeam.lifestealbeam",
|
||||
secondary: "common.abilities.custom.quadlowbreathe.triplestrike",
|
||||
primary: Simple(None, "common.abilities.custom.quadlowbeam.lifestealbeam"),
|
||||
secondary: Simple(None, "common.abilities.custom.quadlowbreathe.triplestrike"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.quadlowbreathe.dash"),
|
||||
],
|
||||
),
|
||||
Custom("Quad Small Basic"): (
|
||||
primary: "common.abilities.custom.quadsmallbasic.singlestrike",
|
||||
secondary: "common.abilities.custom.quadsmallbasic.singlestrike",
|
||||
primary: Simple(None, "common.abilities.custom.quadsmallbasic.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.quadsmallbasic.singlestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Theropod Basic"): (
|
||||
primary: "common.abilities.custom.theropodbasic.triplestrike",
|
||||
secondary: "common.abilities.custom.theropodbasic.triplestrike",
|
||||
primary: Simple(None, "common.abilities.custom.theropodbasic.triplestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.theropodbasic.triplestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Theropod Small"): (
|
||||
primary: "common.abilities.custom.theropodsmall.triplestrike",
|
||||
secondary: "common.abilities.custom.theropodsmall.triplestrike",
|
||||
primary: Simple(None, "common.abilities.custom.theropodsmall.triplestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.theropodsmall.triplestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Theropod Bird"): (
|
||||
primary: "common.abilities.custom.theropodbird.triplestrike",
|
||||
secondary: "common.abilities.custom.theropodbird.triplestrike",
|
||||
primary: Simple(None, "common.abilities.custom.theropodbird.triplestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.theropodbird.triplestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Theropod Charge"): (
|
||||
primary: "common.abilities.custom.theropodbasic.triplestrike",
|
||||
secondary: "common.abilities.custom.theropodbasic.dash",
|
||||
primary: Simple(None, "common.abilities.custom.theropodbasic.triplestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.theropodbasic.dash"),
|
||||
abilities: [],
|
||||
),
|
||||
// Arthropods
|
||||
Custom("Antlion"): (
|
||||
primary: "common.abilities.custom.arthropods.antlion.singlestrike",
|
||||
secondary: "common.abilities.custom.arthropods.antlion.charge",
|
||||
primary: Simple(None, "common.abilities.custom.arthropods.antlion.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.arthropods.antlion.charge"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Black Widow"): (
|
||||
primary: "common.abilities.custom.arthropods.blackwidow.singlestrike",
|
||||
secondary: "common.abilities.custom.arthropods.blackwidow.ensnaringwebs",
|
||||
primary: Simple(None, "common.abilities.custom.arthropods.blackwidow.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.arthropods.blackwidow.ensnaringwebs"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.arthropods.blackwidow.poisonball"),
|
||||
],
|
||||
),
|
||||
Custom("Horn Beetle"): (
|
||||
primary: "common.abilities.custom.arthropods.hornbeetle.singlestrike",
|
||||
secondary: "common.abilities.custom.arthropods.hornbeetle.harden",
|
||||
primary: Simple(None, "common.abilities.custom.arthropods.hornbeetle.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.arthropods.hornbeetle.harden"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.arthropods.hornbeetle.leap"),
|
||||
],
|
||||
),
|
||||
Custom("Tarantula"): (
|
||||
primary: "common.abilities.custom.arthropods.tarantula.singlestrike",
|
||||
secondary: "common.abilities.custom.arthropods.tarantula.ensnaringwebs",
|
||||
primary: Simple(None, "common.abilities.custom.arthropods.tarantula.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.arthropods.tarantula.ensnaringwebs"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.arthropods.tarantula.leap"),
|
||||
],
|
||||
),
|
||||
Custom("Weevil"): (
|
||||
primary: "common.abilities.custom.arthropods.weevil.singlestrike",
|
||||
secondary: "common.abilities.custom.arthropods.weevil.harden",
|
||||
primary: Simple(None, "common.abilities.custom.arthropods.weevil.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.arthropods.weevil.harden"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.arthropods.weevil.threadshot"),
|
||||
],
|
||||
),
|
||||
/// TODO: Organize the rest into further catagories and give purple tier droppers+ custom skillsets
|
||||
Custom("Turret"): (
|
||||
primary: "common.abilities.custom.turret.arrows",
|
||||
secondary: "common.abilities.custom.turret.arrows",
|
||||
primary: Simple(None, "common.abilities.custom.turret.arrows"),
|
||||
secondary: Simple(None, "common.abilities.custom.turret.arrows"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Organ"): (
|
||||
primary: "common.abilities.custom.organ.organaura",
|
||||
secondary: "common.abilities.custom.organ.organaura",
|
||||
primary: Simple(None, "common.abilities.custom.organ.organaura"),
|
||||
secondary: Simple(None, "common.abilities.custom.organ.organaura"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Haniwa Sentry"): (
|
||||
primary: "common.abilities.custom.turret.flamethrower",
|
||||
secondary: "common.abilities.custom.turret.flamethrower",
|
||||
primary: Simple(None, "common.abilities.custom.turret.flamethrower"),
|
||||
secondary: Simple(None, "common.abilities.custom.turret.flamethrower"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Mindflayer"): (
|
||||
primary: "common.abilities.custom.mindflayer.cursedflames",
|
||||
secondary: "common.abilities.custom.mindflayer.necroticvortex",
|
||||
primary: Simple(None, "common.abilities.custom.mindflayer.cursedflames"),
|
||||
secondary: Simple(None, "common.abilities.custom.mindflayer.necroticvortex"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.mindflayer.dimensionaldoor"),
|
||||
Simple(None, "common.abilities.custom.mindflayer.necroticsphere"),
|
||||
@ -401,32 +411,32 @@
|
||||
],
|
||||
),
|
||||
Custom("Minotaur"): (
|
||||
primary: "common.abilities.custom.minotaur.cleave",
|
||||
secondary: "common.abilities.custom.minotaur.cripplingstrike",
|
||||
primary: Simple(None, "common.abilities.custom.minotaur.cleave"),
|
||||
secondary: Simple(None, "common.abilities.custom.minotaur.cripplingstrike"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.minotaur.charge"),
|
||||
Simple(None, "common.abilities.custom.minotaur.frenzy"),
|
||||
],
|
||||
),
|
||||
Custom("Clay Golem"): (
|
||||
primary: "common.abilities.custom.claygolem.strike",
|
||||
secondary: "common.abilities.custom.claygolem.laser",
|
||||
primary: Simple(None, "common.abilities.custom.claygolem.strike"),
|
||||
secondary: Simple(None, "common.abilities.custom.claygolem.laser"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.claygolem.shockwave"),
|
||||
Simple(None, "common.abilities.custom.claygolem.rocket"),
|
||||
],
|
||||
),
|
||||
Custom("Yeti"): (
|
||||
primary: "common.abilities.custom.yeti.strike",
|
||||
secondary: "common.abilities.custom.yeti.icespikes",
|
||||
primary: Simple(None, "common.abilities.custom.yeti.strike"),
|
||||
secondary: Simple(None, "common.abilities.custom.yeti.icespikes"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.yeti.frostbreath"),
|
||||
Simple(None, "common.abilities.custom.yeti.snowball"),
|
||||
],
|
||||
),
|
||||
Custom("Harvester"): (
|
||||
primary: "common.abilities.custom.harvester.scythe",
|
||||
secondary: "common.abilities.custom.harvester.firebreath",
|
||||
primary: Simple(None, "common.abilities.custom.harvester.scythe"),
|
||||
secondary: Simple(None, "common.abilities.custom.harvester.firebreath"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.harvester.ensnaringvines"),
|
||||
Simple(None, "common.abilities.custom.harvester.explodingpumpkin"),
|
||||
@ -434,8 +444,8 @@
|
||||
),
|
||||
// TODO: Allow ability sets to expand other ability sets
|
||||
Custom("Dagon"): (
|
||||
primary: "common.abilities.custom.dagon.dagonbombs",
|
||||
secondary: "common.abilities.custom.dagon.seaurchins",
|
||||
primary: Simple(None, "common.abilities.custom.dagon.dagonbombs"),
|
||||
secondary: Simple(None, "common.abilities.custom.dagon.seaurchins"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.dagon.steamwave"),
|
||||
Simple(None, "common.abilities.custom.cardinal.steambeam"),
|
||||
@ -443,28 +453,28 @@
|
||||
],
|
||||
),
|
||||
Custom("Cardinal"): (
|
||||
primary: "common.abilities.sceptre.lifestealbeam",
|
||||
secondary: "common.abilities.sceptre.healingaura",
|
||||
primary: Simple(None, "common.abilities.sceptre.lifestealbeam"),
|
||||
secondary: Simple(None, "common.abilities.sceptre.healingaura"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.cardinal.steambeam"),
|
||||
Simple(None, "common.abilities.custom.cardinal.summonseacrocs"),
|
||||
],
|
||||
),
|
||||
Custom("Oni"): (
|
||||
primary: "common.abilities.custom.oni.dash",
|
||||
secondary: "common.abilities.custom.oni.doublestrike",
|
||||
primary: Simple(None, "common.abilities.custom.oni.dash"),
|
||||
secondary: Simple(None, "common.abilities.custom.oni.doublestrike"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Bird Large Breathe"): (
|
||||
primary: "common.abilities.custom.birdlargebreathe.firebomb",
|
||||
secondary: "common.abilities.custom.birdlargebreathe.triplestrike",
|
||||
primary: Simple(None, "common.abilities.custom.birdlargebreathe.firebomb"),
|
||||
secondary: Simple(None, "common.abilities.custom.birdlargebreathe.triplestrike"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.birdlargebreathe.flamethrower"),
|
||||
],
|
||||
),
|
||||
Custom("Bird Large Fire"): (
|
||||
primary: "common.abilities.custom.birdlargefire.firebomb",
|
||||
secondary: "common.abilities.custom.birdlargefire.triplestrike",
|
||||
primary: Simple(None, "common.abilities.custom.birdlargefire.firebomb"),
|
||||
secondary: Simple(None, "common.abilities.custom.birdlargefire.triplestrike"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.birdlargefire.fireshockwave"),
|
||||
],
|
||||
@ -510,8 +520,8 @@
|
||||
],
|
||||
),
|
||||
Custom("Bird Large Basic"): (
|
||||
primary: "common.abilities.custom.birdlargebasic.triplestrike",
|
||||
secondary: "common.abilities.custom.birdlargebasic.summontornadoes",
|
||||
primary: Simple(None, "common.abilities.custom.birdlargebasic.triplestrike"),
|
||||
secondary: Simple(None, "common.abilities.custom.birdlargebasic.summontornadoes"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.birdlargebasic.dash"),
|
||||
],
|
||||
@ -547,33 +557,33 @@
|
||||
],
|
||||
),
|
||||
Custom("Tornado"): (
|
||||
primary: "common.abilities.custom.tornado.spin",
|
||||
secondary: "common.abilities.empty.basic",
|
||||
primary: Simple(None, "common.abilities.custom.tornado.spin"),
|
||||
secondary: Simple(None, "common.abilities.empty.basic"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Golf Club"): (
|
||||
primary: "common.abilities.hammer.singlestrike",
|
||||
secondary: "common.abilities.tool.golf_club.charged",
|
||||
primary: Simple(None, "common.abilities.hammer.singlestrike"),
|
||||
secondary: Simple(None, "common.abilities.tool.golf_club.charged"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("DoubleBass"): (
|
||||
primary: "common.abilities.music.double_bass",
|
||||
secondary: "common.abilities.music.double_bass",
|
||||
primary: Simple(None, "common.abilities.music.double_bass"),
|
||||
secondary: Simple(None, "common.abilities.music.double_bass"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Flute"): (
|
||||
primary: "common.abilities.music.flute",
|
||||
secondary: "common.abilities.music.flute",
|
||||
primary: Simple(None, "common.abilities.music.flute"),
|
||||
secondary: Simple(None, "common.abilities.music.flute"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("GlassFlute"): (
|
||||
primary: "common.abilities.music.glass_flute",
|
||||
secondary: "common.abilities.music.glass_flute",
|
||||
primary: Simple(None, "common.abilities.music.glass_flute"),
|
||||
secondary: Simple(None, "common.abilities.music.glass_flute"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Lyre"): (
|
||||
primary: "common.abilities.music.lyre",
|
||||
secondary: "common.abilities.music.lyre",
|
||||
primary: Simple(None, "common.abilities.music.lyre"),
|
||||
secondary: Simple(None, "common.abilities.music.lyre"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("IcyTalharpa"): (
|
||||
@ -582,28 +592,28 @@
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Washboard"): (
|
||||
primary: "common.abilities.music.washboard",
|
||||
secondary: "common.abilities.music.washboard",
|
||||
primary: Simple(None, "common.abilities.music.washboard"),
|
||||
secondary: Simple(None, "common.abilities.music.washboard"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Kalimba"): (
|
||||
primary: "common.abilities.music.kalimba",
|
||||
secondary: "common.abilities.music.kalimba",
|
||||
primary: Simple(None, "common.abilities.music.kalimba"),
|
||||
secondary: Simple(None, "common.abilities.music.kalimba"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Melodica"): (
|
||||
primary: "common.abilities.music.melodica",
|
||||
secondary: "common.abilities.music.melodica",
|
||||
primary: Simple(None, "common.abilities.music.melodica"),
|
||||
secondary: Simple(None, "common.abilities.music.melodica"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Lute"): (
|
||||
primary: "common.abilities.music.lute",
|
||||
secondary: "common.abilities.music.lute",
|
||||
primary: Simple(None, "common.abilities.music.lute"),
|
||||
secondary: Simple(None, "common.abilities.music.lute"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Guitar"): (
|
||||
primary: "common.abilities.music.guitar",
|
||||
secondary: "common.abilities.music.guitar",
|
||||
primary: Simple(None, "common.abilities.music.guitar"),
|
||||
secondary: Simple(None, "common.abilities.music.guitar"),
|
||||
abilities: [],
|
||||
),
|
||||
Custom("DarkGuitar"): (
|
||||
@ -612,30 +622,30 @@
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Sitar"): (
|
||||
primary: "common.abilities.music.sitar",
|
||||
secondary: "common.abilities.music.sitar",
|
||||
primary: Simple(None, "common.abilities.music.sitar"),
|
||||
secondary: Simple(None, "common.abilities.music.sitar"),
|
||||
abilities: [],
|
||||
),
|
||||
Tool(Debug): (
|
||||
primary: "common.abilities.debug.forwardboost",
|
||||
secondary: "common.abilities.debug.upboost",
|
||||
primary: Simple(None, "common.abilities.debug.forwardboost"),
|
||||
secondary: Simple(None, "common.abilities.debug.upboost"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.debug.possess"),
|
||||
],
|
||||
),
|
||||
Tool(Farming): (
|
||||
primary: "common.abilities.farming.basic",
|
||||
secondary: "common.abilities.farming.basic",
|
||||
primary: Simple(None, "common.abilities.farming.basic"),
|
||||
secondary: Simple(None, "common.abilities.farming.basic"),
|
||||
abilities: [],
|
||||
),
|
||||
Tool(Pick): (
|
||||
primary: "common.abilities.pick.swing",
|
||||
secondary: "common.abilities.pick.swing",
|
||||
primary: Simple(None, "common.abilities.pick.swing"),
|
||||
secondary: Simple(None, "common.abilities.pick.swing"),
|
||||
abilities: [],
|
||||
),
|
||||
Tool(Empty): (
|
||||
primary: "common.abilities.empty.basic",
|
||||
secondary: "common.abilities.empty.basic",
|
||||
primary: Simple(None, "common.abilities.empty.basic"),
|
||||
secondary: Simple(None, "common.abilities.empty.basic"),
|
||||
abilities: [],
|
||||
),
|
||||
})
|
||||
|
@ -35,6 +35,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: true,
|
||||
energy_cost_per_strike: 0,
|
||||
)
|
@ -47,7 +47,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: true,
|
||||
stance: Some(Sword(Cleaving)),
|
||||
energy_cost_per_strike: 5,
|
||||
)
|
@ -19,6 +19,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: false,
|
||||
energy_cost_per_strike: 20,
|
||||
)
|
4
assets/common/abilities/sword/cleaving_stance.ron
Normal file
4
assets/common/abilities/sword/cleaving_stance.ron
Normal file
@ -0,0 +1,4 @@
|
||||
BasicStance(
|
||||
buildup_duration: 0.25,
|
||||
stance: Sword(Cleaving),
|
||||
)
|
@ -47,7 +47,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: true,
|
||||
stance: Some(Sword(Crippling)),
|
||||
energy_cost_per_strike: 4,
|
||||
)
|
@ -24,6 +24,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: false,
|
||||
energy_cost_per_strike: 25,
|
||||
)
|
4
assets/common/abilities/sword/crippling_stance.ron
Normal file
4
assets/common/abilities/sword/crippling_stance.ron
Normal file
@ -0,0 +1,4 @@
|
||||
BasicStance(
|
||||
buildup_duration: 0.25,
|
||||
stance: Sword(Crippling),
|
||||
)
|
@ -24,6 +24,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: false,
|
||||
energy_cost_per_strike: 25,
|
||||
)
|
@ -35,8 +35,6 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: true,
|
||||
stance: Some(Sword(Defensive)),
|
||||
energy_cost_per_strike: 2,
|
||||
meta: (
|
||||
capabilities: (
|
||||
|
@ -23,6 +23,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: false,
|
||||
energy_cost_per_strike: 10,
|
||||
)
|
4
assets/common/abilities/sword/defensive_stance.ron
Normal file
4
assets/common/abilities/sword/defensive_stance.ron
Normal file
@ -0,0 +1,4 @@
|
||||
BasicStance(
|
||||
buildup_duration: 0.25,
|
||||
stance: Sword(Defensive),
|
||||
)
|
@ -35,8 +35,6 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: true,
|
||||
stance: Some(Sword(Heavy)),
|
||||
energy_cost_per_strike: 4,
|
||||
meta: (
|
||||
capabilities: (
|
||||
|
@ -18,6 +18,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: false,
|
||||
energy_cost_per_strike: 15,
|
||||
)
|
4
assets/common/abilities/sword/heavy_stance.ron
Normal file
4
assets/common/abilities/sword/heavy_stance.ron
Normal file
@ -0,0 +1,4 @@
|
||||
BasicStance(
|
||||
buildup_duration: 0.25,
|
||||
stance: Sword(Heavy),
|
||||
)
|
@ -69,8 +69,6 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: true,
|
||||
stance: Some(Sword(Mobility)),
|
||||
energy_cost_per_strike: 2,
|
||||
meta: (
|
||||
capabilities: (
|
||||
|
@ -23,6 +23,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: false,
|
||||
energy_cost_per_strike: 10,
|
||||
)
|
4
assets/common/abilities/sword/mobility_stance.ron
Normal file
4
assets/common/abilities/sword/mobility_stance.ron
Normal file
@ -0,0 +1,4 @@
|
||||
BasicStance(
|
||||
buildup_duration: 0.25,
|
||||
stance: Sword(Mobility),
|
||||
)
|
@ -23,6 +23,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: false,
|
||||
energy_cost_per_strike: 10,
|
||||
)
|
@ -57,7 +57,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: true,
|
||||
stance: Some(Sword(Offensive)),
|
||||
energy_cost_per_strike: 3,
|
||||
)
|
4
assets/common/abilities/sword/offensive_stance.ron
Normal file
4
assets/common/abilities/sword/offensive_stance.ron
Normal file
@ -0,0 +1,4 @@
|
||||
BasicStance(
|
||||
buildup_duration: 0.25,
|
||||
stance: Sword(Offensive),
|
||||
)
|
@ -35,8 +35,6 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: true,
|
||||
stance: Some(Sword(Parrying)),
|
||||
energy_cost_per_strike: 5,
|
||||
meta: (
|
||||
capabilities: (
|
||||
|
@ -24,6 +24,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: false,
|
||||
energy_cost_per_strike: 15,
|
||||
)
|
4
assets/common/abilities/sword/parrying_stance.ron
Normal file
4
assets/common/abilities/sword/parrying_stance.ron
Normal file
@ -0,0 +1,4 @@
|
||||
BasicStance(
|
||||
buildup_duration: 0.25,
|
||||
stance: Sword(Parrying),
|
||||
)
|
@ -35,7 +35,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: true,
|
||||
stance: Some(Sword(Reaching)),
|
||||
energy_cost_per_strike: 4,
|
||||
)
|
@ -24,6 +24,5 @@ ComboMelee2(
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
is_stance: false,
|
||||
energy_cost_per_strike: 15,
|
||||
)
|
4
assets/common/abilities/sword/reaching_stance.ron
Normal file
4
assets/common/abilities/sword/reaching_stance.ron
Normal file
@ -0,0 +1,4 @@
|
||||
BasicStance(
|
||||
buildup_duration: 0.25,
|
||||
stance: Sword(Reaching),
|
||||
)
|
@ -1,30 +1,30 @@
|
||||
({
|
||||
Sword(OffensiveFinisher): {Sword(OffensiveCombo): 1},
|
||||
Sword(OffensiveAdvance): {Sword(OffensiveCombo): 1},
|
||||
Sword(CripplingCombo): {Sword(OffensiveCombo): 1},
|
||||
Sword(CripplingFinisher): {Sword(CripplingCombo): 1},
|
||||
Sword(CripplingStrike): {Sword(CripplingCombo): 1},
|
||||
Sword(CripplingGouge): {Sword(CripplingCombo): 1},
|
||||
Sword(CleavingCombo): {Sword(OffensiveCombo): 1},
|
||||
Sword(CleavingFinisher): {Sword(CleavingCombo): 1},
|
||||
Sword(CleavingSpin): {Sword(CleavingCombo): 1},
|
||||
Sword(CleavingDive): {Sword(CleavingCombo): 1},
|
||||
Sword(DefensiveBulwark): {Sword(DefensiveCombo): 1},
|
||||
Sword(DefensiveRetreat): {Sword(DefensiveCombo): 1},
|
||||
Sword(ParryingCombo): {Sword(DefensiveCombo): 1},
|
||||
Sword(ParryingParry): {Sword(ParryingCombo): 1},
|
||||
Sword(ParryingRiposte): {Sword(ParryingCombo): 1},
|
||||
Sword(ParryingCounter): {Sword(ParryingCombo): 1},
|
||||
Sword(HeavyCombo): {Sword(DefensiveCombo): 1},
|
||||
Sword(HeavyFinisher): {Sword(HeavyCombo): 1},
|
||||
Sword(HeavyPommelStrike): {Sword(HeavyCombo): 1},
|
||||
Sword(HeavyFortitude): {Sword(HeavyCombo): 1},
|
||||
Sword(MobilityFeint): {Sword(MobilityCombo): 1},
|
||||
Sword(MobilityAgility): {Sword(MobilityCombo): 1},
|
||||
Sword(ReachingCombo): {Sword(MobilityCombo): 1},
|
||||
Sword(ReachingCharge): {Sword(ReachingCombo): 1},
|
||||
Sword(ReachingFlurry): {Sword(ReachingCombo): 1},
|
||||
Sword(ReachingSkewer): {Sword(ReachingCombo): 1},
|
||||
Sword(OffensiveFinisher): {Sword(OffensiveStance): 1},
|
||||
Sword(OffensiveAdvance): {Sword(OffensiveStance): 1},
|
||||
Sword(CripplingStance): {Sword(OffensiveStance): 1},
|
||||
Sword(CripplingFinisher): {Sword(CripplingStance): 1},
|
||||
Sword(CripplingStrike): {Sword(CripplingStance): 1},
|
||||
Sword(CripplingGouge): {Sword(CripplingStance): 1},
|
||||
Sword(CleavingStance): {Sword(OffensiveStance): 1},
|
||||
Sword(CleavingFinisher): {Sword(CleavingStance): 1},
|
||||
Sword(CleavingSpin): {Sword(CleavingStance): 1},
|
||||
Sword(CleavingDive): {Sword(CleavingStance): 1},
|
||||
Sword(DefensiveBulwark): {Sword(DefensiveStance): 1},
|
||||
Sword(DefensiveRetreat): {Sword(DefensiveStance): 1},
|
||||
Sword(ParryingStance): {Sword(DefensiveStance): 1},
|
||||
Sword(ParryingParry): {Sword(ParryingStance): 1},
|
||||
Sword(ParryingRiposte): {Sword(ParryingStance): 1},
|
||||
Sword(ParryingCounter): {Sword(ParryingStance): 1},
|
||||
Sword(HeavyStance): {Sword(DefensiveStance): 1},
|
||||
Sword(HeavyFinisher): {Sword(HeavyStance): 1},
|
||||
Sword(HeavyPommelStrike): {Sword(HeavyStance): 1},
|
||||
Sword(HeavyFortitude): {Sword(HeavyStance): 1},
|
||||
Sword(MobilityFeint): {Sword(MobilityStance): 1},
|
||||
Sword(MobilityAgility): {Sword(MobilityStance): 1},
|
||||
Sword(ReachingStance): {Sword(MobilityStance): 1},
|
||||
Sword(ReachingCharge): {Sword(ReachingStance): 1},
|
||||
Sword(ReachingFlurry): {Sword(ReachingStance): 1},
|
||||
Sword(ReachingSkewer): {Sword(ReachingStance): 1},
|
||||
Axe(LDamage): {Axe(UnlockLeap): 1},
|
||||
Axe(LKnockback): {Axe(UnlockLeap): 1},
|
||||
Axe(LCost): {Axe(UnlockLeap): 1},
|
||||
|
@ -17,32 +17,32 @@
|
||||
],
|
||||
Weapon(Sword): [
|
||||
Sword(BalancedFinisher),
|
||||
Sword(OffensiveCombo),
|
||||
Sword(OffensiveStance),
|
||||
Sword(OffensiveFinisher),
|
||||
Sword(OffensiveAdvance),
|
||||
Sword(CripplingCombo),
|
||||
Sword(CripplingStance),
|
||||
Sword(CripplingFinisher),
|
||||
Sword(CripplingStrike),
|
||||
Sword(CripplingGouge),
|
||||
Sword(CleavingCombo),
|
||||
Sword(CleavingStance),
|
||||
Sword(CleavingFinisher),
|
||||
Sword(CleavingSpin),
|
||||
Sword(CleavingDive),
|
||||
Sword(DefensiveCombo),
|
||||
Sword(DefensiveStance),
|
||||
Sword(DefensiveBulwark),
|
||||
Sword(DefensiveRetreat),
|
||||
Sword(ParryingCombo),
|
||||
Sword(ParryingStance),
|
||||
Sword(ParryingParry),
|
||||
Sword(ParryingRiposte),
|
||||
Sword(ParryingCounter),
|
||||
Sword(HeavyCombo),
|
||||
Sword(HeavyStance),
|
||||
Sword(HeavyFinisher),
|
||||
Sword(HeavyPommelStrike),
|
||||
Sword(HeavyFortitude),
|
||||
Sword(MobilityCombo),
|
||||
Sword(MobilityStance),
|
||||
Sword(MobilityFeint),
|
||||
Sword(MobilityAgility),
|
||||
Sword(ReachingCombo),
|
||||
Sword(ReachingStance),
|
||||
Sword(ReachingCharge),
|
||||
Sword(ReachingFlurry),
|
||||
Sword(ReachingSkewer),
|
||||
|
@ -1,13 +1,13 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
Skill((Sword(BalancedFinisher), 1)),
|
||||
Skill((Sword(OffensiveCombo), 1)),
|
||||
Skill((Sword(OffensiveStance), 1)),
|
||||
Skill((Sword(OffensiveFinisher), 1)),
|
||||
Skill((Sword(OffensiveAdvance), 1)),
|
||||
Skill((Sword(DefensiveCombo), 1)),
|
||||
Skill((Sword(DefensiveStance), 1)),
|
||||
Skill((Sword(DefensiveBulwark), 1)),
|
||||
Skill((Sword(DefensiveRetreat), 1)),
|
||||
Skill((Sword(MobilityCombo), 1)),
|
||||
Skill((Sword(MobilityStance), 1)),
|
||||
Skill((Sword(MobilityFeint), 1)),
|
||||
Skill((Sword(MobilityAgility), 1)),
|
||||
])
|
||||
|
@ -1,13 +1,13 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
Skill((Sword(BalancedFinisher), 1)),
|
||||
Skill((Sword(OffensiveCombo), 1)),
|
||||
Skill((Sword(OffensiveStance), 1)),
|
||||
Skill((Sword(OffensiveFinisher), 1)),
|
||||
Skill((Sword(OffensiveAdvance), 1)),
|
||||
Skill((Sword(DefensiveCombo), 1)),
|
||||
Skill((Sword(DefensiveStance), 1)),
|
||||
Skill((Sword(DefensiveBulwark), 1)),
|
||||
Skill((Sword(DefensiveRetreat), 1)),
|
||||
Skill((Sword(MobilityCombo), 1)),
|
||||
Skill((Sword(MobilityStance), 1)),
|
||||
Skill((Sword(MobilityFeint), 1)),
|
||||
Skill((Sword(MobilityAgility), 1)),
|
||||
])
|
||||
|
@ -1,32 +1,32 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
Skill((Sword(BalancedFinisher), 1)),
|
||||
Skill((Sword(OffensiveCombo), 1)),
|
||||
Skill((Sword(OffensiveStance), 1)),
|
||||
Skill((Sword(OffensiveFinisher), 1)),
|
||||
Skill((Sword(OffensiveAdvance), 1)),
|
||||
Skill((Sword(CripplingCombo), 1)),
|
||||
Skill((Sword(CripplingStance), 1)),
|
||||
Skill((Sword(CripplingFinisher), 1)),
|
||||
Skill((Sword(CripplingStrike), 1)),
|
||||
Skill((Sword(CripplingGouge), 1)),
|
||||
Skill((Sword(CleavingCombo), 1)),
|
||||
Skill((Sword(CleavingStance), 1)),
|
||||
Skill((Sword(CleavingFinisher), 1)),
|
||||
Skill((Sword(CleavingSpin), 1)),
|
||||
Skill((Sword(CleavingDive), 1)),
|
||||
Skill((Sword(DefensiveCombo), 1)),
|
||||
Skill((Sword(DefensiveStance), 1)),
|
||||
Skill((Sword(DefensiveBulwark), 1)),
|
||||
Skill((Sword(DefensiveRetreat), 1)),
|
||||
Skill((Sword(ParryingCombo), 1)),
|
||||
Skill((Sword(ParryingStance), 1)),
|
||||
Skill((Sword(ParryingParry), 1)),
|
||||
Skill((Sword(ParryingRiposte), 1)),
|
||||
Skill((Sword(ParryingCounter), 1)),
|
||||
Skill((Sword(HeavyCombo), 1)),
|
||||
Skill((Sword(HeavyStance), 1)),
|
||||
Skill((Sword(HeavyFinisher), 1)),
|
||||
Skill((Sword(HeavyPommelStrike), 1)),
|
||||
Skill((Sword(HeavyFortitude), 1)),
|
||||
Skill((Sword(MobilityCombo), 1)),
|
||||
Skill((Sword(MobilityStance), 1)),
|
||||
Skill((Sword(MobilityFeint), 1)),
|
||||
Skill((Sword(MobilityAgility), 1)),
|
||||
Skill((Sword(ReachingCombo), 1)),
|
||||
Skill((Sword(ReachingStance), 1)),
|
||||
Skill((Sword(ReachingCharge), 1)),
|
||||
Skill((Sword(ReachingFlurry), 1)),
|
||||
Skill((Sword(ReachingSkewer), 1)),
|
||||
|
@ -1,32 +1,32 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
Skill((Sword(BalancedFinisher), 1)),
|
||||
Skill((Sword(OffensiveCombo), 1)),
|
||||
Skill((Sword(OffensiveStance), 1)),
|
||||
Skill((Sword(OffensiveFinisher), 1)),
|
||||
Skill((Sword(OffensiveAdvance), 1)),
|
||||
Skill((Sword(CripplingCombo), 1)),
|
||||
Skill((Sword(CripplingStance), 1)),
|
||||
Skill((Sword(CripplingFinisher), 1)),
|
||||
Skill((Sword(CripplingStrike), 1)),
|
||||
Skill((Sword(CripplingGouge), 1)),
|
||||
Skill((Sword(CleavingCombo), 1)),
|
||||
Skill((Sword(CleavingStance), 1)),
|
||||
Skill((Sword(CleavingFinisher), 1)),
|
||||
Skill((Sword(CleavingSpin), 1)),
|
||||
Skill((Sword(CleavingDive), 1)),
|
||||
Skill((Sword(DefensiveCombo), 1)),
|
||||
Skill((Sword(DefensiveStance), 1)),
|
||||
Skill((Sword(DefensiveBulwark), 1)),
|
||||
Skill((Sword(DefensiveRetreat), 1)),
|
||||
Skill((Sword(ParryingCombo), 1)),
|
||||
Skill((Sword(ParryingStance), 1)),
|
||||
Skill((Sword(ParryingParry), 1)),
|
||||
Skill((Sword(ParryingRiposte), 1)),
|
||||
Skill((Sword(ParryingCounter), 1)),
|
||||
Skill((Sword(HeavyCombo), 1)),
|
||||
Skill((Sword(HeavyStance), 1)),
|
||||
Skill((Sword(HeavyFinisher), 1)),
|
||||
Skill((Sword(HeavyPommelStrike), 1)),
|
||||
Skill((Sword(HeavyFortitude), 1)),
|
||||
Skill((Sword(MobilityCombo), 1)),
|
||||
Skill((Sword(MobilityStance), 1)),
|
||||
Skill((Sword(MobilityFeint), 1)),
|
||||
Skill((Sword(MobilityAgility), 1)),
|
||||
Skill((Sword(ReachingCombo), 1)),
|
||||
Skill((Sword(ReachingStance), 1)),
|
||||
Skill((Sword(ReachingCharge), 1)),
|
||||
Skill((Sword(ReachingFlurry), 1)),
|
||||
Skill((Sword(ReachingSkewer), 1)),
|
||||
|
@ -15,32 +15,32 @@
|
||||
// Sword
|
||||
(UnlockGroup(Weapon(Sword)), 1),
|
||||
(Sword(BalancedFinisher), 1),
|
||||
(Sword(OffensiveCombo), 1),
|
||||
(Sword(OffensiveStance), 1),
|
||||
(Sword(OffensiveFinisher), 1),
|
||||
(Sword(OffensiveAdvance), 1),
|
||||
(Sword(CripplingCombo), 1),
|
||||
(Sword(CripplingStance), 1),
|
||||
(Sword(CripplingFinisher), 1),
|
||||
(Sword(CripplingStrike), 1),
|
||||
(Sword(CripplingGouge), 1),
|
||||
(Sword(CleavingCombo), 1),
|
||||
(Sword(CleavingStance), 1),
|
||||
(Sword(CleavingFinisher), 1),
|
||||
(Sword(CleavingSpin), 1),
|
||||
(Sword(CleavingDive), 1),
|
||||
(Sword(DefensiveCombo), 1),
|
||||
(Sword(DefensiveStance), 1),
|
||||
(Sword(DefensiveBulwark), 1),
|
||||
(Sword(DefensiveRetreat), 1),
|
||||
(Sword(ParryingCombo), 1),
|
||||
(Sword(ParryingStance), 1),
|
||||
(Sword(ParryingParry), 1),
|
||||
(Sword(ParryingRiposte), 1),
|
||||
(Sword(ParryingCounter), 1),
|
||||
(Sword(HeavyCombo), 1),
|
||||
(Sword(HeavyStance), 1),
|
||||
(Sword(HeavyFinisher), 1),
|
||||
(Sword(HeavyPommelStrike), 1),
|
||||
(Sword(HeavyFortitude), 1),
|
||||
(Sword(MobilityCombo), 1),
|
||||
(Sword(MobilityStance), 1),
|
||||
(Sword(MobilityFeint), 1),
|
||||
(Sword(MobilityAgility), 1),
|
||||
(Sword(ReachingCombo), 1),
|
||||
(Sword(ReachingStance), 1),
|
||||
(Sword(ReachingCharge), 1),
|
||||
(Sword(ReachingFlurry), 1),
|
||||
(Sword(ReachingSkewer), 1),
|
||||
|
@ -20,12 +20,16 @@ common-abilities-sword-balanced_finisher = Finisher
|
||||
.desc = A powerful strike you can use after fighting long enough.
|
||||
common-abilities-sword-offensive_combo = Offensive Stance
|
||||
.desc = This stance hits harder, but is more tiring to use.
|
||||
common-abilities-sword-offensive_stance = Offensive Stance
|
||||
.desc = This stance hits harder, but is more tiring to use.
|
||||
common-abilities-sword-offensive_finisher = Offensive Finisher
|
||||
.desc = A strike that becomes more powerful the longer you have fought.
|
||||
common-abilities-sword-offensive_advance = Offensive Advance
|
||||
.desc = Swiftly engage the enemy with a powerful strike.
|
||||
common-abilities-sword-crippling_combo = Crippling Stance
|
||||
.desc = This stance is for the dishonorable that enjoy maiming their foes.
|
||||
common-abilities-sword-crippling_stance = Crippling Stance
|
||||
.desc = This stance is for the dishonorable that enjoy maiming their foes.
|
||||
common-abilities-sword-crippling_finisher = Crippling Finisher
|
||||
.desc = This strike becomes more crippling to your target the longer you have fought.
|
||||
common-abilities-sword-crippling_strike = Crippling Strike
|
||||
@ -34,6 +38,8 @@ common-abilities-sword-crippling_gouge = Crippling Gouge
|
||||
.desc = Inflict a lasting wound on your foe.
|
||||
common-abilities-sword-cleaving_combo = Cleaving Stance
|
||||
.desc = This stance focuses on wide, arcing strikes that can hit multiple foes.
|
||||
common-abilities-sword-cleaving_stance = Cleaving Stance
|
||||
.desc = This stance focuses on wide, arcing strikes that can hit multiple foes.
|
||||
common-abilities-sword-cleaving_finisher = Cleaving Finisher
|
||||
.desc = A cleaving strike that has the potential to finish multiple foes.
|
||||
common-abilities-sword-cleaving_spin = Cleaving Spin
|
||||
@ -42,12 +48,16 @@ common-abilities-sword-cleaving_dive = Cleaving Dive
|
||||
.desc = Able to cleave through even the largest enemies if you are falling fast.
|
||||
common-abilities-sword-defensive_combo = Defensive Stance
|
||||
.desc = A more guarded form, where you keep your blade ready to fend off attacks.
|
||||
common-abilities-sword-defensive_stance = Defensive Stance
|
||||
.desc = A more guarded form, where you keep your blade ready to fend off attacks.
|
||||
common-abilities-sword-defensive_bulwark = Defensive Bulwark
|
||||
.desc = You ready yourself against incoming attacks, defending yourself against the brunt of them.
|
||||
common-abilities-sword-defensive_retreat = Defensive Retreat
|
||||
.desc = Strike your enemies as you tactically backstep.
|
||||
common-abilities-sword-parrying_combo = Parrying Stance
|
||||
.desc = In this stance, you ready yourself to stop each strike and parry an attack.
|
||||
common-abilities-sword-parrying_stance = Parrying Stance
|
||||
.desc = In this stance, you ready yourself to stop each strike and parry an attack.
|
||||
common-abilities-sword-parrying_parry = Parry
|
||||
.desc = You wait for the next attack and deflect it.
|
||||
common-abilities-sword-parrying_riposte = Riposte
|
||||
@ -56,6 +66,8 @@ common-abilities-sword-parrying_counter = Counter
|
||||
.desc = You strike with lightning speed in an attempt to finish your foe before their attack lands.
|
||||
common-abilities-sword-heavy_combo = Heavy Stance
|
||||
.desc = In this stance, you keep your strikes more controlled to retain your poise.
|
||||
common-abilities-sword-heavy_stance = Heavy Stance
|
||||
.desc = In this stance, you keep your strikes more controlled to retain your poise.
|
||||
common-abilities-sword-heavy_finisher = Heavy Finisher
|
||||
.desc = A powerful blow that is more staggering to your target the longer you have fought.
|
||||
common-abilities-sword-heavy_pommelstrike = Pommel Strike
|
||||
@ -64,12 +76,16 @@ common-abilities-sword-heavy_fortitude = Heavy Fortitude
|
||||
.desc = You steady yourself so that the next few strikes do not stagger you at all.
|
||||
common-abilities-sword-mobility_combo = Mobility Stance
|
||||
.desc = In this stance, you hold your sword closer, ready to roll with the slightest reason.
|
||||
common-abilities-sword-mobility_stance = Mobility Stance
|
||||
.desc = In this stance, you hold your sword closer, ready to roll with the slightest reason.
|
||||
common-abilities-sword-mobility_feint = Feint
|
||||
.desc = Deceive your foe by beginning to strike, before stepping to the side and attacking from there.
|
||||
common-abilities-sword-mobility_agility = Agility
|
||||
.desc = Draw on a reserve of energy to move and attack more swiftly.
|
||||
common-abilities-sword-reaching_combo = Reaching Stance
|
||||
.desc = This stance focuses on thrusts over slashes.
|
||||
common-abilities-sword-reaching_stance = Reaching Stance
|
||||
.desc = This stance focuses on thrusts over slashes.
|
||||
common-abilities-sword-reaching_charge = Charge
|
||||
.desc = Quickly close the gap to your foe by charging forward in a lunging attack.
|
||||
common-abilities-sword-reaching_flurry = Lunging Flurry
|
||||
|
@ -968,7 +968,7 @@ impl Knockback {
|
||||
let from_char = {
|
||||
let resistant = char_state
|
||||
.and_then(|cs| cs.ability_info())
|
||||
.and_then(|a| a.ability_meta)
|
||||
.map(|a| a.ability_meta)
|
||||
.map_or(false, |a| {
|
||||
a.capabilities.contains(Capability::KNOCKBACK_RESISTANT)
|
||||
});
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
character_state::AttackImmunities,
|
||||
inventory::{
|
||||
item::{
|
||||
tool::{AbilityContext, AbilityItem, AuxiliaryAbilityKind, Stats, ToolKind},
|
||||
tool::{AbilityContext, AbilityItem, AbilityKind, Stats, ToolKind},
|
||||
ItemKind,
|
||||
},
|
||||
slot::EquipSlot,
|
||||
@ -143,7 +143,7 @@ impl ActiveAbilities {
|
||||
inv: Option<&Inventory>,
|
||||
skill_set: &SkillSet,
|
||||
body: Option<&Body>,
|
||||
context: Option<AbilityContext>,
|
||||
context: AbilityContext,
|
||||
// bool is from_offhand
|
||||
) -> Option<(CharacterAbility, bool)> {
|
||||
let ability = self.get_ability(input, inv, Some(skill_set));
|
||||
@ -175,14 +175,17 @@ impl ActiveAbilities {
|
||||
|
||||
match ability {
|
||||
Ability::ToolPrimary => ability_set(EquipSlot::ActiveMainhand)
|
||||
.map(|abilities| abilities.primary.ability.clone())
|
||||
.and_then(|abilities| abilities.primary(context).map(unwrap_ability))
|
||||
.and_then(unlocked)
|
||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveMainhand), false)),
|
||||
Ability::ToolSecondary => ability_set(EquipSlot::ActiveOffhand)
|
||||
.map(|abilities| abilities.secondary.ability.clone())
|
||||
.and_then(|abilities| abilities.secondary(context).map(unwrap_ability))
|
||||
.and_then(unlocked)
|
||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveOffhand), true))
|
||||
.or_else(|| {
|
||||
ability_set(EquipSlot::ActiveMainhand)
|
||||
.map(|abilities| abilities.secondary.ability.clone())
|
||||
.and_then(|abilities| abilities.secondary(context).map(unwrap_ability))
|
||||
.and_then(unlocked)
|
||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveMainhand), false))
|
||||
}),
|
||||
Ability::SpeciesMovement => matches!(body, Some(Body::Humanoid(_)))
|
||||
@ -210,10 +213,10 @@ impl ActiveAbilities {
|
||||
.flat_map(|i| &i.item_config_expect().abilities.abilities)
|
||||
.enumerate()
|
||||
.filter_map(move |(i, a)| match a {
|
||||
AuxiliaryAbilityKind::Simple(skill, _) => skill
|
||||
AbilityKind::Simple(skill, _) => skill
|
||||
.map_or(true, |s| skill_set.map_or(false, |ss| ss.has_skill(s)))
|
||||
.then_some(i),
|
||||
AuxiliaryAbilityKind::Contextualized(abilities) => abilities
|
||||
AbilityKind::Contextualized(abilities) => abilities
|
||||
.values()
|
||||
.any(|(skill, _)| {
|
||||
skill.map_or(true, |s| skill_set.map_or(false, |ss| ss.has_skill(s)))
|
||||
@ -257,21 +260,14 @@ pub enum Ability {
|
||||
}
|
||||
|
||||
impl Ability {
|
||||
pub fn ability_id(
|
||||
self,
|
||||
inv: Option<&Inventory>,
|
||||
context: Option<AbilityContext>,
|
||||
) -> Option<&str> {
|
||||
pub fn ability_id(self, inv: Option<&Inventory>, context: AbilityContext) -> Option<&str> {
|
||||
let ability_set = |equip_slot| {
|
||||
inv.and_then(|inv| inv.equipped(equip_slot))
|
||||
.map(|i| &i.item_config_expect().abilities)
|
||||
};
|
||||
|
||||
let contextual_id = |auxiliary_kind: Option<&AuxiliaryAbilityKind<_>>, equip_slot| {
|
||||
matches!(
|
||||
auxiliary_kind,
|
||||
Some(AuxiliaryAbilityKind::Contextualized(_))
|
||||
)
|
||||
let contextual_id = |auxiliary_kind: Option<&AbilityKind<_>>, equip_slot| {
|
||||
matches!(auxiliary_kind, Some(AbilityKind::Contextualized(_)))
|
||||
.then_some(
|
||||
match inv.and_then(|inv| inv.equipped(equip_slot)).and_then(|i| {
|
||||
if let ItemKind::Tool(tool) = &*i.kind() {
|
||||
@ -291,12 +287,13 @@ impl Ability {
|
||||
|
||||
match self {
|
||||
Ability::ToolPrimary => ability_set(EquipSlot::ActiveMainhand)
|
||||
.map(|abilities| abilities.primary.id.as_str()),
|
||||
.and_then(|abilities| abilities.primary(context).map(|(_, a)| a.id.as_str())),
|
||||
Ability::ToolSecondary => ability_set(EquipSlot::ActiveOffhand)
|
||||
.map(|abilities| abilities.secondary.id.as_str())
|
||||
.and_then(|abilities| abilities.secondary(context).map(|(_, a)| a.id.as_str()))
|
||||
.or_else(|| {
|
||||
ability_set(EquipSlot::ActiveMainhand)
|
||||
.map(|abilities| abilities.secondary.id.as_str())
|
||||
ability_set(EquipSlot::ActiveMainhand).and_then(|abilities| {
|
||||
abilities.secondary(context).map(|(_, a)| a.id.as_str())
|
||||
})
|
||||
}),
|
||||
Ability::SpeciesMovement => None, // TODO: Make not None
|
||||
Ability::MainWeaponAux(index) => {
|
||||
@ -428,9 +425,7 @@ impl From<&CharacterState> for CharacterAbilityType {
|
||||
CharacterState::LeapMelee(data) => Self::LeapMelee(data.stage_section),
|
||||
CharacterState::LeapShockwave(data) => Self::LeapShockwave(data.stage_section),
|
||||
CharacterState::ComboMelee(data) => Self::ComboMelee(data.stage_section, data.stage),
|
||||
CharacterState::ComboMelee2(data) => {
|
||||
data.stage_section.map_or(Self::Other, Self::ComboMelee2)
|
||||
},
|
||||
CharacterState::ComboMelee2(data) => Self::ComboMelee2(data.stage_section),
|
||||
CharacterState::FinisherMelee(data) => Self::FinisherMelee(data.stage_section),
|
||||
CharacterState::DiveMelee(data) => Self::DiveMelee(data.stage_section),
|
||||
CharacterState::RiposteMelee(data) => Self::RiposteMelee(data.stage_section),
|
||||
@ -461,7 +456,8 @@ impl From<&CharacterState> for CharacterAbilityType {
|
||||
| CharacterState::UseItem(_)
|
||||
| CharacterState::SpriteInteract(_)
|
||||
| CharacterState::Skate(_)
|
||||
| CharacterState::Wallrun(_) => Self::Other,
|
||||
| CharacterState::Wallrun(_)
|
||||
| CharacterState::BasicStance(_) => Self::Other,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -565,8 +561,6 @@ pub enum CharacterAbility {
|
||||
},
|
||||
ComboMelee2 {
|
||||
strikes: Vec<combo_melee2::Strike<f32>>,
|
||||
is_stance: bool,
|
||||
stance: Option<Stance>,
|
||||
energy_cost_per_strike: f32,
|
||||
#[serde(default)]
|
||||
meta: AbilityMeta,
|
||||
@ -793,6 +787,12 @@ pub enum CharacterAbility {
|
||||
#[serde(default)]
|
||||
meta: AbilityMeta,
|
||||
},
|
||||
BasicStance {
|
||||
buildup_duration: f32,
|
||||
stance: Stance,
|
||||
#[serde(default)]
|
||||
meta: AbilityMeta,
|
||||
},
|
||||
}
|
||||
|
||||
impl Default for CharacterAbility {
|
||||
@ -847,9 +847,11 @@ impl CharacterAbility {
|
||||
| CharacterAbility::BasicBlock { energy_cost, .. }
|
||||
| CharacterAbility::SelfBuff { energy_cost, .. }
|
||||
| CharacterAbility::RiposteMelee { energy_cost, .. }
|
||||
| CharacterAbility::RapidMelee { energy_cost, .. } => {
|
||||
update.energy.try_change_by(-*energy_cost).is_ok()
|
||||
},
|
||||
| CharacterAbility::RapidMelee { energy_cost, .. }
|
||||
| CharacterAbility::ComboMelee2 {
|
||||
energy_cost_per_strike: energy_cost,
|
||||
..
|
||||
} => update.energy.try_change_by(-*energy_cost).is_ok(),
|
||||
// Consumes energy within state, so value only checked before entering state
|
||||
CharacterAbility::RepeaterRanged { energy_cost, .. } => {
|
||||
update.energy.current() >= *energy_cost
|
||||
@ -869,22 +871,6 @@ impl CharacterAbility {
|
||||
| !*scales_with_combo)
|
||||
&& update.energy.try_change_by(-*energy_cost).is_ok()
|
||||
},
|
||||
CharacterAbility::ComboMelee2 {
|
||||
is_stance,
|
||||
energy_cost_per_strike,
|
||||
..
|
||||
} => {
|
||||
// If it is a stance, just check that enough energy is present, otherwise
|
||||
// consume the required energy now
|
||||
if *is_stance {
|
||||
update.energy.current() > *energy_cost_per_strike
|
||||
} else {
|
||||
update
|
||||
.energy
|
||||
.try_change_by(-*energy_cost_per_strike)
|
||||
.is_ok()
|
||||
}
|
||||
},
|
||||
CharacterAbility::FinisherMelee {
|
||||
energy_cost,
|
||||
minimum_combo,
|
||||
@ -907,7 +893,8 @@ impl CharacterAbility {
|
||||
| CharacterAbility::Blink { .. }
|
||||
| CharacterAbility::Music { .. }
|
||||
| CharacterAbility::BasicSummon { .. }
|
||||
| CharacterAbility::SpriteSummon { .. } => true,
|
||||
| CharacterAbility::SpriteSummon { .. }
|
||||
| CharacterAbility::BasicStance { .. } => true,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1083,10 +1070,8 @@ impl CharacterAbility {
|
||||
},
|
||||
ComboMelee2 {
|
||||
ref mut strikes,
|
||||
is_stance: _,
|
||||
ref mut energy_cost_per_strike,
|
||||
meta: _,
|
||||
stance: _,
|
||||
} => {
|
||||
*energy_cost_per_strike /= stats.energy_efficiency;
|
||||
*strikes = strikes
|
||||
@ -1463,6 +1448,13 @@ impl CharacterAbility {
|
||||
*energy_cost /= stats.energy_efficiency;
|
||||
*melee_constructor = melee_constructor.adjusted_by_stats(stats);
|
||||
},
|
||||
BasicStance {
|
||||
ref mut buildup_duration,
|
||||
stance: _,
|
||||
meta: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
},
|
||||
}
|
||||
self
|
||||
}
|
||||
@ -1504,7 +1496,8 @@ impl CharacterAbility {
|
||||
| Blink { .. }
|
||||
| Music { .. }
|
||||
| BasicSummon { .. }
|
||||
| SpriteSummon { .. } => 0.0,
|
||||
| SpriteSummon { .. }
|
||||
| BasicStance { .. } => 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1545,7 +1538,8 @@ impl CharacterAbility {
|
||||
| Blink { .. }
|
||||
| Music { .. }
|
||||
| BasicSummon { .. }
|
||||
| SpriteSummon { .. } => 0,
|
||||
| SpriteSummon { .. }
|
||||
| BasicStance { .. } => 0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1578,7 +1572,8 @@ impl CharacterAbility {
|
||||
| Music { meta, .. }
|
||||
| DiveMelee { meta, .. }
|
||||
| RiposteMelee { meta, .. }
|
||||
| RapidMelee { meta, .. } => *meta,
|
||||
| RapidMelee { meta, .. }
|
||||
| BasicStance { meta, .. } => *meta,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2274,14 +2269,10 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
CharacterAbility::ComboMelee2 {
|
||||
strikes,
|
||||
energy_cost_per_strike,
|
||||
is_stance,
|
||||
stance,
|
||||
meta: _,
|
||||
} => CharacterState::ComboMelee2(combo_melee2::Data {
|
||||
static_data: combo_melee2::StaticData {
|
||||
strikes: strikes.iter().map(|s| s.to_duration()).collect(),
|
||||
is_stance: *is_stance,
|
||||
stance: *stance,
|
||||
energy_cost_per_strike: *energy_cost_per_strike,
|
||||
ability_info,
|
||||
},
|
||||
@ -2291,15 +2282,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
// If ability is a stance, if starting from wielding, get ready to enter stance,
|
||||
// otherwise enter stance immediately, otherwise if not a stance immediately begin
|
||||
// the strike
|
||||
stage_section: if *is_stance {
|
||||
if matches!(data.character, CharacterState::Wielding(_)) {
|
||||
Some(StageSection::Ready)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
Some(StageSection::Buildup)
|
||||
},
|
||||
stage_section: StageSection::Buildup,
|
||||
completed_strikes: 0,
|
||||
}),
|
||||
CharacterAbility::LeapMelee {
|
||||
@ -2806,6 +2789,18 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
stage_section: StageSection::Buildup,
|
||||
exhausted: false,
|
||||
}),
|
||||
CharacterAbility::BasicStance {
|
||||
buildup_duration,
|
||||
stance,
|
||||
meta: _,
|
||||
} => CharacterState::BasicStance(basic_stance::Data {
|
||||
static_data: basic_stance::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
stance: *stance,
|
||||
ability_info,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,6 +143,8 @@ pub enum CharacterState {
|
||||
/// A series of consecutive, identical attacks that only go through buildup
|
||||
/// and recover once for the entire state
|
||||
RapidMelee(rapid_melee::Data),
|
||||
/// Causes the character to enter a new stance, or leave the current stance
|
||||
BasicStance(basic_stance::Data),
|
||||
}
|
||||
|
||||
impl CharacterState {
|
||||
@ -182,6 +184,7 @@ impl CharacterState {
|
||||
| CharacterState::DiveMelee(_)
|
||||
| CharacterState::RiposteMelee(_)
|
||||
| CharacterState::RapidMelee(_)
|
||||
| CharacterState::BasicStance(_)
|
||||
)
|
||||
}
|
||||
|
||||
@ -263,6 +266,7 @@ impl CharacterState {
|
||||
| CharacterState::DiveMelee(_)
|
||||
| CharacterState::RiposteMelee(_)
|
||||
| CharacterState::RapidMelee(_)
|
||||
| CharacterState::BasicStance(_)
|
||||
)
|
||||
}
|
||||
|
||||
@ -290,7 +294,7 @@ impl CharacterState {
|
||||
pub fn is_parry(&self) -> bool {
|
||||
let from_capability = if let Some(capabilities) = self
|
||||
.ability_info()
|
||||
.and_then(|a| a.ability_meta)
|
||||
.map(|a| a.ability_meta)
|
||||
.map(|m| m.capabilities)
|
||||
{
|
||||
capabilities.contains(Capability::BUILDUP_PARRIES)
|
||||
@ -343,7 +347,7 @@ impl CharacterState {
|
||||
pub fn is_forced_movement(&self) -> bool {
|
||||
matches!(self,
|
||||
CharacterState::ComboMelee(s) if s.stage_section == StageSection::Action)
|
||||
|| matches!(self, CharacterState::ComboMelee2(s) if s.stage_section == Some(StageSection::Action))
|
||||
|| matches!(self, CharacterState::ComboMelee2(s) if s.stage_section == StageSection::Action)
|
||||
|| matches!(self, CharacterState::DashMelee(s) if s.stage_section == StageSection::Charge)
|
||||
|| matches!(self, CharacterState::LeapMelee(s) if s.stage_section == StageSection::Movement)
|
||||
|| matches!(self, CharacterState::SpinMelee(s) if s.stage_section == StageSection::Action)
|
||||
@ -394,6 +398,7 @@ impl CharacterState {
|
||||
| CharacterState::Music(_)
|
||||
| CharacterState::RiposteMelee(_)
|
||||
| CharacterState::RapidMelee(_)
|
||||
| CharacterState::BasicStance(_)
|
||||
)
|
||||
}
|
||||
|
||||
@ -462,6 +467,7 @@ impl CharacterState {
|
||||
CharacterState::DiveMelee(data) => data.behavior(j, output_events),
|
||||
CharacterState::RiposteMelee(data) => data.behavior(j, output_events),
|
||||
CharacterState::RapidMelee(data) => data.behavior(j, output_events),
|
||||
CharacterState::BasicStance(data) => data.behavior(j, output_events),
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,6 +522,7 @@ impl CharacterState {
|
||||
CharacterState::DiveMelee(data) => data.handle_event(j, output_events, action),
|
||||
CharacterState::RiposteMelee(data) => data.handle_event(j, output_events, action),
|
||||
CharacterState::RapidMelee(data) => data.handle_event(j, output_events, action),
|
||||
CharacterState::BasicStance(data) => data.handle_event(j, output_events, action),
|
||||
}
|
||||
}
|
||||
|
||||
@ -536,7 +543,7 @@ impl CharacterState {
|
||||
CharacterState::Skate(_) => None,
|
||||
CharacterState::Glide(_) => None,
|
||||
CharacterState::GlideWield(_) => None,
|
||||
CharacterState::Stunned(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::Stunned(_) => None,
|
||||
CharacterState::Sit => None,
|
||||
CharacterState::Dance => None,
|
||||
CharacterState::BasicBlock(data) => Some(data.static_data.ability_info),
|
||||
@ -562,13 +569,14 @@ impl CharacterState {
|
||||
CharacterState::BasicSummon(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::SelfBuff(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::SpriteSummon(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::UseItem(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::SpriteInteract(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::UseItem(_) => None,
|
||||
CharacterState::SpriteInteract(_) => None,
|
||||
CharacterState::FinisherMelee(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::Music(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::DiveMelee(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::RiposteMelee(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::RapidMelee(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::BasicStance(data) => Some(data.static_data.ability_info),
|
||||
}
|
||||
}
|
||||
|
||||
@ -586,10 +594,10 @@ impl CharacterState {
|
||||
CharacterState::Dance => None,
|
||||
CharacterState::BasicBlock(data) => Some(data.stage_section),
|
||||
CharacterState::Roll(data) => Some(data.stage_section),
|
||||
CharacterState::Equipping(_) => Some(StageSection::Buildup),
|
||||
CharacterState::Wielding(_) => None,
|
||||
CharacterState::Equipping(_) => None,
|
||||
CharacterState::ComboMelee(data) => Some(data.stage_section),
|
||||
CharacterState::ComboMelee2(data) => data.stage_section,
|
||||
CharacterState::ComboMelee2(data) => Some(data.stage_section),
|
||||
CharacterState::BasicMelee(data) => Some(data.stage_section),
|
||||
CharacterState::BasicRanged(data) => Some(data.stage_section),
|
||||
CharacterState::Boost(_) => None,
|
||||
@ -614,6 +622,7 @@ impl CharacterState {
|
||||
CharacterState::DiveMelee(data) => Some(data.stage_section),
|
||||
CharacterState::RiposteMelee(data) => Some(data.stage_section),
|
||||
CharacterState::RapidMelee(data) => Some(data.stage_section),
|
||||
CharacterState::BasicStance(_) => Some(StageSection::Buildup),
|
||||
}
|
||||
}
|
||||
|
||||
@ -645,7 +654,10 @@ impl CharacterState {
|
||||
..Default::default()
|
||||
}),
|
||||
CharacterState::Wielding(_) => None,
|
||||
CharacterState::Equipping(_) => None,
|
||||
CharacterState::Equipping(data) => Some(DurationsInfo {
|
||||
buildup: Some(data.static_data.buildup_duration),
|
||||
..Default::default()
|
||||
}),
|
||||
CharacterState::ComboMelee(data) => {
|
||||
let stage_index = data.stage_index();
|
||||
let stage = data.static_data.stage_data[stage_index];
|
||||
@ -662,10 +674,6 @@ impl CharacterState {
|
||||
buildup: Some(strike.buildup_duration),
|
||||
action: Some(strike.swing_duration),
|
||||
recover: Some(strike.recover_duration),
|
||||
ready: data
|
||||
.static_data
|
||||
.is_stance
|
||||
.then_some(combo_melee2::STANCE_ENTER_TIME),
|
||||
..Default::default()
|
||||
})
|
||||
},
|
||||
@ -809,6 +817,10 @@ impl CharacterState {
|
||||
recover: Some(data.static_data.recover_duration),
|
||||
..Default::default()
|
||||
}),
|
||||
CharacterState::BasicStance(data) => Some(DurationsInfo {
|
||||
buildup: Some(data.static_data.buildup_duration),
|
||||
..Default::default()
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@ -854,15 +866,7 @@ impl CharacterState {
|
||||
CharacterState::DiveMelee(data) => Some(data.timer),
|
||||
CharacterState::RiposteMelee(data) => Some(data.timer),
|
||||
CharacterState::RapidMelee(data) => Some(data.timer),
|
||||
}
|
||||
}
|
||||
|
||||
// Determines if a character state should be returned to when using another
|
||||
// ability from that character state
|
||||
pub fn should_be_returned_to(&self) -> bool {
|
||||
match self {
|
||||
CharacterState::ComboMelee2(data) => data.static_data.is_stance,
|
||||
_ => false,
|
||||
CharacterState::BasicStance(data) => Some(data.timer),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -874,7 +878,6 @@ pub struct DurationsInfo {
|
||||
pub recover: Option<Duration>,
|
||||
pub movement: Option<Duration>,
|
||||
pub charge: Option<Duration>,
|
||||
pub ready: Option<Duration>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq)]
|
||||
|
@ -281,22 +281,22 @@ impl Tool {
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct AbilitySet<T> {
|
||||
pub primary: T,
|
||||
pub secondary: T,
|
||||
pub abilities: Vec<AuxiliaryAbilityKind<T>>,
|
||||
pub primary: AbilityKind<T>,
|
||||
pub secondary: AbilityKind<T>,
|
||||
pub abilities: Vec<AbilityKind<T>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum AuxiliaryAbilityKind<T> {
|
||||
pub enum AbilityKind<T> {
|
||||
Simple(Option<Skill>, T),
|
||||
Contextualized(HashMap<AbilityContext, (Option<Skill>, T)>),
|
||||
}
|
||||
|
||||
impl<T> AuxiliaryAbilityKind<T> {
|
||||
pub fn map<U, F: FnMut(T) -> U>(self, mut f: F) -> AuxiliaryAbilityKind<U> {
|
||||
impl<T> AbilityKind<T> {
|
||||
pub fn map<U, F: FnMut(T) -> U>(self, mut f: F) -> AbilityKind<U> {
|
||||
match self {
|
||||
Self::Simple(s, x) => AuxiliaryAbilityKind::<U>::Simple(s, f(x)),
|
||||
Self::Contextualized(abilities) => AuxiliaryAbilityKind::<U>::Contextualized(
|
||||
Self::Simple(s, x) => AbilityKind::<U>::Simple(s, f(x)),
|
||||
Self::Contextualized(abilities) => AbilityKind::<U>::Contextualized(
|
||||
abilities
|
||||
.into_iter()
|
||||
.map(|(c, (s, x))| (c, (s, f(x))))
|
||||
@ -305,10 +305,10 @@ impl<T> AuxiliaryAbilityKind<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_ref<U, F: FnMut(&T) -> U>(&self, mut f: F) -> AuxiliaryAbilityKind<U> {
|
||||
pub fn map_ref<U, F: FnMut(&T) -> U>(&self, mut f: F) -> AbilityKind<U> {
|
||||
match self {
|
||||
Self::Simple(s, x) => AuxiliaryAbilityKind::<U>::Simple(*s, f(x)),
|
||||
Self::Contextualized(abilities) => AuxiliaryAbilityKind::<U>::Contextualized(
|
||||
Self::Simple(s, x) => AbilityKind::<U>::Simple(*s, f(x)),
|
||||
Self::Contextualized(abilities) => AbilityKind::<U>::Contextualized(
|
||||
abilities
|
||||
.into_iter()
|
||||
.map(|(c, (s, x))| (*c, (*s, f(x))))
|
||||
@ -317,12 +317,10 @@ impl<T> AuxiliaryAbilityKind<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ability(&self, context: Option<AbilityContext>) -> Option<(Option<Skill>, &T)> {
|
||||
pub fn ability(&self, context: AbilityContext) -> Option<(Option<Skill>, &T)> {
|
||||
match self {
|
||||
AuxiliaryAbilityKind::Simple(s, a) => Some((*s, a)),
|
||||
AuxiliaryAbilityKind::Contextualized(abilities) => {
|
||||
context.and_then(|c| abilities.get(&c).map(|(s, a)| (*s, a)))
|
||||
},
|
||||
AbilityKind::Simple(s, a) => Some((*s, a)),
|
||||
AbilityKind::Contextualized(abilities) => abilities.get(&context).map(|(s, a)| (*s, a)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -330,11 +328,16 @@ impl<T> AuxiliaryAbilityKind<T> {
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Copy, Eq, PartialEq, Hash)]
|
||||
pub enum AbilityContext {
|
||||
Stance(Stance),
|
||||
None,
|
||||
}
|
||||
|
||||
impl AbilityContext {
|
||||
pub fn try_from(stance: Option<&Stance>) -> Option<Self> {
|
||||
stance.map(|stance| Self::Stance(*stance))
|
||||
pub fn from(stance: Option<&Stance>) -> Self {
|
||||
match stance {
|
||||
Some(Stance::None) => AbilityContext::None,
|
||||
Some(stance) => AbilityContext::Stance(*stance),
|
||||
None => AbilityContext::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -351,25 +354,29 @@ impl AbilitySet<AbilityItem> {
|
||||
impl<T> AbilitySet<T> {
|
||||
pub fn map<U, F: FnMut(T) -> U>(self, mut f: F) -> AbilitySet<U> {
|
||||
AbilitySet {
|
||||
primary: f(self.primary),
|
||||
secondary: f(self.secondary),
|
||||
primary: self.primary.map(&mut f),
|
||||
secondary: self.secondary.map(&mut f),
|
||||
abilities: self.abilities.into_iter().map(|x| x.map(&mut f)).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_ref<U, F: FnMut(&T) -> U>(&self, mut f: F) -> AbilitySet<U> {
|
||||
AbilitySet {
|
||||
primary: f(&self.primary),
|
||||
secondary: f(&self.secondary),
|
||||
primary: self.primary.map_ref(&mut f),
|
||||
secondary: self.secondary.map_ref(&mut f),
|
||||
abilities: self.abilities.iter().map(|x| x.map_ref(&mut f)).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn auxiliary(
|
||||
&self,
|
||||
index: usize,
|
||||
context: Option<AbilityContext>,
|
||||
) -> Option<(Option<Skill>, &T)> {
|
||||
pub fn primary(&self, context: AbilityContext) -> Option<(Option<Skill>, &T)> {
|
||||
self.primary.ability(context)
|
||||
}
|
||||
|
||||
pub fn secondary(&self, context: AbilityContext) -> Option<(Option<Skill>, &T)> {
|
||||
self.secondary.ability(context)
|
||||
}
|
||||
|
||||
pub fn auxiliary(&self, index: usize, context: AbilityContext) -> Option<(Option<Skill>, &T)> {
|
||||
self.abilities.get(index).and_then(|a| a.ability(context))
|
||||
}
|
||||
}
|
||||
@ -377,14 +384,14 @@ impl<T> AbilitySet<T> {
|
||||
impl Default for AbilitySet<AbilityItem> {
|
||||
fn default() -> Self {
|
||||
AbilitySet {
|
||||
primary: AbilityItem {
|
||||
primary: AbilityKind::Simple(None, AbilityItem {
|
||||
id: String::new(),
|
||||
ability: CharacterAbility::default(),
|
||||
},
|
||||
secondary: AbilityItem {
|
||||
}),
|
||||
secondary: AbilityKind::Simple(None, AbilityItem {
|
||||
id: String::new(),
|
||||
ability: CharacterAbility::default(),
|
||||
},
|
||||
}),
|
||||
abilities: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
@ -78,11 +78,7 @@ pub enum PoiseState {
|
||||
impl PoiseState {
|
||||
/// Returns the optional stunned character state and duration of stun, and
|
||||
/// optional impulse strength corresponding to a particular poise state
|
||||
pub fn poise_effect(
|
||||
&self,
|
||||
was_wielded: bool,
|
||||
ability_info: states::utils::AbilityInfo,
|
||||
) -> (Option<(CharacterState, f64)>, Option<f32>) {
|
||||
pub fn poise_effect(&self, was_wielded: bool) -> (Option<(CharacterState, f64)>, Option<f32>) {
|
||||
use states::{
|
||||
stunned::{Data, StaticData},
|
||||
utils::StageSection,
|
||||
@ -117,7 +113,6 @@ impl PoiseState {
|
||||
recover_duration,
|
||||
movement_speed,
|
||||
poise_state: *self,
|
||||
ability_info,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
@ -285,7 +280,7 @@ impl Poise {
|
||||
let from_char = {
|
||||
let resistant = char_state
|
||||
.and_then(|cs| cs.ability_info())
|
||||
.and_then(|a| a.ability_meta)
|
||||
.map(|a| a.ability_meta)
|
||||
.map_or(false, |a| {
|
||||
a.capabilities.contains(Capability::POISE_RESISTANT)
|
||||
});
|
||||
|
@ -28,32 +28,32 @@ pub enum Skill {
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
|
||||
pub enum SwordSkill {
|
||||
BalancedFinisher,
|
||||
OffensiveCombo,
|
||||
OffensiveStance,
|
||||
OffensiveFinisher,
|
||||
OffensiveAdvance,
|
||||
CripplingCombo,
|
||||
CripplingStance,
|
||||
CripplingFinisher,
|
||||
CripplingStrike,
|
||||
CripplingGouge,
|
||||
CleavingCombo,
|
||||
CleavingStance,
|
||||
CleavingFinisher,
|
||||
CleavingSpin,
|
||||
CleavingDive,
|
||||
DefensiveCombo,
|
||||
DefensiveStance,
|
||||
DefensiveBulwark,
|
||||
DefensiveRetreat,
|
||||
ParryingCombo,
|
||||
ParryingStance,
|
||||
ParryingParry,
|
||||
ParryingRiposte,
|
||||
ParryingCounter,
|
||||
HeavyCombo,
|
||||
HeavyStance,
|
||||
HeavyFinisher,
|
||||
HeavyPommelStrike,
|
||||
HeavyFortitude,
|
||||
MobilityCombo,
|
||||
MobilityStance,
|
||||
MobilityFeint,
|
||||
MobilityAgility,
|
||||
ReachingCombo,
|
||||
ReachingStance,
|
||||
ReachingCharge,
|
||||
ReachingFlurry,
|
||||
ReachingSkewer,
|
||||
|
@ -96,11 +96,7 @@ impl CharacterBehavior for Data {
|
||||
}
|
||||
},
|
||||
StageSection::Action => {
|
||||
if self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
if input_is_pressed(data, self.static_data.ability_info.input)
|
||||
&& (self.static_data.energy_drain <= f32::EPSILON
|
||||
|| update.energy.current() > 0.0)
|
||||
{
|
||||
|
@ -74,11 +74,7 @@ impl CharacterBehavior for Data {
|
||||
},
|
||||
StageSection::Action => {
|
||||
if self.static_data.can_hold
|
||||
&& self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
&& input_is_pressed(data, self.static_data.ability_info.input)
|
||||
{
|
||||
// Block
|
||||
update.character = CharacterState::BasicBlock(Data {
|
||||
|
@ -118,12 +118,7 @@ impl CharacterBehavior for Data {
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
if self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
{
|
||||
if input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
reset_state(self, data, output_events, &mut update);
|
||||
} else {
|
||||
end_melee_ability(data, &mut update);
|
||||
@ -149,7 +144,10 @@ fn reset_state(
|
||||
output_events: &mut OutputEvents,
|
||||
update: &mut StateUpdate,
|
||||
) {
|
||||
if let Some(input) = data.static_data.ability_info.input {
|
||||
handle_input(join, output_events, update, input);
|
||||
}
|
||||
handle_input(
|
||||
join,
|
||||
output_events,
|
||||
update,
|
||||
data.static_data.ability_info.input,
|
||||
);
|
||||
}
|
||||
|
@ -127,12 +127,7 @@ impl CharacterBehavior for Data {
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
if self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
{
|
||||
if input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
reset_state(self, data, output_events, &mut update);
|
||||
} else {
|
||||
end_ability(data, &mut update);
|
||||
@ -158,7 +153,10 @@ fn reset_state(
|
||||
output_events: &mut OutputEvents,
|
||||
update: &mut StateUpdate,
|
||||
) {
|
||||
if let Some(input) = data.static_data.ability_info.input {
|
||||
handle_input(join, output_events, update, input);
|
||||
}
|
||||
handle_input(
|
||||
join,
|
||||
output_events,
|
||||
update,
|
||||
data.static_data.ability_info.input,
|
||||
);
|
||||
}
|
||||
|
52
common/src/states/basic_stance.rs
Normal file
52
common/src/states/basic_stance.rs
Normal file
@ -0,0 +1,52 @@
|
||||
use super::utils::*;
|
||||
use crate::{
|
||||
comp::{character_state::OutputEvents, CharacterState, Stance, StateUpdate},
|
||||
event::ServerEvent,
|
||||
states::behavior::{CharacterBehavior, JoinData},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
|
||||
/// Separated out to condense update portions of character state
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct StaticData {
|
||||
pub buildup_duration: Duration,
|
||||
pub stance: Stance,
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Data {
|
||||
pub static_data: StaticData,
|
||||
pub timer: Duration,
|
||||
}
|
||||
|
||||
impl CharacterBehavior for Data {
|
||||
fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
|
||||
handle_orientation(data, &mut update, 1.0, None);
|
||||
handle_move(data, &mut update, 1.0);
|
||||
handle_jump(data, output_events, &mut update, 1.0);
|
||||
handle_interrupts(data, &mut update);
|
||||
|
||||
if self.timer < self.static_data.buildup_duration {
|
||||
if let CharacterState::BasicStance(c) = &mut update.character {
|
||||
c.timer = tick_attack_or_default(data, self.timer, None);
|
||||
}
|
||||
} else {
|
||||
let stance = if Some(self.static_data.stance) == data.stance.copied() {
|
||||
Stance::None
|
||||
} else {
|
||||
self.static_data.stance
|
||||
};
|
||||
output_events.emit_server(ServerEvent::ChangeStance {
|
||||
entity: data.entity,
|
||||
stance,
|
||||
});
|
||||
end_ability(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
}
|
||||
}
|
@ -46,12 +46,7 @@ impl CharacterBehavior for Data {
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
if self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
{
|
||||
if input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
reset_state(self, data, output_events, &mut update);
|
||||
} else {
|
||||
update.vel.0 = update.vel.0.try_normalized().unwrap_or_default()
|
||||
@ -74,7 +69,10 @@ fn reset_state(
|
||||
output_events: &mut OutputEvents,
|
||||
update: &mut StateUpdate,
|
||||
) {
|
||||
if let Some(input) = data.static_data.ability_info.input {
|
||||
handle_input(join, output_events, update, input);
|
||||
}
|
||||
handle_input(
|
||||
join,
|
||||
output_events,
|
||||
update,
|
||||
data.static_data.ability_info.input,
|
||||
);
|
||||
}
|
||||
|
@ -61,11 +61,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
match self.stage_section {
|
||||
StageSection::Charge => {
|
||||
if self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
if input_is_pressed(data, self.static_data.ability_info.input)
|
||||
&& update.energy.current() >= self.static_data.energy_cost
|
||||
&& self.timer < self.static_data.charge_duration
|
||||
{
|
||||
@ -84,11 +80,7 @@ impl CharacterBehavior for Data {
|
||||
update
|
||||
.energy
|
||||
.change_by(-self.static_data.energy_drain * data.dt.0);
|
||||
} else if self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
} else if input_is_pressed(data, self.static_data.ability_info.input)
|
||||
&& update.energy.current() >= self.static_data.energy_cost
|
||||
{
|
||||
// Maintains charge
|
||||
|
@ -99,13 +99,7 @@ impl CharacterBehavior for Data {
|
||||
}
|
||||
},
|
||||
StageSection::Charge => {
|
||||
if !self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
&& !self.exhausted
|
||||
{
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) && !self.exhausted {
|
||||
let charge_frac = self.charge_frac();
|
||||
let arrow = ProjectileConstructor::Arrow {
|
||||
damage: self.static_data.initial_damage
|
||||
@ -148,11 +142,7 @@ impl CharacterBehavior for Data {
|
||||
..*self
|
||||
});
|
||||
} else if self.timer < self.static_data.charge_duration
|
||||
&& self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
&& input_is_pressed(data, self.static_data.ability_info.input)
|
||||
{
|
||||
// Charges
|
||||
update.character = CharacterState::ChargedRanged(Data {
|
||||
@ -164,12 +154,7 @@ impl CharacterBehavior for Data {
|
||||
update
|
||||
.energy
|
||||
.change_by(-self.static_data.energy_drain * data.dt.0);
|
||||
} else if self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
{
|
||||
} else if input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
// Holds charge
|
||||
update.character = CharacterState::ChargedRanged(Data {
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
|
@ -342,12 +342,7 @@ impl CharacterBehavior for Data {
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
if self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
{
|
||||
if input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
reset_state(self, data, output_events, &mut update);
|
||||
} else {
|
||||
end_melee_ability(data, &mut update);
|
||||
@ -385,11 +380,14 @@ fn reset_state(
|
||||
output_events: &mut OutputEvents,
|
||||
update: &mut StateUpdate,
|
||||
) {
|
||||
if let Some(input) = data.static_data.ability_info.input {
|
||||
handle_input(join, output_events, update, input);
|
||||
handle_input(
|
||||
join,
|
||||
output_events,
|
||||
update,
|
||||
data.static_data.ability_info.input,
|
||||
);
|
||||
|
||||
if let CharacterState::ComboMelee(c) = &mut update.character {
|
||||
c.stage = (data.stage % data.static_data.num_stages) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,11 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
character_state::OutputEvents,
|
||||
slot::{EquipSlot, Slot},
|
||||
tool::Stats,
|
||||
CharacterState, InputAttr, InputKind, InventoryAction, MeleeConstructor, Stance,
|
||||
StateUpdate,
|
||||
character_state::OutputEvents, tool::Stats, CharacterState, MeleeConstructor, StateUpdate,
|
||||
},
|
||||
event::ServerEvent,
|
||||
states::{
|
||||
behavior::{CharacterBehavior, JoinData},
|
||||
idle,
|
||||
utils::*,
|
||||
wielding,
|
||||
},
|
||||
uid::Uid,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -82,12 +74,6 @@ pub struct StrikeMovement {
|
||||
pub struct StaticData {
|
||||
/// Data for each stage
|
||||
pub strikes: Vec<Strike<Duration>>,
|
||||
/// Whether or not combo melee should function as a stance (where it remains
|
||||
/// in the character state after a strike has finished)
|
||||
pub is_stance: bool,
|
||||
/// If a stance is added, character state will attempt to enter that stance
|
||||
/// if not already in it
|
||||
pub stance: Option<Stance>,
|
||||
/// The amount of energy consumed with each swing
|
||||
pub energy_cost_per_strike: f32,
|
||||
/// What key is used to press ability
|
||||
@ -108,64 +94,24 @@ pub struct Data {
|
||||
pub timer: Duration,
|
||||
/// Checks what section a strike is in, if a strike is currently being
|
||||
/// performed
|
||||
pub stage_section: Option<StageSection>,
|
||||
pub stage_section: StageSection,
|
||||
/// Index of the strike that is currently in progress, or if not in a strike
|
||||
/// currently the next strike that will occur
|
||||
pub completed_strikes: usize,
|
||||
}
|
||||
|
||||
pub const STANCE_ENTER_TIME: Duration = Duration::from_millis(250);
|
||||
pub const STANCE_LEAVE_TIME: Duration = Duration::from_secs(30);
|
||||
|
||||
impl CharacterBehavior for Data {
|
||||
fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
|
||||
fn behavior(&self, data: &JoinData, _output_events: &mut OutputEvents) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
|
||||
if let Some(stance) = self.static_data.stance {
|
||||
if data.stance != Some(&stance) {
|
||||
output_events.emit_server(ServerEvent::ChangeStance {
|
||||
entity: data.entity,
|
||||
stance,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// If is a stance, use M1 to control strikes, otherwise use the input that
|
||||
// activated the ability
|
||||
let ability_input = if self.static_data.is_stance {
|
||||
InputKind::Primary
|
||||
} else {
|
||||
self.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.unwrap_or(InputKind::Primary)
|
||||
};
|
||||
|
||||
handle_orientation(data, &mut update, 1.0, None);
|
||||
let move_eff = if self.stage_section.is_some() {
|
||||
0.7
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
handle_move(data, &mut update, move_eff);
|
||||
let interrupted = handle_interrupts(data, &mut update);
|
||||
handle_move(data, &mut update, 0.7);
|
||||
handle_interrupts(data, &mut update);
|
||||
|
||||
let strike_data = self.strike_data();
|
||||
|
||||
match self.stage_section {
|
||||
Some(StageSection::Ready) => {
|
||||
// Adds a small duration to entering a stance to discourage spam swapping
|
||||
// stances for ability activation benefits of matching stance
|
||||
if self.timer < STANCE_ENTER_TIME {
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = tick_attack_or_default(data, self.timer, None);
|
||||
}
|
||||
} else if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = Duration::default();
|
||||
c.stage_section = None;
|
||||
}
|
||||
},
|
||||
Some(StageSection::Buildup) => {
|
||||
StageSection::Buildup => {
|
||||
if let Some(movement) = strike_data.movement.buildup {
|
||||
handle_forced_movement(data, &mut update, movement);
|
||||
}
|
||||
@ -178,15 +124,15 @@ impl CharacterBehavior for Data {
|
||||
// Transitions to swing section of stage
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = Duration::default();
|
||||
c.stage_section = Some(StageSection::Action);
|
||||
c.stage_section = StageSection::Action;
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(StageSection::Action) => {
|
||||
StageSection::Action => {
|
||||
if let Some(movement) = strike_data.movement.swing {
|
||||
handle_forced_movement(data, &mut update, movement);
|
||||
}
|
||||
if input_is_pressed(data, ability_input) {
|
||||
if input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
// Only have the next strike skip the recover period of this strike if not
|
||||
// every strike in the combo is complete yet
|
||||
@ -221,16 +167,16 @@ impl CharacterBehavior for Data {
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.completed_strikes += 1;
|
||||
}
|
||||
next_strike(&mut update);
|
||||
next_strike(data, &mut update);
|
||||
} else {
|
||||
// Transitions to recover section of stage
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = Duration::default();
|
||||
c.stage_section = Some(StageSection::Recover);
|
||||
c.stage_section = StageSection::Recover;
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(StageSection::Recover) => {
|
||||
StageSection::Recover => {
|
||||
if let Some(movement) = strike_data.movement.recover {
|
||||
handle_forced_movement(data, &mut update, movement);
|
||||
}
|
||||
@ -239,173 +185,17 @@ impl CharacterBehavior for Data {
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = tick_attack_or_default(data, self.timer, None);
|
||||
}
|
||||
} else {
|
||||
// If is a stance, stay in combo melee, otherwise return to wielding
|
||||
if self.static_data.is_stance {
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = Duration::default();
|
||||
c.stage_section = None;
|
||||
c.completed_strikes = 0;
|
||||
}
|
||||
} else {
|
||||
// Return to wielding
|
||||
end_melee_ability(data, &mut update);
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(_) => {
|
||||
_ => {
|
||||
// If it somehow ends up in an incorrect stage section
|
||||
end_melee_ability(data, &mut update);
|
||||
},
|
||||
None => {
|
||||
if self.timer < STANCE_LEAVE_TIME {
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = tick_attack_or_default(data, self.timer, None);
|
||||
}
|
||||
} else {
|
||||
// Done
|
||||
end_melee_ability(data, &mut update);
|
||||
}
|
||||
|
||||
handle_climb(data, &mut update);
|
||||
handle_jump(data, output_events, &mut update, 1.0);
|
||||
|
||||
if input_is_pressed(data, ability_input) {
|
||||
next_strike(&mut update)
|
||||
} else if !self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
&& !interrupted
|
||||
{
|
||||
attempt_input(data, output_events, &mut update);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
update
|
||||
}
|
||||
|
||||
fn start_input(
|
||||
&self,
|
||||
data: &JoinData,
|
||||
input: InputKind,
|
||||
target_entity: Option<Uid>,
|
||||
select_pos: Option<Vec3<f32>>,
|
||||
) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
|
||||
if matches!(data.character, CharacterState::ComboMelee2(data) if data.static_data.ability_info.input == Some(input) && input != InputKind::Primary && data.stage_section.is_none())
|
||||
{
|
||||
end_melee_ability(data, &mut update);
|
||||
} else {
|
||||
update.queued_inputs.insert(input, InputAttr {
|
||||
select_pos,
|
||||
target_entity,
|
||||
});
|
||||
}
|
||||
update
|
||||
}
|
||||
|
||||
fn swap_equipped_weapons(&self, data: &JoinData, _: &mut OutputEvents) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
if let CharacterState::ComboMelee2(c) = data.character {
|
||||
if c.stage_section.is_none() {
|
||||
update.character = CharacterState::Wielding(wielding::Data {
|
||||
is_sneaking: data.character.is_stealthy(),
|
||||
});
|
||||
attempt_swap_equipped_weapons(data, &mut update);
|
||||
}
|
||||
}
|
||||
update
|
||||
}
|
||||
|
||||
fn unwield(&self, data: &JoinData, _: &mut OutputEvents) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
if let CharacterState::ComboMelee2(c) = data.character {
|
||||
if c.stage_section.is_none() {
|
||||
update.character = CharacterState::Idle(idle::Data {
|
||||
is_sneaking: data.character.is_stealthy(),
|
||||
footwear: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
update
|
||||
}
|
||||
|
||||
fn manipulate_loadout(
|
||||
&self,
|
||||
data: &JoinData,
|
||||
output_events: &mut OutputEvents,
|
||||
inv_action: InventoryAction,
|
||||
) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
if let CharacterState::ComboMelee2(c) = data.character {
|
||||
if c.stage_section.is_none() {
|
||||
let reset_to_idle = match inv_action {
|
||||
InventoryAction::Drop(slot)
|
||||
| InventoryAction::Swap(slot, _)
|
||||
| InventoryAction::Swap(_, Slot::Equip(slot))
|
||||
if matches!(slot, EquipSlot::ActiveMainhand | EquipSlot::ActiveOffhand) =>
|
||||
{
|
||||
true
|
||||
},
|
||||
InventoryAction::Use(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
if reset_to_idle {
|
||||
update.character = CharacterState::Idle(idle::Data {
|
||||
is_sneaking: data.character.is_stealthy(),
|
||||
footwear: None,
|
||||
});
|
||||
}
|
||||
handle_manipulate_loadout(data, output_events, &mut update, inv_action);
|
||||
}
|
||||
}
|
||||
update
|
||||
}
|
||||
|
||||
fn glide_wield(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
if let CharacterState::ComboMelee2(c) = data.character {
|
||||
if c.stage_section.is_none() {
|
||||
attempt_glide_wield(data, &mut update, output_events);
|
||||
}
|
||||
}
|
||||
update
|
||||
}
|
||||
|
||||
fn sit(&self, data: &JoinData, _: &mut OutputEvents) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
if let CharacterState::ComboMelee2(c) = data.character {
|
||||
if c.stage_section.is_none() {
|
||||
attempt_sit(data, &mut update);
|
||||
}
|
||||
}
|
||||
update
|
||||
}
|
||||
|
||||
fn dance(&self, data: &JoinData, _: &mut OutputEvents) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
if let CharacterState::ComboMelee2(c) = data.character {
|
||||
if c.stage_section.is_none() {
|
||||
attempt_dance(data, &mut update);
|
||||
}
|
||||
}
|
||||
update
|
||||
}
|
||||
|
||||
fn sneak(&self, data: &JoinData, _: &mut OutputEvents) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
if let CharacterState::ComboMelee2(c) = data.character {
|
||||
if c.stage_section.is_none()
|
||||
&& data.physics.on_ground.is_some()
|
||||
&& data.body.is_humanoid()
|
||||
{
|
||||
update.character = CharacterState::Wielding(wielding::Data { is_sneaking: true });
|
||||
}
|
||||
}
|
||||
update
|
||||
}
|
||||
}
|
||||
@ -416,7 +206,7 @@ impl Data {
|
||||
}
|
||||
}
|
||||
|
||||
fn next_strike(update: &mut StateUpdate) {
|
||||
fn next_strike(data: &JoinData, update: &mut StateUpdate) {
|
||||
let revert_to_wield = if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
if update
|
||||
.energy
|
||||
@ -426,7 +216,7 @@ fn next_strike(update: &mut StateUpdate) {
|
||||
c.exhausted = false;
|
||||
c.start_next_strike = false;
|
||||
c.timer = Duration::default();
|
||||
c.stage_section = Some(StageSection::Buildup);
|
||||
c.stage_section = StageSection::Buildup;
|
||||
false
|
||||
} else {
|
||||
true
|
||||
@ -435,6 +225,6 @@ fn next_strike(update: &mut StateUpdate) {
|
||||
false
|
||||
};
|
||||
if revert_to_wield {
|
||||
update.character = CharacterState::Wielding(wielding::Data { is_sneaking: false });
|
||||
end_melee_ability(data, update)
|
||||
}
|
||||
}
|
||||
|
@ -81,11 +81,7 @@ impl CharacterBehavior for Data {
|
||||
} else {
|
||||
// Transitions to charge section of stage
|
||||
update.character = CharacterState::DashMelee(Data {
|
||||
auto_charge: !self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input)),
|
||||
auto_charge: !input_is_pressed(data, self.static_data.ability_info.input),
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Charge,
|
||||
..*self
|
||||
@ -94,11 +90,7 @@ impl CharacterBehavior for Data {
|
||||
},
|
||||
StageSection::Charge => {
|
||||
if self.timer < self.charge_end_timer
|
||||
&& (self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
&& (input_is_pressed(data, self.static_data.ability_info.input)
|
||||
|| (self.auto_charge && self.timer < self.static_data.charge_duration))
|
||||
&& update.energy.current() > 0.0
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ pub mod basic_beam;
|
||||
pub mod basic_block;
|
||||
pub mod basic_melee;
|
||||
pub mod basic_ranged;
|
||||
pub mod basic_stance;
|
||||
pub mod basic_summon;
|
||||
pub mod behavior;
|
||||
pub mod blink;
|
||||
|
@ -56,12 +56,7 @@ impl CharacterBehavior for Data {
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
if self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
{
|
||||
if input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
reset_state(self, data, output_events, &mut update);
|
||||
} else {
|
||||
end_ability(data, &mut update);
|
||||
@ -75,12 +70,7 @@ impl CharacterBehavior for Data {
|
||||
}
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
{
|
||||
if !input_is_pressed(data, self.static_data.ability_info.input) {
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
@ -94,7 +84,10 @@ fn reset_state(
|
||||
output_events: &mut OutputEvents,
|
||||
update: &mut StateUpdate,
|
||||
) {
|
||||
if let Some(input) = data.static_data.ability_info.input {
|
||||
handle_input(join, output_events, update, input);
|
||||
}
|
||||
handle_input(
|
||||
join,
|
||||
output_events,
|
||||
update,
|
||||
data.static_data.ability_info.input,
|
||||
);
|
||||
}
|
||||
|
@ -87,11 +87,7 @@ impl CharacterBehavior for Data {
|
||||
.unwrap_or_default(),
|
||||
..*self
|
||||
});
|
||||
} else if self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))
|
||||
} else if input_is_pressed(data, self.static_data.ability_info.input)
|
||||
&& update.energy.current() >= self.static_data.energy_cost
|
||||
{
|
||||
// Fire if input is pressed still
|
||||
|
@ -121,11 +121,7 @@ impl CharacterBehavior for Data {
|
||||
} else if update.energy.current() >= self.static_data.energy_cost
|
||||
&& (self.consecutive_spins < self.static_data.num_spins
|
||||
|| (self.static_data.is_infinite
|
||||
&& self
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map_or(false, |input| input_is_pressed(data, input))))
|
||||
&& input_is_pressed(data, self.static_data.ability_info.input)))
|
||||
{
|
||||
update.character = CharacterState::SpinMelee(Data {
|
||||
timer: Duration::default(),
|
||||
|
@ -39,8 +39,6 @@ pub struct StaticData {
|
||||
///
|
||||
/// If third field is true, item should be consumed on collection
|
||||
pub required_item: Option<(ItemDefinitionIdOwned, InvSlotId, bool)>,
|
||||
/// Miscellaneous information about the ability
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
|
@ -17,8 +17,6 @@ pub struct StaticData {
|
||||
pub movement_speed: f32,
|
||||
/// Poise state (used for determining animation in the client)
|
||||
pub poise_state: PoiseState,
|
||||
/// Miscellaneous information about the ability
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
|
@ -16,7 +16,7 @@ use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
|
||||
/// Separated out to condense update portions of character state
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct StaticData {
|
||||
/// Buildup to item use
|
||||
pub buildup_duration: Duration,
|
||||
@ -34,11 +34,9 @@ pub struct StaticData {
|
||||
pub was_wielded: bool,
|
||||
/// Was sneaking
|
||||
pub was_sneak: bool,
|
||||
/// Miscellaneous information about the ability
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Data {
|
||||
/// Struct containing data that does not change over the course of the
|
||||
/// character state
|
||||
|
@ -667,7 +667,9 @@ pub fn fly_move(data: &JoinData<'_>, update: &mut StateUpdate, efficiency: f32)
|
||||
/// Checks if an input related to an attack is held. If one is, moves entity
|
||||
/// into wielding state
|
||||
pub fn handle_wield(data: &JoinData<'_>, update: &mut StateUpdate) {
|
||||
if data.controller.queued_inputs.keys().any(|i| i.is_ability()) {
|
||||
if data.controller.queued_inputs.keys().any(|i| i.is_ability())
|
||||
|| data.controller.held_inputs.keys().any(|i| i.is_ability())
|
||||
{
|
||||
attempt_wield(data, update);
|
||||
}
|
||||
}
|
||||
@ -818,7 +820,6 @@ pub fn handle_manipulate_loadout(
|
||||
item_hash: item.item_hash(),
|
||||
was_wielded: data.character.is_wield(),
|
||||
was_sneak: data.character.is_stealthy(),
|
||||
ability_info: AbilityInfo::from_forced_state_change(data.character),
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
@ -950,9 +951,6 @@ pub fn handle_manipulate_loadout(
|
||||
was_wielded: data.character.is_wield(),
|
||||
was_sneak: data.character.is_stealthy(),
|
||||
required_item,
|
||||
ability_info: AbilityInfo::from_forced_state_change(
|
||||
data.character,
|
||||
),
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
@ -1034,7 +1032,7 @@ pub fn handle_jump(
|
||||
}
|
||||
|
||||
fn handle_ability(data: &JoinData<'_>, update: &mut StateUpdate, input: InputKind) -> bool {
|
||||
let context = AbilityContext::try_from(data.stance);
|
||||
let context = AbilityContext::from(data.stance);
|
||||
if let Some(ability_input) = input.into() {
|
||||
if let Some((ability, from_offhand)) = data
|
||||
.active_abilities
|
||||
@ -1090,7 +1088,13 @@ pub fn attempt_input(
|
||||
update: &mut StateUpdate,
|
||||
) {
|
||||
// TODO: look into using first() when it becomes stable
|
||||
if let Some(input) = data.controller.queued_inputs.keys().next() {
|
||||
if let Some(input) = data
|
||||
.controller
|
||||
.queued_inputs
|
||||
.keys()
|
||||
.next()
|
||||
.or_else(|| data.controller.held_inputs.keys().next())
|
||||
{
|
||||
handle_input(data, output_events, update, *input);
|
||||
}
|
||||
}
|
||||
@ -1134,11 +1138,7 @@ pub fn handle_dodge_input(data: &JoinData<'_>, update: &mut StateUpdate) -> bool
|
||||
update.used_inputs.push(InputKind::Roll);
|
||||
if let CharacterState::Roll(roll) = &mut update.character {
|
||||
if let CharacterState::ComboMelee(c) = data.character {
|
||||
roll.was_combo = c
|
||||
.static_data
|
||||
.ability_info
|
||||
.input
|
||||
.map(|input| (input, c.stage));
|
||||
roll.was_combo = Some((c.static_data.ability_info.input, c.stage));
|
||||
roll.was_wielded = true;
|
||||
} else {
|
||||
if data.character.is_wield() {
|
||||
@ -1170,7 +1170,7 @@ pub fn handle_interrupts(data: &JoinData, update: &mut StateUpdate) -> bool {
|
||||
let interruptible = data
|
||||
.character
|
||||
.ability_info()
|
||||
.and_then(|info| info.ability_meta)
|
||||
.map(|info| info.ability_meta)
|
||||
.map_or(false, |meta| {
|
||||
meta.capabilities.contains(Capability::ROLL_INTERRUPT)
|
||||
});
|
||||
@ -1179,7 +1179,7 @@ pub fn handle_interrupts(data: &JoinData, update: &mut StateUpdate) -> bool {
|
||||
let can_block = data
|
||||
.character
|
||||
.ability_info()
|
||||
.and_then(|info| info.ability_meta)
|
||||
.map(|info| info.ability_meta)
|
||||
.map_or(false, |meta| {
|
||||
meta.capabilities.contains(Capability::BLOCK_INTERRUPT)
|
||||
});
|
||||
@ -1313,7 +1313,6 @@ pub enum StageSection {
|
||||
Charge,
|
||||
Movement,
|
||||
Action,
|
||||
Ready,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -1359,11 +1358,10 @@ impl MovementDirection {
|
||||
pub struct AbilityInfo {
|
||||
pub tool: Option<ToolKind>,
|
||||
pub hand: Option<HandInfo>,
|
||||
pub input: Option<InputKind>,
|
||||
pub input: InputKind,
|
||||
pub input_attr: Option<InputAttr>,
|
||||
pub ability_meta: Option<AbilityMeta>,
|
||||
pub ability_meta: AbilityMeta,
|
||||
pub ability: Option<Ability>,
|
||||
pub return_ability: Option<InputKind>,
|
||||
}
|
||||
|
||||
impl AbilityInfo {
|
||||
@ -1388,68 +1386,23 @@ impl AbilityInfo {
|
||||
.zip(data.active_abilities)
|
||||
.map(|(i, a)| a.get_ability(i, data.inventory, Some(data.skill_set)));
|
||||
|
||||
let return_ability = if data.character.should_be_returned_to() {
|
||||
data.character.ability_info().and_then(|info| info.input)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Self {
|
||||
tool,
|
||||
hand,
|
||||
input: Some(input),
|
||||
input_attr: data.controller.queued_inputs.get(&input).copied(),
|
||||
ability_meta: Some(ability_meta),
|
||||
input,
|
||||
input_attr: data
|
||||
.controller
|
||||
.queued_inputs
|
||||
.get(&input)
|
||||
.or_else(|| data.controller.held_inputs.get(&input))
|
||||
.copied(),
|
||||
ability_meta,
|
||||
ability,
|
||||
return_ability,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_forced_state_change(char_state: &CharacterState) -> Self {
|
||||
let return_ability = if char_state.should_be_returned_to() {
|
||||
char_state.ability_info().and_then(|info| info.input)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// If this ability should not be returned to, check if this ability was going to
|
||||
// return to another ability, and return to that one instead
|
||||
let return_ability = return_ability.or_else(|| {
|
||||
char_state
|
||||
.ability_info()
|
||||
.and_then(|info| info.return_ability)
|
||||
});
|
||||
|
||||
Self {
|
||||
tool: None,
|
||||
hand: None,
|
||||
input: None,
|
||||
input_attr: None,
|
||||
ability_meta: None,
|
||||
ability: None,
|
||||
return_ability,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn end_ability(data: &JoinData<'_>, update: &mut StateUpdate) {
|
||||
// If an ability has a return ability specified, and is not itself an ability
|
||||
// that should be returned to (to prevent bouncing between two abilities),
|
||||
// attempt to return to the specified ability, otherwise return to wield or idle
|
||||
// depending on whether or not leaving a wield state
|
||||
let returned = if let Some(return_ability) = (!data.character.should_be_returned_to())
|
||||
.then_some(
|
||||
data.character
|
||||
.ability_info()
|
||||
.and_then(|info| info.return_ability),
|
||||
)
|
||||
.flatten()
|
||||
{
|
||||
handle_ability(data, update, return_ability)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
if !returned {
|
||||
if data.character.is_wield() || data.character.was_wielded() {
|
||||
update.character = CharacterState::Wielding(wielding::Data {
|
||||
is_sneaking: data.character.is_stealthy(),
|
||||
@ -1461,7 +1414,6 @@ pub fn end_ability(data: &JoinData<'_>, update: &mut StateUpdate) {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn end_melee_ability(data: &JoinData<'_>, update: &mut StateUpdate) {
|
||||
end_ability(data, update);
|
||||
|
@ -19,7 +19,7 @@ use common::{
|
||||
resources::{DeltaTime, Time},
|
||||
states::{
|
||||
behavior::{JoinData, JoinStruct},
|
||||
idle, utils,
|
||||
idle,
|
||||
},
|
||||
terrain::TerrainGrid,
|
||||
uid::Uid,
|
||||
@ -152,11 +152,10 @@ impl<'a> System<'a> for Sys {
|
||||
// Enter stunned state if poise damage is enough
|
||||
if let Some(mut poise) = poises.get_mut(entity) {
|
||||
let was_wielded = char_state.is_wield();
|
||||
let ability_info = utils::AbilityInfo::from_forced_state_change(&char_state);
|
||||
let poise_state = poise.poise_state();
|
||||
let pos = pos.0;
|
||||
if let (Some((stunned_state, stunned_duration)), impulse_strength) =
|
||||
poise_state.poise_effect(was_wielded, ability_info)
|
||||
poise_state.poise_effect(was_wielded)
|
||||
{
|
||||
// Reset poise if there is some stunned state to apply
|
||||
poise.reset(*read_data.time, stunned_duration);
|
||||
|
@ -9,7 +9,6 @@ use common::{
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
resources::{DeltaTime, EntitiesDiedLastTick, Time},
|
||||
states,
|
||||
};
|
||||
use common_ecs::{Job, Origin, Phase, System};
|
||||
use specs::{
|
||||
@ -163,11 +162,7 @@ impl<'a> System<'a> for Sys {
|
||||
| CharacterState::GlideWield(_)
|
||||
| CharacterState::Wielding(_)
|
||||
| CharacterState::Equipping(_)
|
||||
| CharacterState::Boost(_)
|
||||
| CharacterState::ComboMelee2(states::combo_melee2::Data {
|
||||
stage_section: None,
|
||||
..
|
||||
}) => {
|
||||
| CharacterState::Boost(_) => {
|
||||
if energy.needs_regen() {
|
||||
energy.regen(ENERGY_REGEN_ACCEL, dt);
|
||||
}
|
||||
@ -199,7 +194,8 @@ impl<'a> System<'a> for Sys {
|
||||
| CharacterState::FinisherMelee(_)
|
||||
| CharacterState::DiveMelee(_)
|
||||
| CharacterState::RiposteMelee(_)
|
||||
| CharacterState::RapidMelee(_) => {
|
||||
| CharacterState::RapidMelee(_)
|
||||
| CharacterState::BasicStance(_) => {
|
||||
if energy.needs_regen_rate_reset() {
|
||||
energy.reset_regen_rate();
|
||||
}
|
||||
|
@ -820,7 +820,7 @@ impl<'a> AgentData<'a> {
|
||||
&& self
|
||||
.char_state
|
||||
.ability_info()
|
||||
.and_then(|a| a.ability_meta)
|
||||
.map(|a| a.ability_meta)
|
||||
.map(|m| m.capabilities)
|
||||
.map_or(false, |c| c.contains(Capability::BLOCK_INTERRUPT))
|
||||
} else {
|
||||
@ -843,7 +843,7 @@ impl<'a> AgentData<'a> {
|
||||
agent.action_state.conditions[CONDITION_HOLD] = false;
|
||||
agent.action_state.timers[TIMER_HOLD_TIMEOUT] = 0.0;
|
||||
} else if matches!(
|
||||
self.char_state.ability_info().and_then(|info| info.input),
|
||||
self.char_state.ability_info().map(|info| info.input),
|
||||
Some(InputKind::Ability(1))
|
||||
) {
|
||||
// If used defensive retreat, stand still for a little bit to bait people
|
||||
@ -927,7 +927,7 @@ impl<'a> AgentData<'a> {
|
||||
&& self
|
||||
.char_state
|
||||
.ability_info()
|
||||
.and_then(|a| a.ability_meta)
|
||||
.map(|a| a.ability_meta)
|
||||
.map(|m| m.capabilities)
|
||||
.map_or(false, |c| c.contains(Capability::ROLL_INTERRUPT));
|
||||
if try_roll {
|
||||
@ -1617,7 +1617,7 @@ impl<'a> AgentData<'a> {
|
||||
enum ActionStateConditions {
|
||||
ConditionStaffCanShockwave = 0,
|
||||
}
|
||||
let context = AbilityContext::try_from(self.stance);
|
||||
let context = AbilityContext::from(self.stance);
|
||||
let extract_ability = |input: AbilityInput| {
|
||||
self.active_abilities
|
||||
.activate_ability(
|
||||
|
@ -27,7 +27,7 @@ use common::{
|
||||
outcome::{HealthChangeInfo, Outcome},
|
||||
resources::{Secs, Time},
|
||||
rtsim::RtSimEntity,
|
||||
states::utils::{AbilityInfo, StageSection},
|
||||
states::utils::StageSection,
|
||||
terrain::{Block, BlockKind, TerrainGrid},
|
||||
uid::{Uid, UidAllocator},
|
||||
util::Dir,
|
||||
@ -1245,27 +1245,12 @@ pub fn handle_parry_hook(server: &Server, defender: EcsEntity, attacker: Option<
|
||||
.write_storage::<comp::CharacterState>()
|
||||
.get_mut(defender)
|
||||
{
|
||||
let should_return = char_state
|
||||
.ability_info()
|
||||
.and_then(|info| info.return_ability)
|
||||
.is_some();
|
||||
|
||||
let return_to_wield = match &mut *char_state {
|
||||
CharacterState::RiposteMelee(c) => {
|
||||
c.stage_section = StageSection::Action;
|
||||
c.timer = Duration::default();
|
||||
false
|
||||
},
|
||||
CharacterState::BasicBlock(c) if should_return => {
|
||||
c.timer = c.static_data.recover_duration;
|
||||
c.stage_section = StageSection::Recover;
|
||||
// Refund half the energy of entering the block for a successful parry
|
||||
server_eventbus.emit_now(ServerEvent::EnergyChange {
|
||||
entity: defender,
|
||||
change: c.static_data.energy_cost / 2.0,
|
||||
});
|
||||
false
|
||||
},
|
||||
CharacterState::BasicBlock(c) => {
|
||||
// Refund half the energy of entering the block for a successful parry
|
||||
server_eventbus.emit_now(ServerEvent::EnergyChange {
|
||||
@ -1280,7 +1265,7 @@ pub fn handle_parry_hook(server: &Server, defender: EcsEntity, attacker: Option<
|
||||
// defender
|
||||
if char_state
|
||||
.ability_info()
|
||||
.and_then(|info| info.ability_meta)
|
||||
.map(|info| info.ability_meta)
|
||||
.map_or(false, |meta| {
|
||||
meta.capabilities
|
||||
.contains(comp::ability::Capability::BUILDUP_PARRIES)
|
||||
@ -1374,9 +1359,8 @@ pub fn handle_entity_attacked_hook(server: &Server, entity: EcsEntity) {
|
||||
) {
|
||||
let poise_state = comp::poise::PoiseState::Interrupted;
|
||||
let was_wielded = char_state.is_wield();
|
||||
let ability_info = AbilityInfo::from_forced_state_change(&char_state);
|
||||
if let (Some((stunned_state, stunned_duration)), impulse_strength) =
|
||||
poise_state.poise_effect(was_wielded, ability_info)
|
||||
poise_state.poise_effect(was_wielded)
|
||||
{
|
||||
// Reset poise if there is some stunned state to apply
|
||||
poise.reset(*time, stunned_duration);
|
||||
|
@ -242,7 +242,7 @@ pub struct Diary<'a> {
|
||||
tooltip_manager: &'a mut TooltipManager,
|
||||
slot_manager: &'a mut SlotManager,
|
||||
pulse: f32,
|
||||
context: Option<AbilityContext>,
|
||||
context: AbilityContext,
|
||||
|
||||
#[conrod(common_builder)]
|
||||
common: widget::CommonBuilder,
|
||||
@ -288,7 +288,7 @@ impl<'a> Diary<'a> {
|
||||
tooltip_manager: &'a mut TooltipManager,
|
||||
slot_manager: &'a mut SlotManager,
|
||||
pulse: f32,
|
||||
context: Option<AbilityContext>,
|
||||
context: AbilityContext,
|
||||
) -> Self {
|
||||
Self {
|
||||
show,
|
||||
@ -1596,7 +1596,7 @@ impl<'a> Diary<'a> {
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 489.0, 462.0),
|
||||
},
|
||||
SkillIcon::Ability {
|
||||
skill: Skill::Sword(SwordSkill::OffensiveCombo),
|
||||
skill: Skill::Sword(SwordSkill::OffensiveStance),
|
||||
ability_id: "common.abilities.sword.offensive_combo",
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 389.0, 313.0),
|
||||
},
|
||||
@ -1611,7 +1611,7 @@ impl<'a> Diary<'a> {
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 489.0, 361.0),
|
||||
},
|
||||
SkillIcon::Ability {
|
||||
skill: Skill::Sword(SwordSkill::CripplingCombo),
|
||||
skill: Skill::Sword(SwordSkill::CripplingStance),
|
||||
ability_id: "common.abilities.sword.crippling_combo",
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 289.0, 164.0),
|
||||
},
|
||||
@ -1631,7 +1631,7 @@ impl<'a> Diary<'a> {
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 2.0, 164.0),
|
||||
},
|
||||
SkillIcon::Ability {
|
||||
skill: Skill::Sword(SwordSkill::CleavingCombo),
|
||||
skill: Skill::Sword(SwordSkill::CleavingStance),
|
||||
ability_id: "common.abilities.sword.cleaving_combo",
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 289.0, 15.0),
|
||||
},
|
||||
@ -1651,7 +1651,7 @@ impl<'a> Diary<'a> {
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 2.0, 15.0),
|
||||
},
|
||||
SkillIcon::Ability {
|
||||
skill: Skill::Sword(SwordSkill::DefensiveCombo),
|
||||
skill: Skill::Sword(SwordSkill::DefensiveStance),
|
||||
ability_id: "common.abilities.sword.defensive_combo",
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 389.0, 611.0),
|
||||
},
|
||||
@ -1666,7 +1666,7 @@ impl<'a> Diary<'a> {
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 489.0, 563.0),
|
||||
},
|
||||
SkillIcon::Ability {
|
||||
skill: Skill::Sword(SwordSkill::ParryingCombo),
|
||||
skill: Skill::Sword(SwordSkill::ParryingStance),
|
||||
ability_id: "common.abilities.sword.parrying_combo",
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 289.0, 760.0),
|
||||
},
|
||||
@ -1686,7 +1686,7 @@ impl<'a> Diary<'a> {
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 2.0, 760.0),
|
||||
},
|
||||
SkillIcon::Ability {
|
||||
skill: Skill::Sword(SwordSkill::HeavyCombo),
|
||||
skill: Skill::Sword(SwordSkill::HeavyStance),
|
||||
ability_id: "common.abilities.sword.heavy_combo",
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 289.0, 909.0),
|
||||
},
|
||||
@ -1706,7 +1706,7 @@ impl<'a> Diary<'a> {
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 2.0, 909.0),
|
||||
},
|
||||
SkillIcon::Ability {
|
||||
skill: Skill::Sword(SwordSkill::MobilityCombo),
|
||||
skill: Skill::Sword(SwordSkill::MobilityStance),
|
||||
ability_id: "common.abilities.sword.mobility_combo",
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 289.0, 462.0),
|
||||
},
|
||||
@ -1721,7 +1721,7 @@ impl<'a> Diary<'a> {
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 289.0, 611.0),
|
||||
},
|
||||
SkillIcon::Ability {
|
||||
skill: Skill::Sword(SwordSkill::ReachingCombo),
|
||||
skill: Skill::Sword(SwordSkill::ReachingStance),
|
||||
ability_id: "common.abilities.sword.reaching_combo",
|
||||
position: TopLeftWithMarginsOn(state.ids.sword_bg, 141.0, 462.0),
|
||||
},
|
||||
|
@ -2995,7 +2995,7 @@ impl Hud {
|
||||
skillsets.get(entity),
|
||||
bodies.get(entity),
|
||||
) {
|
||||
let context = AbilityContext::try_from(stances.get(entity));
|
||||
let context = AbilityContext::from(stances.get(entity));
|
||||
match Skillbar::new(
|
||||
client,
|
||||
&info,
|
||||
@ -3466,7 +3466,7 @@ impl Hud {
|
||||
bodies.get(entity),
|
||||
poises.get(entity),
|
||||
) {
|
||||
let context = AbilityContext::try_from(stances.get(entity));
|
||||
let context = AbilityContext::from(stances.get(entity));
|
||||
for event in Diary::new(
|
||||
&self.show,
|
||||
client,
|
||||
|
@ -310,7 +310,7 @@ pub struct Skillbar<'a> {
|
||||
common: widget::CommonBuilder,
|
||||
msm: &'a MaterialStatManifest,
|
||||
combo_floater: Option<ComboFloater>,
|
||||
context: Option<AbilityContext>,
|
||||
context: AbilityContext,
|
||||
combo: Option<&'a Combo>,
|
||||
}
|
||||
|
||||
@ -341,7 +341,7 @@ impl<'a> Skillbar<'a> {
|
||||
localized_strings: &'a Localization,
|
||||
msm: &'a MaterialStatManifest,
|
||||
combo_floater: Option<ComboFloater>,
|
||||
context: Option<AbilityContext>,
|
||||
context: AbilityContext,
|
||||
combo: Option<&'a Combo>,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
@ -128,7 +128,7 @@ type HotbarSource<'a> = (
|
||||
&'a SkillSet,
|
||||
Option<&'a ActiveAbilities>,
|
||||
&'a Body,
|
||||
Option<AbilityContext>,
|
||||
AbilityContext,
|
||||
Option<&'a Combo>,
|
||||
);
|
||||
type HotbarImageSource<'a> = (&'a ItemImgs, &'a img_ids::Imgs);
|
||||
@ -219,7 +219,7 @@ type AbilitiesSource<'a> = (
|
||||
&'a ActiveAbilities,
|
||||
&'a Inventory,
|
||||
&'a SkillSet,
|
||||
Option<AbilityContext>,
|
||||
AbilityContext,
|
||||
);
|
||||
|
||||
impl<'a> SlotKey<AbilitiesSource<'a>, img_ids::Imgs> for AbilitySlot {
|
||||
|
@ -346,31 +346,39 @@ pub fn ability_image(imgs: &img_ids::Imgs, ability_id: &str) -> image::Id {
|
||||
"common.abilities.sword.balanced_thrust" => imgs.sword_balanced_thrust,
|
||||
"common.abilities.sword.balanced_finisher" => imgs.sword_balanced_finisher,
|
||||
"common.abilities.sword.offensive_combo" => imgs.sword_offensive_combo,
|
||||
"common.abilities.sword.offensive_stance" => imgs.sword_offensive_combo,
|
||||
"common.abilities.sword.offensive_finisher" => imgs.sword_offensive_finisher,
|
||||
"common.abilities.sword.offensive_advance" => imgs.sword_offensive_advance,
|
||||
"common.abilities.sword.crippling_combo" => imgs.sword_crippling_combo,
|
||||
"common.abilities.sword.crippling_stance" => imgs.sword_crippling_combo,
|
||||
"common.abilities.sword.crippling_finisher" => imgs.sword_crippling_finisher,
|
||||
"common.abilities.sword.crippling_strike" => imgs.sword_crippling_strike,
|
||||
"common.abilities.sword.crippling_gouge" => imgs.sword_crippling_gouge,
|
||||
"common.abilities.sword.cleaving_combo" => imgs.sword_cleaving_combo,
|
||||
"common.abilities.sword.cleaving_stance" => imgs.sword_cleaving_combo,
|
||||
"common.abilities.sword.cleaving_finisher" => imgs.sword_cleaving_finisher,
|
||||
"common.abilities.sword.cleaving_spin" => imgs.sword_cleaving_spin,
|
||||
"common.abilities.sword.cleaving_dive" => imgs.sword_cleaving_dive,
|
||||
"common.abilities.sword.defensive_combo" => imgs.sword_defensive_combo,
|
||||
"common.abilities.sword.defensive_stance" => imgs.sword_defensive_combo,
|
||||
"common.abilities.sword.defensive_bulwark" => imgs.sword_defensive_bulwark,
|
||||
"common.abilities.sword.defensive_retreat" => imgs.sword_defensive_retreat,
|
||||
"common.abilities.sword.parrying_combo" => imgs.sword_parrying_combo,
|
||||
"common.abilities.sword.parrying_stance" => imgs.sword_parrying_combo,
|
||||
"common.abilities.sword.parrying_parry" => imgs.sword_parrying_parry,
|
||||
"common.abilities.sword.parrying_riposte" => imgs.sword_parrying_riposte,
|
||||
"common.abilities.sword.parrying_counter" => imgs.sword_parrying_counter,
|
||||
"common.abilities.sword.heavy_combo" => imgs.sword_heavy_combo,
|
||||
"common.abilities.sword.heavy_stance" => imgs.sword_heavy_combo,
|
||||
"common.abilities.sword.heavy_finisher" => imgs.sword_heavy_finisher,
|
||||
"common.abilities.sword.heavy_pommelstrike" => imgs.sword_heavy_pommelstrike,
|
||||
"common.abilities.sword.heavy_fortitude" => imgs.sword_heavy_fortitude,
|
||||
"common.abilities.sword.mobility_combo" => imgs.sword_mobility_combo,
|
||||
"common.abilities.sword.mobility_stance" => imgs.sword_mobility_combo,
|
||||
"common.abilities.sword.mobility_feint" => imgs.sword_mobility_feint,
|
||||
"common.abilities.sword.mobility_agility" => imgs.sword_mobility_agility,
|
||||
"common.abilities.sword.reaching_combo" => imgs.sword_reaching_combo,
|
||||
"common.abilities.sword.reaching_stance" => imgs.sword_reaching_combo,
|
||||
"common.abilities.sword.reaching_charge" => imgs.sword_reaching_charge,
|
||||
"common.abilities.sword.reaching_flurry" => imgs.sword_reaching_flurry,
|
||||
"common.abilities.sword.reaching_skewer" => imgs.sword_reaching_skewer,
|
||||
|
@ -920,7 +920,7 @@ impl FigureMgr {
|
||||
let second_tool_spec = second_tool_spec.as_deref();
|
||||
let hands = (active_tool_hand, second_tool_hand);
|
||||
|
||||
let context = AbilityContext::try_from(stance);
|
||||
let context = AbilityContext::from(stance);
|
||||
|
||||
let ability_id = character.and_then(|c| {
|
||||
c.ability_info()
|
||||
@ -1759,26 +1759,17 @@ impl FigureMgr {
|
||||
}
|
||||
},
|
||||
CharacterState::ComboMelee2(s) => {
|
||||
if matches!(
|
||||
s.stage_section,
|
||||
Some(
|
||||
StageSection::Buildup
|
||||
| StageSection::Action
|
||||
| StageSection::Recover
|
||||
)
|
||||
) {
|
||||
let timer = s.timer.as_secs_f32();
|
||||
let current_strike =
|
||||
s.completed_strikes % s.static_data.strikes.len();
|
||||
let current_strike = s.completed_strikes % s.static_data.strikes.len();
|
||||
let strike_data = s.static_data.strikes[current_strike];
|
||||
let progress = match s.stage_section {
|
||||
Some(StageSection::Buildup) => {
|
||||
StageSection::Buildup => {
|
||||
timer / strike_data.buildup_duration.as_secs_f32()
|
||||
},
|
||||
Some(StageSection::Action) => {
|
||||
StageSection::Action => {
|
||||
timer / strike_data.swing_duration.as_secs_f32()
|
||||
},
|
||||
Some(StageSection::Recover) => {
|
||||
StageSection::Recover => {
|
||||
timer / strike_data.recover_duration.as_secs_f32()
|
||||
},
|
||||
_ => 0.0,
|
||||
@ -1788,7 +1779,7 @@ impl FigureMgr {
|
||||
&target_base,
|
||||
(
|
||||
ability_id,
|
||||
s.stage_section,
|
||||
Some(s.stage_section),
|
||||
Some(s.static_data.ability_info),
|
||||
current_strike,
|
||||
move_dir,
|
||||
@ -1797,7 +1788,9 @@ impl FigureMgr {
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
} else if physics.in_liquid().is_some() {
|
||||
},
|
||||
CharacterState::BasicStance(_) => {
|
||||
if physics.in_liquid().is_some() {
|
||||
anim::character::SwimWieldAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(
|
||||
@ -1811,25 +1804,6 @@ impl FigureMgr {
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
} else if false {
|
||||
// Check for sneaking here if we want combo melee 2 to be able to
|
||||
// sneak when not actively swinging
|
||||
anim::character::SneakWieldAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(
|
||||
(active_tool_kind, active_tool_spec),
|
||||
second_tool_kind,
|
||||
hands,
|
||||
rel_vel,
|
||||
// TODO: Update to use the quaternion.
|
||||
ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||
state.last_ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||
time,
|
||||
),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
} else {
|
||||
anim::character::WieldAnimation::update_skeleton(
|
||||
&target_base,
|
||||
|
Loading…
Reference in New Issue
Block a user