From 0c9f05b8d1b0bb315dcfc7cb10fa91770a774b4b Mon Sep 17 00:00:00 2001 From: juliancoffee Date: Tue, 8 Jun 2021 00:58:05 +0300 Subject: [PATCH] Load skillsets from assets Done: support loading from assets in skillset_builder.rs entity_config field with skillset asset field move every SkillSet config to assets tests for skillset assets tests for assets in entity configs --- assets/common/entity/dungeon/tier-0/bow.ron | 3 +- assets/common/entity/dungeon/tier-0/spear.ron | 3 +- assets/common/entity/dungeon/tier-0/staff.ron | 3 +- assets/common/entity/dungeon/tier-1/bow.ron | 3 +- assets/common/entity/dungeon/tier-1/spear.ron | 3 +- assets/common/entity/dungeon/tier-1/staff.ron | 3 +- assets/common/entity/dungeon/tier-2/bow.ron | 3 +- assets/common/entity/dungeon/tier-2/spear.ron | 3 +- assets/common/entity/dungeon/tier-2/staff.ron | 3 +- assets/common/entity/dungeon/tier-3/bow.ron | 3 +- assets/common/entity/dungeon/tier-3/spear.ron | 3 +- assets/common/entity/dungeon/tier-3/staff.ron | 3 +- assets/common/entity/dungeon/tier-4/bow.ron | 3 +- assets/common/entity/dungeon/tier-4/spear.ron | 3 +- assets/common/entity/dungeon/tier-4/staff.ron | 3 +- .../entity/dungeon/tier-5/beastmaster.ron | 4 +- assets/common/entity/dungeon/tier-5/boss.ron | 9 + assets/common/entity/dungeon/tier-5/husk.ron | 3 +- .../common/entity/dungeon/tier-5/warlock.ron | 3 +- .../common/entity/dungeon/tier-5/warlord.ron | 3 +- assets/common/entity/test.ron | 6 +- assets/common/entity/village/guard.ron | 9 + assets/common/entity/village/merchant.ron | 9 + assets/common/entity/village/villager.ron | 16 + assets/common/loadout/world/traveler.ron | 2 +- assets/common/skillset/dungeon/tier-0/bow.ron | 12 + assets/common/skillset/dungeon/tier-1/bow.ron | 12 + assets/common/skillset/dungeon/tier-2/bow.ron | 12 + assets/common/skillset/dungeon/tier-3/bow.ron | 12 + assets/common/skillset/dungeon/tier-4/bow.ron | 12 + assets/common/skillset/dungeon/tier-5/axe.ron | 21 + assets/common/skillset/dungeon/tier-5/bow.ron | 21 + .../common/skillset/dungeon/tier-5/enemy.ron | 8 + .../common/skillset/dungeon/tier-5/hammer.ron | 21 + .../skillset/dungeon/tier-5/mindflayer.ron | 21 + .../common/skillset/dungeon/tier-5/staff.ron | 21 + .../common/skillset/dungeon/tier-5/sword.ron | 19 + assets/common/skillset/village/guard.ron | 24 + assets/common/skillset/village/merchant.ron | 17 + common/base/src/lib.rs | 21 + common/src/comp/inventory/loadout_builder.rs | 30 +- common/src/generation.rs | 72 +- common/src/skillset_builder.rs | 817 +++--------------- common/src/states/basic_summon.rs | 41 +- server/src/sys/terrain.rs | 57 +- world/src/site/dungeon/mod.rs | 13 +- world/src/site/settlement/mod.rs | 32 +- 47 files changed, 585 insertions(+), 840 deletions(-) create mode 100644 assets/common/entity/dungeon/tier-5/boss.ron create mode 100644 assets/common/entity/village/guard.ron create mode 100644 assets/common/entity/village/merchant.ron create mode 100644 assets/common/entity/village/villager.ron create mode 100644 assets/common/skillset/dungeon/tier-0/bow.ron create mode 100644 assets/common/skillset/dungeon/tier-1/bow.ron create mode 100644 assets/common/skillset/dungeon/tier-2/bow.ron create mode 100644 assets/common/skillset/dungeon/tier-3/bow.ron create mode 100644 assets/common/skillset/dungeon/tier-4/bow.ron create mode 100644 assets/common/skillset/dungeon/tier-5/axe.ron create mode 100644 assets/common/skillset/dungeon/tier-5/bow.ron create mode 100644 assets/common/skillset/dungeon/tier-5/enemy.ron create mode 100644 assets/common/skillset/dungeon/tier-5/hammer.ron create mode 100644 assets/common/skillset/dungeon/tier-5/mindflayer.ron create mode 100644 assets/common/skillset/dungeon/tier-5/staff.ron create mode 100644 assets/common/skillset/dungeon/tier-5/sword.ron create mode 100644 assets/common/skillset/village/guard.ron create mode 100644 assets/common/skillset/village/merchant.ron diff --git a/assets/common/entity/dungeon/tier-0/bow.ron b/assets/common/entity/dungeon/tier-0/bow.ron index 0ba5a289d6..e135808266 100644 --- a/assets/common/entity/dungeon/tier-0/bow.ron +++ b/assets/common/entity/dungeon/tier-0/bow.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.gnarling.adlet_bow")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-0.gnarling"), + loadout_asset: Some("common.loadout.dungeon.tier-0.gnarling"), + skillset_asset: Some("common.skillset.dungeon.tier-0.bow"), ) diff --git a/assets/common/entity/dungeon/tier-0/spear.ron b/assets/common/entity/dungeon/tier-0/spear.ron index ffc2e9cf4f..72c3b46fa3 100644 --- a/assets/common/entity/dungeon/tier-0/spear.ron +++ b/assets/common/entity/dungeon/tier-0/spear.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.gnarling.wooden_spear")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-0.gnarling"), + loadout_asset: Some("common.loadout.dungeon.tier-0.gnarling"), + skillset_asset: None, ) diff --git a/assets/common/entity/dungeon/tier-0/staff.ron b/assets/common/entity/dungeon/tier-0/staff.ron index b0b6a7a751..d8928f39fe 100644 --- a/assets/common/entity/dungeon/tier-0/staff.ron +++ b/assets/common/entity/dungeon/tier-0/staff.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.gnarling.gnoll_staff")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-0.gnarling"), + loadout_asset: Some("common.loadout.dungeon.tier-0.gnarling"), + skillset_asset: None, ) diff --git a/assets/common/entity/dungeon/tier-1/bow.ron b/assets/common/entity/dungeon/tier-1/bow.ron index fde472fdb5..e7ea1ed0dc 100644 --- a/assets/common/entity/dungeon/tier-1/bow.ron +++ b/assets/common/entity/dungeon/tier-1/bow.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.adlet.adlet_bow")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-1.adlet_bow"), + loadout_asset: Some("common.loadout.dungeon.tier-1.adlet_bow"), + skillset_asset: Some("common.skillset.dungeon.tier-1.bow"), ) diff --git a/assets/common/entity/dungeon/tier-1/spear.ron b/assets/common/entity/dungeon/tier-1/spear.ron index 48a07585be..0f2d3322e5 100644 --- a/assets/common/entity/dungeon/tier-1/spear.ron +++ b/assets/common/entity/dungeon/tier-1/spear.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.adlet.wooden_spear")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-1.adlet_spear"), + loadout_asset: Some("common.loadout.dungeon.tier-1.adlet_spear"), + skillset_asset: None, ) diff --git a/assets/common/entity/dungeon/tier-1/staff.ron b/assets/common/entity/dungeon/tier-1/staff.ron index 820c12436c..522ec1d415 100644 --- a/assets/common/entity/dungeon/tier-1/staff.ron +++ b/assets/common/entity/dungeon/tier-1/staff.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.adlet.gnoll_staff")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-1.adlet_spear"), + loadout_asset: Some("common.loadout.dungeon.tier-1.adlet_spear"), + skillset_asset: None, ) diff --git a/assets/common/entity/dungeon/tier-2/bow.ron b/assets/common/entity/dungeon/tier-2/bow.ron index 8ea21fa08c..73950982ee 100644 --- a/assets/common/entity/dungeon/tier-2/bow.ron +++ b/assets/common/entity/dungeon/tier-2/bow.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.sahagin.adlet_bow")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-2.sahagin"), + loadout_asset: Some("common.loadout.dungeon.tier-2.sahagin"), + skillset_asset: Some("common.skillset.dungeon.tier-2.bow"), ) diff --git a/assets/common/entity/dungeon/tier-2/spear.ron b/assets/common/entity/dungeon/tier-2/spear.ron index bd8d7c9e4e..c9499cfa47 100644 --- a/assets/common/entity/dungeon/tier-2/spear.ron +++ b/assets/common/entity/dungeon/tier-2/spear.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.sahagin.wooden_spear")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-2.sahagin"), + loadout_asset: Some("common.loadout.dungeon.tier-2.sahagin"), + skillset_asset: None, ) diff --git a/assets/common/entity/dungeon/tier-2/staff.ron b/assets/common/entity/dungeon/tier-2/staff.ron index 73cb84ee55..4ecbcd121e 100644 --- a/assets/common/entity/dungeon/tier-2/staff.ron +++ b/assets/common/entity/dungeon/tier-2/staff.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.sahagin.gnoll_staff")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-2.sahagin"), + loadout_asset: Some("common.loadout.dungeon.tier-2.sahagin"), + skillset_asset: None, ) diff --git a/assets/common/entity/dungeon/tier-3/bow.ron b/assets/common/entity/dungeon/tier-3/bow.ron index d1a9d98924..e642c37333 100644 --- a/assets/common/entity/dungeon/tier-3/bow.ron +++ b/assets/common/entity/dungeon/tier-3/bow.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.haniwa.adlet_bow")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-3.haniwa"), + loadout_asset: Some("common.loadout.dungeon.tier-3.haniwa"), + skillset_asset: Some("common.skillset.dungeon.tier-3.bow"), ) diff --git a/assets/common/entity/dungeon/tier-3/spear.ron b/assets/common/entity/dungeon/tier-3/spear.ron index 5e303990af..4c107bdd73 100644 --- a/assets/common/entity/dungeon/tier-3/spear.ron +++ b/assets/common/entity/dungeon/tier-3/spear.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.haniwa.wooden_spear")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-3.haniwa"), + loadout_asset: Some("common.loadout.dungeon.tier-3.haniwa"), + skillset_asset: None, ) diff --git a/assets/common/entity/dungeon/tier-3/staff.ron b/assets/common/entity/dungeon/tier-3/staff.ron index ef130792c0..adfe8857e8 100644 --- a/assets/common/entity/dungeon/tier-3/staff.ron +++ b/assets/common/entity/dungeon/tier-3/staff.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.haniwa.gnoll_staff")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-3.haniwa"), + loadout_asset: Some("common.loadout.dungeon.tier-3.haniwa"), + skillset_asset: None, ) diff --git a/assets/common/entity/dungeon/tier-4/bow.ron b/assets/common/entity/dungeon/tier-4/bow.ron index 7a9006fb5a..04cf0e7b02 100644 --- a/assets/common/entity/dungeon/tier-4/bow.ron +++ b/assets/common/entity/dungeon/tier-4/bow.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.myrmidon.adlet_bow")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-4.myrmidon"), + loadout_asset: Some("common.loadout.dungeon.tier-4.myrmidon"), + skillset_asset: Some("common.skillset.dungeon.tier-4.bow"), ) diff --git a/assets/common/entity/dungeon/tier-4/spear.ron b/assets/common/entity/dungeon/tier-4/spear.ron index 3ae610eb7e..d73950e575 100644 --- a/assets/common/entity/dungeon/tier-4/spear.ron +++ b/assets/common/entity/dungeon/tier-4/spear.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.myrmidon.wooden_spear")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-4.myrmidon"), + loadout_asset: Some("common.loadout.dungeon.tier-4.myrmidon"), + skillset_asset: None, ) diff --git a/assets/common/entity/dungeon/tier-4/staff.ron b/assets/common/entity/dungeon/tier-4/staff.ron index 23d0521872..a022a4b330 100644 --- a/assets/common/entity/dungeon/tier-4/staff.ron +++ b/assets/common/entity/dungeon/tier-4/staff.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.npc_weapons.biped_small.myrmidon.gnoll_staff")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-4.myrmidon"), + loadout_asset: Some("common.loadout.dungeon.tier-4.myrmidon"), + skillset_asset: None, ) diff --git a/assets/common/entity/dungeon/tier-5/beastmaster.ron b/assets/common/entity/dungeon/tier-5/beastmaster.ron index c34e9bc99e..4c2421ac72 100644 --- a/assets/common/entity/dungeon/tier-5/beastmaster.ron +++ b/assets/common/entity/dungeon/tier-5/beastmaster.ron @@ -8,5 +8,7 @@ EntityConfig ( ])), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-5.beastmaster"), + loadout_asset: Some("common.loadout.dungeon.tier-5.beastmaster"), + // TODO: make skillset for him, I'm just too lazy + skillset_asset: Some("common.skillset.dungeon.tier-5.enemy"), ) diff --git a/assets/common/entity/dungeon/tier-5/boss.ron b/assets/common/entity/dungeon/tier-5/boss.ron new file mode 100644 index 0000000000..042951cee6 --- /dev/null +++ b/assets/common/entity/dungeon/tier-5/boss.ron @@ -0,0 +1,9 @@ +EntityConfig ( + name: Some("Mindflayer"), + + main_tool: None, + second_tool: None, + + loadout_asset: None, + skillset_asset: Some("common.skillset.dungeon.tier-5.mindflayer"), +) diff --git a/assets/common/entity/dungeon/tier-5/husk.ron b/assets/common/entity/dungeon/tier-5/husk.ron index 4e8bd6d35b..6c23289a44 100644 --- a/assets/common/entity/dungeon/tier-5/husk.ron +++ b/assets/common/entity/dungeon/tier-5/husk.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: None, second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-5.husk"), + loadout_asset: Some("common.loadout.dungeon.tier-5.husk"), + skillset_asset: None, ) diff --git a/assets/common/entity/dungeon/tier-5/warlock.ron b/assets/common/entity/dungeon/tier-5/warlock.ron index f151381032..8e5fe4ae70 100644 --- a/assets/common/entity/dungeon/tier-5/warlock.ron +++ b/assets/common/entity/dungeon/tier-5/warlock.ron @@ -4,5 +4,6 @@ EntityConfig ( main_tool: Some(Item("common.items.weapons.staff.cultist_staff")), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-5.warlock"), + loadout_asset: Some("common.loadout.dungeon.tier-5.warlock"), + skillset_asset: Some("common.skillset.dungeon.tier-5.enemy"), ) diff --git a/assets/common/entity/dungeon/tier-5/warlord.ron b/assets/common/entity/dungeon/tier-5/warlord.ron index 8369c3f29c..37430fc373 100644 --- a/assets/common/entity/dungeon/tier-5/warlord.ron +++ b/assets/common/entity/dungeon/tier-5/warlord.ron @@ -10,5 +10,6 @@ EntityConfig ( ])), second_tool: None, - loadout_config: Some("common.loadout.dungeon.tier-5.warlord"), + loadout_asset: Some("common.loadout.dungeon.tier-5.warlord"), + skillset_asset: Some("common.skillset.dungeon.tier-5.enemy"), ) diff --git a/assets/common/entity/test.ron b/assets/common/entity/test.ron index 040cc162b2..915f98ade2 100644 --- a/assets/common/entity/test.ron +++ b/assets/common/entity/test.ron @@ -16,10 +16,10 @@ EntityConfig ( second_tool: None, /// Loadout Config (with asset_specifier for loadout) - loadout_config: Some("common.loadout.village.merchant"), + loadout_asset: Some("common.loadout.village.merchant"), - /// Skillset Config as Option (with asset_specifier for skillset) - // skillset_config: None, + /// Skillset Config (with asset_specifier for skillset) + skillset_asset: Some("common.skillset.village.merchant"), /// Loot /// Can be Item (with asset_specifier for item) diff --git a/assets/common/entity/village/guard.ron b/assets/common/entity/village/guard.ron new file mode 100644 index 0000000000..93d770cb2c --- /dev/null +++ b/assets/common/entity/village/guard.ron @@ -0,0 +1,9 @@ +EntityConfig ( + name: Some("Guard"), + + main_tool: Some(Item("common.items.weapons.sword.iron-4")), + second_tool: None, + + loadout_asset: None, + skillset_asset: Some("common.skillset.village.guard"), +) diff --git a/assets/common/entity/village/merchant.ron b/assets/common/entity/village/merchant.ron new file mode 100644 index 0000000000..07dd497fdf --- /dev/null +++ b/assets/common/entity/village/merchant.ron @@ -0,0 +1,9 @@ +EntityConfig ( + name: Some("Merchant"), + + main_tool: Some(Item("common.items.weapons.bow.eldwood-0")), + second_tool: None, + + loadout_asset: None, + skillset_asset: Some("common.skillset.village.merchant"), +) diff --git a/assets/common/entity/village/villager.ron b/assets/common/entity/village/villager.ron new file mode 100644 index 0000000000..45a92d5abb --- /dev/null +++ b/assets/common/entity/village/villager.ron @@ -0,0 +1,16 @@ +EntityConfig ( + name: None, + + main_tool: Some(Choice([ + (1.0, Some(Item("common.items.weapons.tool.broom"))), + (1.0, Some(Item("common.items.weapons.tool.hoe"))), + (1.0, Some(Item("common.items.weapons.tool.pickaxe"))), + (1.0, Some(Item("common.items.weapons.tool.rake"))), + (1.0, Some(Item("common.items.weapons.tool.shovel-0"))), + (1.0, Some(Item("common.items.weapons.tool.shovel-1"))), + ])), + second_tool: None, + + loadout_asset: None, + skillset_asset: None, +) diff --git a/assets/common/loadout/world/traveler.ron b/assets/common/loadout/world/traveler.ron index c2126e5496..2a38bafaef 100644 --- a/assets/common/loadout/world/traveler.ron +++ b/assets/common/loadout/world/traveler.ron @@ -9,7 +9,7 @@ Armor(Chest): Item("common.items.npc_armor.chest.leather_blue"), Armor(Legs): Item("common.items.npc_armor.pants.leather_blue"), - Armor(Shoulders): Item("common.items.armor.swift.shoulder"), + Armor(Shoulders): Item("common.items.armor.hide.leather.shoulder"), Armor(Back): Choice([ (1.0, Some(Item("common.items.armor.hide.rawhide.back"))), diff --git a/assets/common/skillset/dungeon/tier-0/bow.ron b/assets/common/skillset/dungeon/tier-0/bow.ron new file mode 100644 index 0000000000..5a99b61b66 --- /dev/null +++ b/assets/common/skillset/dungeon/tier-0/bow.ron @@ -0,0 +1,12 @@ +([ + Group(Weapon(Bow)), + + // Charged + Skill((Bow(CDamage), Some(1))), + Skill((Bow(CKnockback), Some(1))), + Skill((Bow(CSpeed), Some(1))), + Skill((Bow(CMove), Some(1))), + + // Repeater + Skill((Bow(RDamage), Some(1))), +]) diff --git a/assets/common/skillset/dungeon/tier-1/bow.ron b/assets/common/skillset/dungeon/tier-1/bow.ron new file mode 100644 index 0000000000..5a99b61b66 --- /dev/null +++ b/assets/common/skillset/dungeon/tier-1/bow.ron @@ -0,0 +1,12 @@ +([ + Group(Weapon(Bow)), + + // Charged + Skill((Bow(CDamage), Some(1))), + Skill((Bow(CKnockback), Some(1))), + Skill((Bow(CSpeed), Some(1))), + Skill((Bow(CMove), Some(1))), + + // Repeater + Skill((Bow(RDamage), Some(1))), +]) diff --git a/assets/common/skillset/dungeon/tier-2/bow.ron b/assets/common/skillset/dungeon/tier-2/bow.ron new file mode 100644 index 0000000000..5a99b61b66 --- /dev/null +++ b/assets/common/skillset/dungeon/tier-2/bow.ron @@ -0,0 +1,12 @@ +([ + Group(Weapon(Bow)), + + // Charged + Skill((Bow(CDamage), Some(1))), + Skill((Bow(CKnockback), Some(1))), + Skill((Bow(CSpeed), Some(1))), + Skill((Bow(CMove), Some(1))), + + // Repeater + Skill((Bow(RDamage), Some(1))), +]) diff --git a/assets/common/skillset/dungeon/tier-3/bow.ron b/assets/common/skillset/dungeon/tier-3/bow.ron new file mode 100644 index 0000000000..5a99b61b66 --- /dev/null +++ b/assets/common/skillset/dungeon/tier-3/bow.ron @@ -0,0 +1,12 @@ +([ + Group(Weapon(Bow)), + + // Charged + Skill((Bow(CDamage), Some(1))), + Skill((Bow(CKnockback), Some(1))), + Skill((Bow(CSpeed), Some(1))), + Skill((Bow(CMove), Some(1))), + + // Repeater + Skill((Bow(RDamage), Some(1))), +]) diff --git a/assets/common/skillset/dungeon/tier-4/bow.ron b/assets/common/skillset/dungeon/tier-4/bow.ron new file mode 100644 index 0000000000..5a99b61b66 --- /dev/null +++ b/assets/common/skillset/dungeon/tier-4/bow.ron @@ -0,0 +1,12 @@ +([ + Group(Weapon(Bow)), + + // Charged + Skill((Bow(CDamage), Some(1))), + Skill((Bow(CKnockback), Some(1))), + Skill((Bow(CSpeed), Some(1))), + Skill((Bow(CMove), Some(1))), + + // Repeater + Skill((Bow(RDamage), Some(1))), +]) diff --git a/assets/common/skillset/dungeon/tier-5/axe.ron b/assets/common/skillset/dungeon/tier-5/axe.ron new file mode 100644 index 0000000000..abfcaae590 --- /dev/null +++ b/assets/common/skillset/dungeon/tier-5/axe.ron @@ -0,0 +1,21 @@ +([ + Group(Weapon(Axe)), + + // DoubleStrike + Skill((Axe(DsCombo), None)), + Skill((Axe(DsDamage), Some(1))), + Skill((Axe(DsSpeed), Some(1))), + Skill((Axe(DsRegen), Some(1))), + + // Spin + Skill((Axe(SInfinite), None)), + Skill((Axe(SHelicopter), None)), + Skill((Axe(SDamage), Some(1))), + Skill((Axe(SSpeed), Some(1))), + + // Leap + Skill((Axe(UnlockLeap), None)), + Skill((Axe(LDamage), Some(1))), + Skill((Axe(LKnockback), Some(1))), + Skill((Axe(LDistance), Some(1))), +]) diff --git a/assets/common/skillset/dungeon/tier-5/bow.ron b/assets/common/skillset/dungeon/tier-5/bow.ron new file mode 100644 index 0000000000..a1cd8b0def --- /dev/null +++ b/assets/common/skillset/dungeon/tier-5/bow.ron @@ -0,0 +1,21 @@ +([ + Group(Weapon(Bow)), + + // Charged + Skill((Bow(CDamage), Some(1))), + Skill((Bow(CRegen), Some(1))), + Skill((Bow(CKnockback), Some(1))), + Skill((Bow(CSpeed), Some(1))), + Skill((Bow(CMove), Some(1))), + + // Repeater + Skill((Bow(RDamage), Some(1))), + Skill((Bow(RSpeed), Some(1))), + + // Shotgun + Skill((Bow(UnlockShotgun), None)), + Skill((Bow(SDamage), Some(1))), + Skill((Bow(SSpread), Some(1))), + Skill((Bow(SArrows), Some(1))), + Skill((Bow(SCost), Some(1))), +]) diff --git a/assets/common/skillset/dungeon/tier-5/enemy.ron b/assets/common/skillset/dungeon/tier-5/enemy.ron new file mode 100644 index 0000000000..0e5ff1c8e5 --- /dev/null +++ b/assets/common/skillset/dungeon/tier-5/enemy.ron @@ -0,0 +1,8 @@ +([ + // Just gather everything + Tree("common.skillset.dungeon.tier-5.sword"), + Tree("common.skillset.dungeon.tier-5.axe"), + Tree("common.skillset.dungeon.tier-5.hammer"), + Tree("common.skillset.dungeon.tier-5.bow"), + Tree("common.skillset.dungeon.tier-5.staff"), +]) diff --git a/assets/common/skillset/dungeon/tier-5/hammer.ron b/assets/common/skillset/dungeon/tier-5/hammer.ron new file mode 100644 index 0000000000..5f0e7561a3 --- /dev/null +++ b/assets/common/skillset/dungeon/tier-5/hammer.ron @@ -0,0 +1,21 @@ +([ + Group(Weapon(Hammer)), + + // Single Strike, as single as you are + Skill((Hammer(SsKnockback), Some(1))), + Skill((Hammer(SsDamage), Some(1))), + Skill((Hammer(SsSpeed), Some(1))), + Skill((Hammer(SsRegen), Some(1))), + + // Charged + Skill((Hammer(CKnockback), Some(1))), + Skill((Hammer(CDamage), Some(1))), + Skill((Hammer(CDrain), Some(1))), + + // Leap + Skill((Hammer(UnlockLeap), None)), + Skill((Hammer(LDamage), Some(1))), + Skill((Hammer(LDistance), Some(1))), + Skill((Hammer(LKnockback), Some(1))), + Skill((Hammer(LRange), Some(1))), +]) diff --git a/assets/common/skillset/dungeon/tier-5/mindflayer.ron b/assets/common/skillset/dungeon/tier-5/mindflayer.ron new file mode 100644 index 0000000000..09cba3e4bd --- /dev/null +++ b/assets/common/skillset/dungeon/tier-5/mindflayer.ron @@ -0,0 +1,21 @@ +([ + Group(Weapon(Staff)), + + // Fireball + Skill((Staff(BDamage), Some(3))), + Skill((Staff(BRegen), Some(2))), + Skill((Staff(BRadius), Some(2))), + + // Flamethrower + Skill((Staff(FDamage), Some(3))), + Skill((Staff(FRange), Some(2))), + Skill((Staff(FDrain), Some(2))), + Skill((Staff(FVelocity), Some(2))), + + // Shockwave + Skill((Staff(UnlockShockwave), None)), + Skill((Staff(SDamage), Some(2))), + Skill((Staff(SKnockback), Some(2))), + Skill((Staff(SRange), Some(2))), + Skill((Staff(SCost), Some(2))), +]) diff --git a/assets/common/skillset/dungeon/tier-5/staff.ron b/assets/common/skillset/dungeon/tier-5/staff.ron new file mode 100644 index 0000000000..4c3dc1af3a --- /dev/null +++ b/assets/common/skillset/dungeon/tier-5/staff.ron @@ -0,0 +1,21 @@ +([ + Group(Weapon(Staff)), + + // Fireball + Skill((Staff(BDamage), Some(1))), + Skill((Staff(BRegen), Some(1))), + Skill((Staff(BRadius), Some(1))), + + // Flamethrower + Skill((Staff(FRange), Some(1))), + Skill((Staff(FDrain), Some(1))), + Skill((Staff(FDamage), Some(1))), + Skill((Staff(FVelocity), Some(1))), + + // Shockwave + Skill((Staff(UnlockShockwave), None)), + Skill((Staff(SDamage), Some(1))), + Skill((Staff(SKnockback), Some(1))), + Skill((Staff(SRange), Some(1))), + Skill((Staff(SCost), Some(1))), +]) diff --git a/assets/common/skillset/dungeon/tier-5/sword.ron b/assets/common/skillset/dungeon/tier-5/sword.ron new file mode 100644 index 0000000000..2f945fc42f --- /dev/null +++ b/assets/common/skillset/dungeon/tier-5/sword.ron @@ -0,0 +1,19 @@ +([ + Group(Weapon(Sword)), + + // TripleStrike + Skill((Sword(TsCombo), None)), + Skill((Sword(TsDamage), Some(1))), + Skill((Sword(TsRegen), Some(1))), + + // Dash + Skill((Sword(DDamage), Some(1))), + Skill((Sword(DCost), Some(1))), + Skill((Sword(DDrain), Some(1))), + + // Spin of death + Skill((Sword(UnlockSpin), None)), + Skill((Sword(SDamage), Some(1))), + Skill((Sword(SSpins), Some(2))), + Skill((Sword(SCost), Some(1))), +]) diff --git a/assets/common/skillset/village/guard.ron b/assets/common/skillset/village/guard.ron new file mode 100644 index 0000000000..ad041b0f2d --- /dev/null +++ b/assets/common/skillset/village/guard.ron @@ -0,0 +1,24 @@ +([ + Group(Weapon(Sword)), + + // TripleStrike + Skill((Sword(TsCombo), None)), + Skill((Sword(TsDamage), Some(1))), + Skill((Sword(TsRegen), Some(1))), + Skill((Sword(TsSpeed), Some(1))), + + // Dash + Skill((Sword(DDamage), Some(1))), + Skill((Sword(DCost), Some(1))), + Skill((Sword(DDrain), Some(1))), + Skill((Sword(DScaling), Some(1))), + Skill((Sword(DSpeed), None)), + Skill((Sword(DInfinite), None)), + + // Spin of death + Skill((Sword(UnlockSpin), None)), + Skill((Sword(SDamage), Some(1))), + Skill((Sword(SSpeed), Some(1))), + Skill((Sword(SSpins), Some(2))), + Skill((Sword(SCost), Some(1))), +]) diff --git a/assets/common/skillset/village/merchant.ron b/assets/common/skillset/village/merchant.ron new file mode 100644 index 0000000000..06355a4ff4 --- /dev/null +++ b/assets/common/skillset/village/merchant.ron @@ -0,0 +1,17 @@ +([ + Group(Weapon(Bow)), + + // Charged + Skill((Bow(CDamage), Some(1))), + Skill((Bow(CRegen), Some(1))), + Skill((Bow(CKnockback), Some(1))), + Skill((Bow(CSpeed), Some(1))), + + // Repeater + Skill((Bow(RDamage), Some(1))), + Skill((Bow(RCost), Some(1))), + + // Shotgun + Skill((Bow(UnlockShotgun), None)), + Skill((Bow(SCost), Some(1))), +]) diff --git a/common/base/src/lib.rs b/common/base/src/lib.rs index 3325612858..d05b952127 100644 --- a/common/base/src/lib.rs +++ b/common/base/src/lib.rs @@ -23,6 +23,27 @@ macro_rules! plot { }; } +// Panic in debug or tests, warn in release +#[macro_export] +macro_rules! dev_panic { + ($msg:expr) => { + if cfg!(any(debug_assertions, test)) { + panic!("{}", $msg); + } else { + tracing::warn!("{}", $msg); + } + }; + + ($msg:expr, or return $result:expr) => { + if cfg!(any(debug_assertions, test)) { + panic!("{}", $msg); + } else { + tracing::warn!("{}", $msg); + return $result; + } + }; +} + // https://discordapp.com/channels/676678179678715904/676685797524766720/723358438943621151 #[macro_export] macro_rules! span { diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index a2d7a12a25..eb8fc67148 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -45,6 +45,14 @@ pub enum Preset { HuskSummon, } +#[derive(Debug, Deserialize, Clone)] +pub struct LoadoutSpec(HashMap); +impl assets::Asset for LoadoutSpec { + type Loader = assets::RonLoader; + + const EXTENSION: &'static str = "ron"; +} + #[derive(Debug, Deserialize, Clone)] pub enum ItemSpec { /// One specific item. @@ -112,35 +120,17 @@ fn choose<'a>( WeightedError::NoItem | WeightedError::AllWeightsZero => &None, WeightedError::InvalidWeight => { let err = format!("Negative values of probability in {}.", asset_specifier); - if cfg!(any(debug_assertions, test)) { - panic!("{}", err); - } else { - warn!("{}", err); - &None - } + common_base::dev_panic!(err, or return &None) }, WeightedError::TooMany => { let err = format!("More than u32::MAX values in {}.", asset_specifier); - if cfg!(any(debug_assertions, test)) { - panic!("{}", err); - } else { - warn!("{}", err); - &None - } + common_base::dev_panic!(err, or return &None) }, }, |(_p, itemspec)| itemspec, ) } -#[derive(Debug, Deserialize, Clone)] -pub struct LoadoutSpec(HashMap); -impl assets::Asset for LoadoutSpec { - type Loader = assets::RonLoader; - - const EXTENSION: &'static str = "ron"; -} - #[must_use] pub fn make_potion_bag(quantity: u32) -> Item { let mut bag = Item::new_from_asset_expect("common.items.armor.misc.bag.tiny_leather_pouch"); diff --git a/common/src/generation.rs b/common/src/generation.rs index 4cf13c361e..f31aa7628e 100644 --- a/common/src/generation.rs +++ b/common/src/generation.rs @@ -6,7 +6,6 @@ use crate::{ Alignment, Body, Item, }, npc::{self, NPC_NAMES}, - skillset_builder::SkillSetConfig, trade, trade::SiteInformation, }; @@ -18,7 +17,8 @@ struct EntityConfig { name: Option, main_tool: Option, second_tool: Option, - loadout_config: Option, + loadout_asset: Option, + skillset_asset: Option, } impl assets::Asset for EntityConfig { @@ -43,10 +43,9 @@ pub struct EntityInfo { // TODO: Properly give NPCs skills pub level: Option, pub loot_drop: Option, - pub loadout_config: Option, + pub loadout_asset: Option, pub make_loadout: Option) -> LoadoutBuilder>, - pub skillset_config: Option, - pub skillset_preset: Option, + pub skillset_asset: Option, pub pet: Option>, // we can't use DHashMap, do we want to move that into common? pub trading_information: Option, @@ -69,10 +68,9 @@ impl EntityInfo { scale: 1.0, level: None, loot_drop: None, - loadout_config: None, + loadout_asset: None, make_loadout: None, - skillset_config: None, - skillset_preset: None, + skillset_asset: None, pet: None, trading_information: None, } @@ -90,7 +88,8 @@ impl EntityInfo { name, main_tool, second_tool, - loadout_config, + loadout_asset, + skillset_asset, } = config; if let Some(name) = name { @@ -109,8 +108,12 @@ impl EntityInfo { self = self.with_main_tool(second_tool); } - if let Some(loadout_config) = loadout_config { - self = self.with_loadout_config(loadout_config); + if let Some(loadout_asset) = loadout_asset { + self = self.with_loadout_asset(loadout_asset); + } + + if let Some(skillset_asset) = skillset_asset { + self = self.with_skillset_asset(skillset_asset); } self @@ -183,8 +186,8 @@ impl EntityInfo { self } - pub fn with_loadout_config(mut self, config: String) -> Self { - self.loadout_config = Some(config); + pub fn with_loadout_asset(mut self, asset: String) -> Self { + self.loadout_asset = Some(asset); self } @@ -196,15 +199,8 @@ impl EntityInfo { self } - pub fn with_skillset_preset(mut self, preset: SkillSetConfig) -> Self { - self.skillset_preset = Some(preset); - self - } - - // FIXME: Doesn't work for now, because skills can't be loaded from assets for - // now - pub fn with_skillset_config(mut self, config: String) -> Self { - self.skillset_config = Some(config); + pub fn with_skillset_asset(mut self, asset: String) -> Self { + self.skillset_asset = Some(asset); self } @@ -269,6 +265,7 @@ pub fn get_npc_name< #[cfg(test)] mod tests { use super::*; + use crate::{comp::inventory::slot::EquipSlot, SkillSetBuilder}; use assets::Error; #[test] @@ -292,12 +289,35 @@ mod tests { } // It just load everything that could - // TODO: add some checks, e.g. that Armor(Head) key correspond - // to Item with ItemKind Head(_) let entity_configs = EntityList::load_expect_cloned("common.entity.*").0; for config in entity_configs { - let pos = Vec3::new(0.0, 0.0, 0.0); - std::mem::drop(EntityInfo::at(pos).with_entity_config(config, None)); + let EntityConfig { + main_tool, + second_tool, + loadout_asset, + skillset_asset, + .. + } = config; + + if let Some(main_tool) = main_tool { + main_tool.validate(EquipSlot::ActiveMainhand); + } + + if let Some(second_tool) = second_tool { + second_tool.validate(EquipSlot::ActiveOffhand); + } + + if let Some(loadout_asset) = loadout_asset { + let rng = &mut rand::thread_rng(); + let builder = LoadoutBuilder::default(); + // we need to just load it check if it exists, + // because all loadouts are tested in LoadoutBuilder module + std::mem::drop(builder.with_asset_expect(&loadout_asset, rng)); + } + + if let Some(skillset_asset) = skillset_asset { + std::mem::drop(SkillSetBuilder::from_asset_expect(&skillset_asset)); + } } } } diff --git a/common/src/skillset_builder.rs b/common/src/skillset_builder.rs index d61ed16be7..8fddd2b7b1 100644 --- a/common/src/skillset_builder.rs +++ b/common/src/skillset_builder.rs @@ -1,30 +1,56 @@ -use crate::comp::{ - item::{tool::ToolKind, Item, ItemKind}, - skills::{ - AxeSkill, BowSkill, HammerSkill, Skill, SkillGroupKind, SkillSet, StaffSkill, SwordSkill, - }, -}; +#![warn(clippy::pedantic)] +//#![warn(clippy::nursery)] +use crate::comp::skills::{Skill, SkillGroupKind, SkillSet}; + +use crate::assets::{self, AssetExt}; use serde::{Deserialize, Serialize}; use tracing::warn; #[derive(Copy, Clone, PartialEq, Serialize, Deserialize, Debug)] -pub enum SkillSetConfig { - Adlet, - Gnarling, - Sahagin, - Haniwa, - Myrmidon, - Guard, - Villager, - Merchant, - Outcast, - Highwayman, - Bandit, - CultistNovice, - CultistAcolyte, - Warlord, - Warlock, - Mindflayer, +pub enum Preset { + Empty, +} + +#[derive(Debug, Deserialize, Clone)] +struct SkillSetTree(Vec); +impl assets::Asset for SkillSetTree { + type Loader = assets::RonLoader; + + const EXTENSION: &'static str = "ron"; +} + +#[derive(Debug, Deserialize, Clone)] +enum SkillNode { + Tree(String), + Skill((Skill, Option)), + Group(SkillGroupKind), +} + +#[must_use] +fn skills_from_asset_expect(asset_specifier: &str) -> Vec<(Skill, Option)> { + let nodes = SkillSetTree::load_expect(asset_specifier).read().0.clone(); + + skills_from_nodes(nodes) +} + +#[must_use] +fn skills_from_nodes(nodes: Vec) -> Vec<(Skill, Option)> { + let mut skills = Vec::new(); + for node in nodes { + match node { + SkillNode::Tree(asset) => { + skills.append(&mut skills_from_asset_expect(&asset)); + }, + SkillNode::Skill(req) => { + skills.push(req); + }, + SkillNode::Group(group) => { + skills.push((Skill::UnlockGroup(group), None)); + }, + } + } + + skills } pub struct SkillSetBuilder(SkillSet); @@ -34,652 +60,40 @@ impl Default for SkillSetBuilder { } impl SkillSetBuilder { - pub fn build_skillset(main_tool: &Option, config: Option) -> Self { - let active_item = main_tool.as_ref().and_then(|ic| { - if let ItemKind::Tool(tool) = &ic.kind() { - Some(tool.kind) - } else { - None - } - }); + /// Creates `SkillSetBuilder` from `asset_specifier` + #[must_use] + pub fn from_asset_expect(asset_specifier: &str) -> Self { + let builder = Self::default(); - use SkillSetConfig::*; - match config { - Some(Adlet) => { - match active_item { - Some(ToolKind::Bow) => { - // Bow - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) - .with_skill(Skill::Bow(BowSkill::CDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::CKnockback), Some(1)) - .with_skill(Skill::Bow(BowSkill::CSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::CMove), Some(1)) - .with_skill(Skill::Bow(BowSkill::RDamage), Some(1)) - }, - _ => Self::default(), - } - }, - Some(Gnarling) => { - match active_item { - Some(ToolKind::Bow) => { - // Bow - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) - .with_skill(Skill::Bow(BowSkill::CDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::CKnockback), Some(1)) - .with_skill(Skill::Bow(BowSkill::CSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::CMove), Some(1)) - .with_skill(Skill::Bow(BowSkill::RDamage), Some(1)) - }, - _ => Self::default(), - } - }, - Some(Sahagin) => { - match active_item { - Some(ToolKind::Bow) => { - // Bow - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) - .with_skill(Skill::Bow(BowSkill::CDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::CKnockback), Some(1)) - .with_skill(Skill::Bow(BowSkill::CSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::CMove), Some(1)) - .with_skill(Skill::Bow(BowSkill::RDamage), Some(1)) - }, - _ => Self::default(), - } - }, - Some(Haniwa) => { - match active_item { - Some(ToolKind::Bow) => { - // Bow - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) - .with_skill(Skill::Bow(BowSkill::CDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::CKnockback), Some(1)) - .with_skill(Skill::Bow(BowSkill::CSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::CMove), Some(1)) - .with_skill(Skill::Bow(BowSkill::RDamage), Some(1)) - }, - _ => Self::default(), - } - }, - Some(Myrmidon) => { - match active_item { - Some(ToolKind::Bow) => { - // Bow - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) - .with_skill(Skill::Bow(BowSkill::CDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::CKnockback), Some(1)) - .with_skill(Skill::Bow(BowSkill::CSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::CMove), Some(1)) - .with_skill(Skill::Bow(BowSkill::RDamage), Some(1)) - }, - _ => Self::default(), - } - }, - Some(Guard) => { - if let Some(ToolKind::Sword) = active_item { - // Sword - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) - .with_skill(Skill::Sword(SwordSkill::TsCombo), None) - .with_skill(Skill::Sword(SwordSkill::TsDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::TsRegen), Some(1)) - .with_skill(Skill::Sword(SwordSkill::TsSpeed), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DCost), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DDrain), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DScaling), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DSpeed), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DInfinite), None) - .with_skill(Skill::Sword(SwordSkill::UnlockSpin), None) - .with_skill(Skill::Sword(SwordSkill::SDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::SSpeed), Some(1)) - .with_skill(Skill::Sword(SwordSkill::SSpins), Some(1)) - .with_skill(Skill::Sword(SwordSkill::SCost), Some(1)) - } else { - Self::default() - } - }, - Some(Outcast) => { - match active_item { - Some(ToolKind::Sword) => { - // Sword - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) - .with_skill(Skill::Sword(SwordSkill::TsCombo), None) - .with_skill(Skill::Sword(SwordSkill::DDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DCost), Some(1)) - }, - Some(ToolKind::Axe) => { - // Axe - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) - .with_skill(Skill::Axe(AxeSkill::DsCombo), None) - .with_skill(Skill::Axe(AxeSkill::SInfinite), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SSpeed), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SCost), Some(1)) - }, - Some(ToolKind::Hammer) => { - // Hammer - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) - .with_skill(Skill::Hammer(HammerSkill::SsKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsSpeed), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CSpeed), Some(1)) - }, - Some(ToolKind::Bow) => { - // Bow - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) - .with_skill(Skill::Bow(BowSkill::ProjSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::CDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::CKnockback), Some(1)) - .with_skill(Skill::Bow(BowSkill::RDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::RSpeed), Some(1)) - }, - Some(ToolKind::Staff) => { - // Staff - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) - .with_skill(Skill::Staff(StaffSkill::FDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FDrain), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FVelocity), Some(1)) - }, - _ => Self::default(), - } - }, - Some(Highwayman) => { - match active_item { - Some(ToolKind::Sword) => { - // Sword - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) - .with_skill(Skill::Sword(SwordSkill::TsCombo), None) - .with_skill(Skill::Sword(SwordSkill::TsDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::UnlockSpin), None) - .with_skill(Skill::Sword(SwordSkill::SSpins), Some(1)) - .with_skill(Skill::Sword(SwordSkill::SCost), Some(1)) - }, - Some(ToolKind::Axe) => { - // Axe - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) - .with_skill(Skill::Axe(AxeSkill::DsCombo), None) - .with_skill(Skill::Axe(AxeSkill::DsDamage), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SInfinite), None) - .with_skill(Skill::Axe(AxeSkill::SDamage), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SSpeed), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SCost), Some(1)) - .with_skill(Skill::Axe(AxeSkill::UnlockLeap), None) - }, - Some(ToolKind::Hammer) => { - // Hammer - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) - .with_skill(Skill::Hammer(HammerSkill::SsKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsSpeed), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::UnlockLeap), None) - .with_skill(Skill::Hammer(HammerSkill::LKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::LRange), Some(1)) - }, - Some(ToolKind::Bow) => { - // Bow - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) - .with_skill(Skill::Bow(BowSkill::CDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::CKnockback), Some(1)) - .with_skill(Skill::Bow(BowSkill::CSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::CMove), Some(1)) - .with_skill(Skill::Bow(BowSkill::RDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::UnlockShotgun), None) - .with_skill(Skill::Bow(BowSkill::SArrows), Some(1)) - }, - Some(ToolKind::Staff) => { - // Staff - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) - .with_skill(Skill::Staff(StaffSkill::BRegen), Some(1)) - .with_skill(Skill::Staff(StaffSkill::BRadius), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FRange), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FVelocity), Some(1)) - .with_skill(Skill::Staff(StaffSkill::UnlockShockwave), None) - }, - _ => Self::default(), - } - }, - Some(Bandit) | Some(Merchant) => { - match active_item { - Some(ToolKind::Sword) => { - // Sword - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) - .with_skill(Skill::Sword(SwordSkill::TsCombo), None) - .with_skill(Skill::Sword(SwordSkill::TsDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DCost), Some(1)) - .with_skill(Skill::Sword(SwordSkill::UnlockSpin), None) - .with_skill(Skill::Sword(SwordSkill::SDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::SSpins), Some(1)) - .with_skill(Skill::Sword(SwordSkill::SCost), Some(1)) - }, - Some(ToolKind::Axe) => { - // Axe - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) - .with_skill(Skill::Axe(AxeSkill::DsCombo), None) - .with_skill(Skill::Axe(AxeSkill::DsSpeed), Some(1)) - .with_skill(Skill::Axe(AxeSkill::DsRegen), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SInfinite), None) - .with_skill(Skill::Axe(AxeSkill::SDamage), Some(1)) - .with_skill(Skill::Axe(AxeSkill::UnlockLeap), None) - .with_skill(Skill::Axe(AxeSkill::LKnockback), Some(1)) - .with_skill(Skill::Axe(AxeSkill::LCost), Some(1)) - .with_skill(Skill::Axe(AxeSkill::LDistance), Some(1)) - }, - Some(ToolKind::Hammer) => { - // Hammer - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) - .with_skill(Skill::Hammer(HammerSkill::SsKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsRegen), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::UnlockLeap), None) - .with_skill(Skill::Hammer(HammerSkill::LDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::LCost), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::LDistance), Some(1)) - }, - Some(ToolKind::Bow) => { - // Bow - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) - .with_skill(Skill::Bow(BowSkill::ProjSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::CDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::CRegen), Some(1)) - .with_skill(Skill::Bow(BowSkill::CSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::RDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::RCost), Some(1)) - .with_skill(Skill::Bow(BowSkill::UnlockShotgun), None) - .with_skill(Skill::Bow(BowSkill::SCost), Some(1)) - .with_skill(Skill::Bow(BowSkill::RCost), Some(1)) - }, - Some(ToolKind::Staff) => { - // Staff - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) - .with_skill(Skill::Staff(StaffSkill::FDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FRange), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FDrain), Some(1)) - .with_skill(Skill::Staff(StaffSkill::UnlockShockwave), None) - .with_skill(Skill::Staff(StaffSkill::SDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::SRange), Some(1)) - }, - _ => Self::default(), - } - }, - Some(CultistNovice) => { - match active_item { - Some(ToolKind::Sword) => { - // Sword - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) - .with_skill(Skill::Sword(SwordSkill::TsCombo), None) - .with_skill(Skill::Sword(SwordSkill::TsRegen), Some(1)) - .with_skill(Skill::Sword(SwordSkill::TsSpeed), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DCost), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DDrain), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DScaling), Some(1)) - .with_skill(Skill::Sword(SwordSkill::UnlockSpin), None) - .with_skill(Skill::Sword(SwordSkill::SSpeed), Some(1)) - .with_skill(Skill::Sword(SwordSkill::SSpins), Some(1)) - .with_skill(Skill::Sword(SwordSkill::SCost), Some(1)) - }, - Some(ToolKind::Axe) => { - // Axe - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) - .with_skill(Skill::Axe(AxeSkill::DsCombo), None) - .with_skill(Skill::Axe(AxeSkill::SInfinite), None) - .with_skill(Skill::Axe(AxeSkill::SHelicopter), None) - .with_skill(Skill::Axe(AxeSkill::SDamage), Some(1)) - .with_skill(Skill::Axe(AxeSkill::UnlockLeap), None) - .with_skill(Skill::Axe(AxeSkill::LKnockback), Some(1)) - .with_skill(Skill::Axe(AxeSkill::LDistance), Some(1)) - }, - Some(ToolKind::Hammer) => { - // Hammer - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) - .with_skill(Skill::Hammer(HammerSkill::SsKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsSpeed), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsRegen), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CDrain), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CSpeed), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::UnlockLeap), None) - .with_skill(Skill::Hammer(HammerSkill::LDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::LKnockback), Some(1)) - }, - Some(ToolKind::Bow) => { - // Bow - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) - .with_skill(Skill::Bow(BowSkill::ProjSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::CDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::CKnockback), Some(1)) - .with_skill(Skill::Bow(BowSkill::RDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::RSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::RCost), Some(1)) - .with_skill(Skill::Bow(BowSkill::UnlockShotgun), None) - .with_skill(Skill::Bow(BowSkill::SDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::SArrows), Some(1)) - .with_skill(Skill::Bow(BowSkill::SSpread), Some(1)) - }, - Some(ToolKind::Staff) => { - // Staff - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) - .with_skill(Skill::Staff(StaffSkill::BDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::BRadius), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FRange), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FDrain), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FVelocity), Some(1)) - .with_skill(Skill::Staff(StaffSkill::UnlockShockwave), None) - .with_skill(Skill::Staff(StaffSkill::SDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::SRange), Some(1)) - }, - _ => Self::default(), - } - }, - Some(CultistAcolyte) => { - match active_item { - Some(ToolKind::Sword) => { - // Sword - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) - .with_skill(Skill::Sword(SwordSkill::TsCombo), None) - .with_skill(Skill::Sword(SwordSkill::TsDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::TsSpeed), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DScaling), Some(1)) - .with_skill(Skill::Sword(SwordSkill::UnlockSpin), None) - .with_skill(Skill::Sword(SwordSkill::SDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::SSpeed), Some(1)) - .with_skill(Skill::Sword(SwordSkill::SSpins), Some(1)) - }, - Some(ToolKind::Axe) => { - // Axe - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) - .with_skill(Skill::Axe(AxeSkill::DsCombo), None) - .with_skill(Skill::Axe(AxeSkill::DsDamage), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SInfinite), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SDamage), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SCost), Some(1)) - .with_skill(Skill::Axe(AxeSkill::UnlockLeap), None) - .with_skill(Skill::Axe(AxeSkill::LDamage), Some(1)) - .with_skill(Skill::Axe(AxeSkill::LKnockback), Some(1)) - .with_skill(Skill::Axe(AxeSkill::LCost), Some(1)) - .with_skill(Skill::Axe(AxeSkill::LDistance), Some(1)) - }, - Some(ToolKind::Hammer) => { - // Hammer - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) - .with_skill(Skill::Hammer(HammerSkill::SsKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsRegen), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CDrain), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::UnlockLeap), None) - .with_skill(Skill::Hammer(HammerSkill::LDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::LRange), Some(1)) - }, - Some(ToolKind::Bow) => { - // Bow - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) - .with_skill(Skill::Bow(BowSkill::CDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::CKnockback), Some(1)) - .with_skill(Skill::Bow(BowSkill::CSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::RDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::RCost), Some(1)) - .with_skill(Skill::Bow(BowSkill::UnlockShotgun), None) - .with_skill(Skill::Bow(BowSkill::SDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::SSpread), Some(1)) - .with_skill(Skill::Bow(BowSkill::SArrows), Some(1)) - .with_skill(Skill::Bow(BowSkill::SCost), Some(1)) - }, - Some(ToolKind::Staff) => { - // Staff - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) - .with_skill(Skill::Staff(StaffSkill::BDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::BRadius), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FRange), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FVelocity), Some(1)) - .with_skill(Skill::Staff(StaffSkill::UnlockShockwave), None) - .with_skill(Skill::Staff(StaffSkill::SDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::SKnockback), Some(1)) - .with_skill(Skill::Staff(StaffSkill::SRange), Some(1)) - }, - _ => Self::default(), - } - }, - Some(Warlord) => { - match active_item { - Some(ToolKind::Sword) => { - // Sword - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) - .with_skill(Skill::Sword(SwordSkill::TsCombo), None) - .with_skill(Skill::Sword(SwordSkill::TsDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::TsRegen), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DCost), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DDrain), Some(1)) - .with_skill(Skill::Sword(SwordSkill::UnlockSpin), None) - .with_skill(Skill::Sword(SwordSkill::SDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::SSpins), Some(2)) - .with_skill(Skill::Sword(SwordSkill::SCost), Some(1)) - }, - Some(ToolKind::Axe) => { - // Axe - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) - .with_skill(Skill::Axe(AxeSkill::DsCombo), None) - .with_skill(Skill::Axe(AxeSkill::DsDamage), Some(1)) - .with_skill(Skill::Axe(AxeSkill::DsSpeed), Some(1)) - .with_skill(Skill::Axe(AxeSkill::DsRegen), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SInfinite), None) - .with_skill(Skill::Axe(AxeSkill::SHelicopter), None) - .with_skill(Skill::Axe(AxeSkill::SDamage), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SSpeed), Some(1)) - .with_skill(Skill::Axe(AxeSkill::UnlockLeap), None) - .with_skill(Skill::Axe(AxeSkill::LDamage), Some(1)) - .with_skill(Skill::Axe(AxeSkill::LKnockback), Some(1)) - .with_skill(Skill::Axe(AxeSkill::LDistance), Some(1)) - }, - Some(ToolKind::Hammer) => { - // Hammer - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) - .with_skill(Skill::Hammer(HammerSkill::SsKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsSpeed), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsRegen), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CDrain), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::UnlockLeap), None) - .with_skill(Skill::Hammer(HammerSkill::LDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::LDistance), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::LKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::LRange), Some(1)) - }, - Some(ToolKind::Bow) => { - // Bow - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) - .with_skill(Skill::Bow(BowSkill::CDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::CRegen), Some(1)) - .with_skill(Skill::Bow(BowSkill::CKnockback), Some(1)) - .with_skill(Skill::Bow(BowSkill::CSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::CMove), Some(1)) - .with_skill(Skill::Bow(BowSkill::RDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::RSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::UnlockShotgun), None) - .with_skill(Skill::Bow(BowSkill::SDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::SSpread), Some(1)) - .with_skill(Skill::Bow(BowSkill::SArrows), Some(1)) - .with_skill(Skill::Bow(BowSkill::SCost), Some(1)) - }, - Some(ToolKind::Staff) => { - // Staff - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) - .with_skill(Skill::Staff(StaffSkill::BDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::BRegen), Some(1)) - .with_skill(Skill::Staff(StaffSkill::BRadius), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FDrain), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FVelocity), Some(1)) - .with_skill(Skill::Staff(StaffSkill::UnlockShockwave), None) - .with_skill(Skill::Staff(StaffSkill::SDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::SKnockback), Some(1)) - .with_skill(Skill::Staff(StaffSkill::SCost), Some(1)) - }, - _ => Self::default(), - } - }, - Some(Warlock) => { - match active_item { - Some(ToolKind::Sword) => { - // Sword - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Sword)) - .with_skill(Skill::Sword(SwordSkill::TsCombo), None) - .with_skill(Skill::Sword(SwordSkill::TsDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::TsRegen), Some(1)) - .with_skill(Skill::Sword(SwordSkill::TsSpeed), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DDamage), Some(2)) - .with_skill(Skill::Sword(SwordSkill::DCost), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DDrain), Some(1)) - .with_skill(Skill::Sword(SwordSkill::DScaling), Some(1)) - .with_skill(Skill::Sword(SwordSkill::UnlockSpin), None) - .with_skill(Skill::Sword(SwordSkill::SDamage), Some(1)) - .with_skill(Skill::Sword(SwordSkill::SSpeed), Some(1)) - .with_skill(Skill::Sword(SwordSkill::SSpins), Some(2)) - .with_skill(Skill::Sword(SwordSkill::SCost), Some(1)) - }, - Some(ToolKind::Axe) => { - // Axe - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Axe)) - .with_skill(Skill::Axe(AxeSkill::DsCombo), None) - .with_skill(Skill::Axe(AxeSkill::DsDamage), Some(1)) - .with_skill(Skill::Axe(AxeSkill::DsSpeed), Some(1)) - .with_skill(Skill::Axe(AxeSkill::DsRegen), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SInfinite), None) - .with_skill(Skill::Axe(AxeSkill::SHelicopter), None) - .with_skill(Skill::Axe(AxeSkill::SDamage), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SSpeed), Some(1)) - .with_skill(Skill::Axe(AxeSkill::SCost), Some(1)) - .with_skill(Skill::Axe(AxeSkill::UnlockLeap), None) - .with_skill(Skill::Axe(AxeSkill::LDamage), Some(1)) - .with_skill(Skill::Axe(AxeSkill::LKnockback), Some(1)) - .with_skill(Skill::Axe(AxeSkill::LCost), Some(1)) - .with_skill(Skill::Axe(AxeSkill::LDistance), Some(1)) - }, - Some(ToolKind::Hammer) => { - // Hammer - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Hammer)) - .with_skill(Skill::Hammer(HammerSkill::SsKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsSpeed), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::SsRegen), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CDrain), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::CSpeed), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::UnlockLeap), None) - .with_skill(Skill::Hammer(HammerSkill::LDamage), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::LCost), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::LDistance), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::LKnockback), Some(1)) - .with_skill(Skill::Hammer(HammerSkill::LRange), Some(1)) - }, - Some(ToolKind::Bow) => { - // Bow - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow)) - .with_skill(Skill::Bow(BowSkill::ProjSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::CDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::CRegen), Some(1)) - .with_skill(Skill::Bow(BowSkill::CKnockback), Some(1)) - .with_skill(Skill::Bow(BowSkill::CSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::CMove), Some(1)) - .with_skill(Skill::Bow(BowSkill::RDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::RSpeed), Some(1)) - .with_skill(Skill::Bow(BowSkill::RCost), Some(1)) - .with_skill(Skill::Bow(BowSkill::UnlockShotgun), None) - .with_skill(Skill::Bow(BowSkill::SDamage), Some(1)) - .with_skill(Skill::Bow(BowSkill::SSpread), Some(1)) - .with_skill(Skill::Bow(BowSkill::SArrows), Some(1)) - .with_skill(Skill::Bow(BowSkill::SCost), Some(1)) - }, - Some(ToolKind::Staff) => { - // Staff - Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) - .with_skill(Skill::Staff(StaffSkill::BDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::BRegen), Some(1)) - .with_skill(Skill::Staff(StaffSkill::BRadius), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FRange), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FDrain), Some(1)) - .with_skill(Skill::Staff(StaffSkill::FVelocity), Some(1)) - .with_skill(Skill::Staff(StaffSkill::UnlockShockwave), None) - .with_skill(Skill::Staff(StaffSkill::SDamage), Some(1)) - .with_skill(Skill::Staff(StaffSkill::SKnockback), Some(1)) - .with_skill(Skill::Staff(StaffSkill::SRange), Some(1)) - .with_skill(Skill::Staff(StaffSkill::SCost), Some(1)) - }, - _ => Self::default(), - } - }, - Some(Mindflayer) => Self::default() - .with_skill_group(SkillGroupKind::Weapon(ToolKind::Staff)) - .with_skill(Skill::Staff(StaffSkill::BDamage), Some(3)) - .with_skill(Skill::Staff(StaffSkill::BRegen), Some(2)) - .with_skill(Skill::Staff(StaffSkill::BRadius), Some(2)) - .with_skill(Skill::Staff(StaffSkill::FDamage), Some(3)) - .with_skill(Skill::Staff(StaffSkill::FRange), Some(2)) - .with_skill(Skill::Staff(StaffSkill::FDrain), Some(2)) - .with_skill(Skill::Staff(StaffSkill::FVelocity), Some(2)) - .with_skill(Skill::Staff(StaffSkill::UnlockShockwave), None) - .with_skill(Skill::Staff(StaffSkill::SDamage), Some(2)) - .with_skill(Skill::Staff(StaffSkill::SKnockback), Some(2)) - .with_skill(Skill::Staff(StaffSkill::SRange), Some(2)) - .with_skill(Skill::Staff(StaffSkill::SCost), Some(2)), - Some(Villager) | None => Self::default(), + builder.with_asset_expect(asset_specifier) + } + + /// Applies `asset_specifier` with needed skill tree + #[must_use] + pub fn with_asset_expect(mut self, asset_specifier: &str) -> Self { + let tree = skills_from_asset_expect(asset_specifier); + for (skill, level) in tree { + self = self.with_skill(skill, level); } + + self + } + + /// Creates `SkillSetBuilder` for given preset + #[must_use] + pub fn from_preset(preset: Preset) -> Self { + let builder = Self::default(); + + builder.with_preset(preset) + } + + /// Applies preset + #[must_use] + pub const fn with_preset(self, preset: Preset) -> Self { + match preset { + Preset::Empty => {}, + } + self } #[must_use] @@ -689,7 +103,6 @@ impl SkillSetBuilder { /// 2) If added skill already applied /// 3) If added skill wasn't applied at the end pub fn with_skill(mut self, skill: Skill, level: Option) -> Self { - #![warn(clippy::pedantic)] let group = if let Some(skill_group) = skill.skill_group_kind() { skill_group } else { @@ -697,12 +110,7 @@ impl SkillSetBuilder { "Tried to add skill: {:?} which does not have an associated skill group.", skill ); - if cfg!(test) { - panic!("{}", err); - } else { - warn!("{}", err); - } - return self; + common_base::dev_panic!(err, or return self); }; let SkillSetBuilder(ref mut skill_set) = self; @@ -711,12 +119,7 @@ impl SkillSetBuilder { "Tried to add skill: {:?} with level {:?} which is already applied", skill, level, ); - if cfg!(test) { - panic!("{}", err); - } else { - warn!("{}", err); - } - return self; + common_base::dev_panic!(err, or return self); } for _ in 0..level.unwrap_or(1) { skill_set.add_skill_points(group, skill_set.skill_cost(skill)); @@ -728,22 +131,16 @@ impl SkillSetBuilder { available and meets all prerequisite skills.", skill ); - if cfg!(test) { - panic!("{}", err); - } else { - warn!("{}", err); - } + common_base::dev_panic!(err); } self } - pub fn with_skill_group(self, skill_group: SkillGroupKind) -> Self { - self.with_skill(Skill::UnlockGroup(skill_group), None) - } - + #[must_use] pub fn build(self) -> SkillSet { self.0 } } +#[must_use] fn skill_is_applied(skill_set: &SkillSet, skill: Skill, level: Option) -> bool { if let Ok(applied_level) = skill_set.skill_level(skill) { applied_level == level @@ -751,3 +148,45 @@ fn skill_is_applied(skill_set: &SkillSet, skill: Skill, level: Option) -> b false } } + +#[cfg(test)] +mod tests { + use super::*; + use assets::Error; + + #[test] + fn test_all_skillset_assets() { + #[derive(Clone)] + struct SkillSetList(Vec); + + impl assets::Compound for SkillSetList { + fn load( + cache: &assets::AssetCache, + specifier: &str, + ) -> Result { + let list = cache + .load::(specifier)? + .read() + .iter() + .map(|spec| SkillSetTree::load_cloned(spec)) + .collect::>()?; + + Ok(Self(list)) + } + } + + let skillsets = SkillSetList::load_expect_cloned("common.skillset.*").0; + for skillset in skillsets { + std::mem::drop({ + let mut skillset_builder = SkillSetBuilder::default(); + let nodes = skillset.0; + let tree = skills_from_nodes(nodes); + for (skill, level) in tree { + skillset_builder = skillset_builder.with_skill(skill, level); + } + + skillset_builder + }); + } + } +} diff --git a/common/src/states/basic_summon.rs b/common/src/states/basic_summon.rs index 8b69c6a3ab..1c094b8883 100644 --- a/common/src/states/basic_summon.rs +++ b/common/src/states/basic_summon.rs @@ -6,7 +6,7 @@ use crate::{ }, event::{LocalEvent, ServerEvent}, outcome::Outcome, - skillset_builder::{SkillSetBuilder, SkillSetConfig}, + skillset_builder::{self, SkillSetBuilder}, states::{ behavior::{CharacterBehavior, JoinData}, utils::*, @@ -74,24 +74,33 @@ impl CharacterBehavior for Data { > self.static_data.cast_duration * self.summon_count / self.static_data.summon_amount { - let body = self.static_data.summon_info.body; + let SummonInfo { + body, + loadout_config, + skillset_config, + .. + } = self.static_data.summon_info; - let mut loadout_builder = - LoadoutBuilder::new().with_default_maintool(&body); + let loadout = { + let loadout_builder = + LoadoutBuilder::new().with_default_maintool(&body); + if let Some(preset) = loadout_config { + loadout_builder.with_preset(preset).build() + } else { + loadout_builder.build() + } + }; - if let Some(preset) = self.static_data.summon_info.loadout_config { - loadout_builder = loadout_builder.with_preset(preset); - } - - let loadout = loadout_builder.build(); + let skill_set = { + let skillset_builder = SkillSetBuilder::default(); + if let Some(preset) = skillset_config { + skillset_builder.with_preset(preset).build() + } else { + skillset_builder.build() + } + }; let stats = comp::Stats::new("Summon".to_string()); - let skill_set = SkillSetBuilder::build_skillset( - &None, - self.static_data.summon_info.skillset_config, - ) - .build(); - // Send server event to create npc update.server_events.push_front(ServerEvent::CreateNpc { pos: *data.pos, @@ -179,5 +188,5 @@ pub struct SummonInfo { health_scaling: u16, // TODO: use assets for specifying skills and loadout? loadout_config: Option, - skillset_config: Option, + skillset_config: Option, } diff --git a/server/src/sys/terrain.rs b/server/src/sys/terrain.rs index b4decd5bad..458c710b28 100644 --- a/server/src/sys/terrain.rs +++ b/server/src/sys/terrain.rs @@ -195,44 +195,49 @@ impl<'a> System<'a> for Sys { } let EntityInfo { - skillset_preset, + skillset_asset, main_tool, - loadout_config, + loadout_asset, make_loadout, trading_information: economy, .. } = entity; - let skill_set = - SkillSetBuilder::build_skillset(&main_tool, skillset_preset).build(); + let skill_set = { + let skillset_builder = SkillSetBuilder::default(); + if let Some(skillset_asset) = skillset_asset { + skillset_builder.with_asset_expect(&skillset_asset).build() + } else { + skillset_builder.build() + } + }; - let mut loadout_builder = LoadoutBuilder::new(); - let rng = &mut rand::thread_rng(); + let loadout = { + let mut loadout_builder = LoadoutBuilder::new(); + let rng = &mut rand::thread_rng(); - // If main tool is passed, use it. Otherwise fallback to default tool - if let Some(main_tool) = main_tool { - loadout_builder = loadout_builder.active_mainhand(Some(main_tool)); - } else { - loadout_builder = loadout_builder.with_default_maintool(&body); - } + // If main tool is passed, use it. Otherwise fallback to default tool + if let Some(main_tool) = main_tool { + loadout_builder = loadout_builder.active_mainhand(Some(main_tool)); + } else { + loadout_builder = loadout_builder.with_default_maintool(&body); + } - // If there is config, apply it. - // If not, use default equipement for this body. - match loadout_config { - Some(asset) => { + // If there is config, apply it. + // If not, use default equipement for this body. + if let Some(asset) = loadout_asset { loadout_builder = loadout_builder.with_asset_expect(&asset, rng); - }, - None => { + } else { loadout_builder = loadout_builder.with_default_equipment(&body); - }, - } + } - // Evaluate lazy function for loadout creation - if let Some(make_loadout) = make_loadout { - loadout_builder = loadout_builder.with_creator(make_loadout, economy.as_ref()); - } - - let loadout = loadout_builder.build(); + // Evaluate lazy function for loadout creation + if let Some(make_loadout) = make_loadout { + loadout_builder = + loadout_builder.with_creator(make_loadout, economy.as_ref()); + } + loadout_builder.build() + }; let health = comp::Health::new(body, entity.level.unwrap_or(0)); let poise = comp::Poise::new(body); diff --git a/world/src/site/dungeon/mod.rs b/world/src/site/dungeon/mod.rs index dc06ebc758..2439027220 100644 --- a/world/src/site/dungeon/mod.rs +++ b/world/src/site/dungeon/mod.rs @@ -932,8 +932,7 @@ fn enemy_0(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { &comp::biped_small::Species::Gnarling, ), )) - .with_loot_drop(chosen.read().choose().to_item()) - .with_skillset_preset(common::skillset_builder::SkillSetConfig::Gnarling); + .with_loot_drop(chosen.read().choose().to_item()); match dynamic_rng.gen_range(0..5) { 0 => gnarling.with_asset_expect("common.entity.dungeon.tier-0.bow"), @@ -949,7 +948,6 @@ fn enemy_1(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { .with_body(comp::Body::BipedSmall( comp::biped_small::Body::random_with(dynamic_rng, &comp::biped_small::Species::Adlet), )) - .with_skillset_preset(common::skillset_builder::SkillSetConfig::Adlet) .with_loot_drop(chosen.read().choose().to_item()); match dynamic_rng.gen_range(0..5) { @@ -966,7 +964,6 @@ fn enemy_2(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { .with_body(comp::Body::BipedSmall( comp::biped_small::Body::random_with(dynamic_rng, &comp::biped_small::Species::Sahagin), )) - .with_skillset_preset(common::skillset_builder::SkillSetConfig::Sahagin) .with_loot_drop(chosen.read().choose().to_item()); match dynamic_rng.gen_range(0..5) { @@ -994,7 +991,6 @@ fn enemy_3(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { &comp::biped_small::Species::Haniwa, ), )) - .with_skillset_preset(common::skillset_builder::SkillSetConfig::Haniwa) .with_loot_drop(chosen.read().choose().to_item()); match dynamic_rng.gen_range(0..5) { @@ -1015,7 +1011,6 @@ fn enemy_4(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { &comp::biped_small::Species::Myrmidon, ), )) - .with_skillset_preset(common::skillset_builder::SkillSetConfig::Myrmidon) .with_loot_drop(chosen.read().choose().to_item()); match dynamic_rng.gen_range(0..5) { @@ -1037,12 +1032,10 @@ fn enemy_5(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { )), 1 => entity .with_body(comp::Body::Humanoid(comp::humanoid::Body::random())) - .with_skillset_preset(common::skillset_builder::SkillSetConfig::Warlock) .with_loot_drop(chosen.read().choose().to_item()) .with_asset_expect("common.entity.dungeon.tier-5.warlock"), _ => entity .with_body(comp::Body::Humanoid(comp::humanoid::Body::random())) - .with_skillset_preset(common::skillset_builder::SkillSetConfig::Warlord) .with_loot_drop(chosen.read().choose().to_item()) .with_asset_expect("common.entity.dungeon.tier-5.warlord"), } @@ -1147,9 +1140,8 @@ fn boss_5(dynamic_rng: &mut impl Rng, tile_wcenter: Vec3) -> Vec) -> Vec entity - .with_main_tool(Item::new_from_asset_expect( - "common.items.weapons.sword.iron-4", - )) - .with_name("Guard") .with_agent_mark(agent::Mark::Guard) .with_lazy_loadout(guard_loadout) .with_level(dynamic_rng.gen_range(10..15)) - .with_skillset_preset( - common::skillset_builder::SkillSetConfig::Guard, - ), + .with_asset_expect("common.entity.village.guard"), 1 | 2 => entity - .with_main_tool(Item::new_from_asset_expect( - "common.items.weapons.bow.eldwood-0", - )) - .with_name("Merchant") .with_agent_mark(agent::Mark::Merchant) .with_economy(&economy) .with_lazy_loadout(merchant_loadout) .with_level(dynamic_rng.gen_range(10..15)) - .with_skillset_preset( - common::skillset_builder::SkillSetConfig::Merchant, - ), + .with_asset_expect("common.entity.village.merchant"), _ => entity - .with_main_tool(Item::new_from_asset_expect( - match dynamic_rng.gen_range(0..7) { - 0 => "common.items.weapons.tool.broom", - 1 => "common.items.weapons.tool.hoe", - 2 => "common.items.weapons.tool.pickaxe", - 3 => "common.items.weapons.tool.pitchfork", - 4 => "common.items.weapons.tool.rake", - 5 => "common.items.weapons.tool.shovel-0", - _ => "common.items.weapons.tool.shovel-1", - //_ => "common.items.weapons.bow.starter", TODO: Re-Add this when we have a better way of distributing npc_weapons here - }, - )) .with_lazy_loadout(villager_loadout) - .with_skillset_preset( - common::skillset_builder::SkillSetConfig::Villager, - ), + .with_asset_expect("common.entity.village.villager"), } });