mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Chieftain AI and attacks
This commit is contained in:
parent
3a35dcc77f
commit
0031aa6f5f
@ -79,6 +79,31 @@
|
|||||||
secondary: "common.abilities.gnarling.blowgun.dart",
|
secondary: "common.abilities.gnarling.blowgun.dart",
|
||||||
abilities: [],
|
abilities: [],
|
||||||
),
|
),
|
||||||
|
Custom("Gnarling Chieftain"): (
|
||||||
|
primary: "common.abilities.gnarling.chieftain.flamestrike",
|
||||||
|
secondary: "common.abilities.gnarling.chieftain.firebarrage",
|
||||||
|
abilities: [
|
||||||
|
(None, "common.abilities.gnarling.chieftain.fireshockwave"),
|
||||||
|
(None, "common.abilities.gnarling.chieftain.redtotem"),
|
||||||
|
(None, "common.abilities.gnarling.chieftain.greentotem"),
|
||||||
|
(None, "common.abilities.gnarling.chieftain.whitetotem"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Custom("Gnarling Totem Red"): (
|
||||||
|
primary: "common.abilities.gnarling.totem.red",
|
||||||
|
secondary: "common.abilities.gnarling.totem.red",
|
||||||
|
abilities: [],
|
||||||
|
),
|
||||||
|
Custom("Gnarling Totem Green"): (
|
||||||
|
primary: "common.abilities.gnarling.totem.green",
|
||||||
|
secondary: "common.abilities.gnarling.totem.green",
|
||||||
|
abilities: [],
|
||||||
|
),
|
||||||
|
Custom("Gnarling Totem White"): (
|
||||||
|
primary: "common.abilities.gnarling.totem.white",
|
||||||
|
secondary: "common.abilities.gnarling.totem.white",
|
||||||
|
abilities: [],
|
||||||
|
),
|
||||||
Custom("Deadwood"): (
|
Custom("Deadwood"): (
|
||||||
primary: "common.abilities.custom.deadwood.lifestealbeam",
|
primary: "common.abilities.custom.deadwood.lifestealbeam",
|
||||||
secondary: "common.abilities.custom.deadwood.dash",
|
secondary: "common.abilities.custom.deadwood.dash",
|
||||||
|
15
assets/common/abilities/gnarling/chieftain/firebarrage.ron
Normal file
15
assets/common/abilities/gnarling/chieftain/firebarrage.ron
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
BasicRanged(
|
||||||
|
energy_cost: 0,
|
||||||
|
buildup_duration: 0.5,
|
||||||
|
recover_duration: 0.4,
|
||||||
|
projectile: Fireball(
|
||||||
|
damage: 9.0,
|
||||||
|
radius: 4.0,
|
||||||
|
energy_regen: 10.0,
|
||||||
|
min_falloff: 0.5,
|
||||||
|
),
|
||||||
|
projectile_body: Object(BoltFire),
|
||||||
|
projectile_speed: 40,
|
||||||
|
num_projectiles: 8,
|
||||||
|
projectile_spread: 0.05,
|
||||||
|
)
|
17
assets/common/abilities/gnarling/chieftain/fireshockwave.ron
Normal file
17
assets/common/abilities/gnarling/chieftain/fireshockwave.ron
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
Shockwave(
|
||||||
|
energy_cost: 0,
|
||||||
|
buildup_duration: 0.5,
|
||||||
|
swing_duration: 0.1,
|
||||||
|
recover_duration: 0.4,
|
||||||
|
damage: 15,
|
||||||
|
poise_damage: 0,
|
||||||
|
knockback: ( strength: 25, direction: Away),
|
||||||
|
shockwave_angle: 360,
|
||||||
|
shockwave_vertical_angle: 90,
|
||||||
|
shockwave_speed: 10,
|
||||||
|
shockwave_duration: 1,
|
||||||
|
requires_ground: false,
|
||||||
|
move_efficiency: 0,
|
||||||
|
damage_kind: Energy,
|
||||||
|
specifier: Fire,
|
||||||
|
)
|
23
assets/common/abilities/gnarling/chieftain/flamestrike.ron
Normal file
23
assets/common/abilities/gnarling/chieftain/flamestrike.ron
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
BasicMelee(
|
||||||
|
energy_cost: 0,
|
||||||
|
buildup_duration: 0.4,
|
||||||
|
swing_duration: 0.1,
|
||||||
|
recover_duration: 0.3,
|
||||||
|
melee_constructor: (
|
||||||
|
kind: Bash(
|
||||||
|
damage: 5,
|
||||||
|
poise: 10,
|
||||||
|
knockback: 0,
|
||||||
|
energy_regen: 0,
|
||||||
|
),
|
||||||
|
range: 7.5,
|
||||||
|
angle: 60.0,
|
||||||
|
damage_effect: Some(Buff((
|
||||||
|
kind: Burning,
|
||||||
|
dur_secs: 10.0,
|
||||||
|
strength: DamageFraction(0.5),
|
||||||
|
chance: 0.5,
|
||||||
|
))),
|
||||||
|
),
|
||||||
|
ori_modifier: 0.7,
|
||||||
|
)
|
15
assets/common/abilities/gnarling/chieftain/greentotem.ron
Normal file
15
assets/common/abilities/gnarling/chieftain/greentotem.ron
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
BasicSummon(
|
||||||
|
buildup_duration: 0.25,
|
||||||
|
cast_duration: 0.5,
|
||||||
|
recover_duration: 0.25,
|
||||||
|
summon_amount: 1,
|
||||||
|
summon_distance: (1, 1),
|
||||||
|
summon_info: (
|
||||||
|
body: Object(GnarlingTotemGreen),
|
||||||
|
scale: None,
|
||||||
|
has_health: true,
|
||||||
|
loadout_config: None,
|
||||||
|
skillset_config: None,
|
||||||
|
),
|
||||||
|
duration: None,
|
||||||
|
)
|
15
assets/common/abilities/gnarling/chieftain/redtotem.ron
Normal file
15
assets/common/abilities/gnarling/chieftain/redtotem.ron
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
BasicSummon(
|
||||||
|
buildup_duration: 0.25,
|
||||||
|
cast_duration: 0.5,
|
||||||
|
recover_duration: 0.25,
|
||||||
|
summon_amount: 1,
|
||||||
|
summon_distance: (1, 1),
|
||||||
|
summon_info: (
|
||||||
|
body: Object(GnarlingTotemRed),
|
||||||
|
scale: None,
|
||||||
|
has_health: true,
|
||||||
|
loadout_config: None,
|
||||||
|
skillset_config: None,
|
||||||
|
),
|
||||||
|
duration: None,
|
||||||
|
)
|
15
assets/common/abilities/gnarling/chieftain/whitetotem.ron
Normal file
15
assets/common/abilities/gnarling/chieftain/whitetotem.ron
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
BasicSummon(
|
||||||
|
buildup_duration: 0.25,
|
||||||
|
cast_duration: 0.5,
|
||||||
|
recover_duration: 0.25,
|
||||||
|
summon_amount: 1,
|
||||||
|
summon_distance: (1, 1),
|
||||||
|
summon_info: (
|
||||||
|
body: Object(GnarlingTotemWhite),
|
||||||
|
scale: None,
|
||||||
|
has_health: true,
|
||||||
|
loadout_config: None,
|
||||||
|
skillset_config: None,
|
||||||
|
),
|
||||||
|
duration: None,
|
||||||
|
)
|
24
assets/common/abilities/gnarling/totem/green.ron
Normal file
24
assets/common/abilities/gnarling/totem/green.ron
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
BasicAura(
|
||||||
|
buildup_duration: 0.25,
|
||||||
|
cast_duration: 0.5,
|
||||||
|
recover_duration: 0.25,
|
||||||
|
targets: InGroup,
|
||||||
|
auras: [
|
||||||
|
(
|
||||||
|
kind: Regeneration,
|
||||||
|
strength: 5,
|
||||||
|
duration: Some(5),
|
||||||
|
category: Magical,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
kind: ProtectingWard,
|
||||||
|
strength: 0.50,
|
||||||
|
duration: Some(5),
|
||||||
|
category: Magical,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
aura_duration: 60,
|
||||||
|
range: 50,
|
||||||
|
energy_cost: 0,
|
||||||
|
scales_with_combo: false,
|
||||||
|
)
|
18
assets/common/abilities/gnarling/totem/red.ron
Normal file
18
assets/common/abilities/gnarling/totem/red.ron
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
BasicAura(
|
||||||
|
buildup_duration: 0.25,
|
||||||
|
cast_duration: 0.5,
|
||||||
|
recover_duration: 0.25,
|
||||||
|
targets: OutOfGroup,
|
||||||
|
auras: [
|
||||||
|
(
|
||||||
|
kind: Burning,
|
||||||
|
strength: 0.5,
|
||||||
|
duration: Some(5),
|
||||||
|
category: Magical,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
aura_duration: 60,
|
||||||
|
range: 50,
|
||||||
|
energy_cost: 0,
|
||||||
|
scales_with_combo: false,
|
||||||
|
)
|
18
assets/common/abilities/gnarling/totem/white.ron
Normal file
18
assets/common/abilities/gnarling/totem/white.ron
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
BasicAura(
|
||||||
|
buildup_duration: 0.25,
|
||||||
|
cast_duration: 0.5,
|
||||||
|
recover_duration: 0.25,
|
||||||
|
targets: InGroup,
|
||||||
|
auras: [
|
||||||
|
(
|
||||||
|
kind: Hastened,
|
||||||
|
strength: 0.5,
|
||||||
|
duration: Some(5),
|
||||||
|
category: Magical,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
aura_duration: 60,
|
||||||
|
range: 50,
|
||||||
|
energy_cost: 0,
|
||||||
|
scales_with_combo: false,
|
||||||
|
)
|
@ -3,15 +3,17 @@ BasicAura(
|
|||||||
cast_duration: 0.5,
|
cast_duration: 0.5,
|
||||||
recover_duration: 0.25,
|
recover_duration: 0.25,
|
||||||
targets: InGroup,
|
targets: InGroup,
|
||||||
aura: (
|
auras: [
|
||||||
|
(
|
||||||
kind: Regeneration,
|
kind: Regeneration,
|
||||||
strength: 0.2,
|
strength: 0.2,
|
||||||
duration: Some(10.0),
|
duration: Some(10.0),
|
||||||
category: Magical,
|
category: Magical,
|
||||||
),
|
),
|
||||||
|
],
|
||||||
aura_duration: 1.0,
|
aura_duration: 1.0,
|
||||||
range: 25.0,
|
range: 25.0,
|
||||||
energy_cost: 20.0,
|
energy_cost: 20.0,
|
||||||
scales_with_combo: true,
|
scales_with_combo: true,
|
||||||
specifier: HealingAura,
|
specifier: Some(HealingAura),
|
||||||
)
|
)
|
||||||
|
@ -3,15 +3,17 @@ BasicAura(
|
|||||||
cast_duration: 0.5,
|
cast_duration: 0.5,
|
||||||
recover_duration: 0.25,
|
recover_duration: 0.25,
|
||||||
targets: InGroup,
|
targets: InGroup,
|
||||||
aura: (
|
auras: [
|
||||||
|
(
|
||||||
kind: ProtectingWard,
|
kind: ProtectingWard,
|
||||||
strength: 0.20,
|
strength: 0.20,
|
||||||
duration: Some(10.0),
|
duration: Some(10.0),
|
||||||
category: Magical,
|
category: Magical,
|
||||||
),
|
),
|
||||||
|
],
|
||||||
aura_duration: 1.0,
|
aura_duration: 1.0,
|
||||||
range: 25.0,
|
range: 25.0,
|
||||||
energy_cost: 40.0,
|
energy_cost: 40.0,
|
||||||
scales_with_combo: false,
|
scales_with_combo: false,
|
||||||
specifier: WardingAura,
|
specifier: Some(WardingAura),
|
||||||
)
|
)
|
||||||
|
@ -8,5 +8,8 @@
|
|||||||
inventory: [],
|
inventory: [],
|
||||||
),
|
),
|
||||||
loot: LootTable("common.loot_tables.dungeon.tier-0.enemy"),
|
loot: LootTable("common.loot_tables.dungeon.tier-0.enemy"),
|
||||||
meta: [],
|
meta: [
|
||||||
|
// Done for health reasons
|
||||||
|
SkillSetAsset("common.skillset.preset.rank5.fullskill"),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
@ -4,8 +4,8 @@ ItemDef(
|
|||||||
kind: Armor((
|
kind: Armor((
|
||||||
kind: Chest("GnarlingChieftain"),
|
kind: Chest("GnarlingChieftain"),
|
||||||
stats: (
|
stats: (
|
||||||
protection: Some(Normal(2.0)),
|
protection: Some(Normal(60.0)),
|
||||||
poise_resilience: Some(Normal(1.0)),
|
poise_resilience: Some(Normal(60.0)),
|
||||||
energy_max: Some(2.7),
|
energy_max: Some(2.7),
|
||||||
energy_reward: Some(0.027),
|
energy_reward: Some(0.027),
|
||||||
crit_power: Some(0.025),
|
crit_power: Some(0.025),
|
||||||
|
@ -6,10 +6,10 @@ ItemDef(
|
|||||||
hands: Two,
|
hands: Two,
|
||||||
stats: Direct((
|
stats: Direct((
|
||||||
equip_time_secs: 0.0,
|
equip_time_secs: 0.0,
|
||||||
power: 0.3,
|
power: 1.0,
|
||||||
effect_power: 0.8,
|
effect_power: 1.0,
|
||||||
speed: 0.6,
|
speed: 1.0,
|
||||||
crit_chance: 0.26764706,
|
crit_chance: 0.1,
|
||||||
range: 1.0,
|
range: 1.0,
|
||||||
energy_efficiency: 1.0,
|
energy_efficiency: 1.0,
|
||||||
buff_strength: 1.0,
|
buff_strength: 1.0,
|
||||||
@ -17,5 +17,5 @@ ItemDef(
|
|||||||
)),
|
)),
|
||||||
quality: Low,
|
quality: Low,
|
||||||
tags: [],
|
tags: [],
|
||||||
ability_spec: Some(Custom("Staff Simple")),
|
ability_spec: Some(Custom("Gnarling Chieftain")),
|
||||||
)
|
)
|
@ -0,0 +1,21 @@
|
|||||||
|
ItemDef(
|
||||||
|
name: "Gnarling Green Totem",
|
||||||
|
description: "Yeet",
|
||||||
|
kind: Tool((
|
||||||
|
kind: Natural,
|
||||||
|
hands: Two,
|
||||||
|
stats: Direct((
|
||||||
|
equip_time_secs: 0.01,
|
||||||
|
power: 1.0,
|
||||||
|
effect_power: 1.0,
|
||||||
|
speed: 1.0,
|
||||||
|
crit_chance: 0.1,
|
||||||
|
range: 1.0,
|
||||||
|
energy_efficiency: 1.0,
|
||||||
|
buff_strength: 1.0,
|
||||||
|
)),
|
||||||
|
)),
|
||||||
|
quality: Low,
|
||||||
|
tags: [],
|
||||||
|
ability_spec: Some(Custom("Gnarling Totem Green")),
|
||||||
|
)
|
@ -0,0 +1,21 @@
|
|||||||
|
ItemDef(
|
||||||
|
name: "Gnarling Red Totem",
|
||||||
|
description: "Yeet",
|
||||||
|
kind: Tool((
|
||||||
|
kind: Natural,
|
||||||
|
hands: Two,
|
||||||
|
stats: Direct((
|
||||||
|
equip_time_secs: 0.01,
|
||||||
|
power: 1.0,
|
||||||
|
effect_power: 1.0,
|
||||||
|
speed: 1.0,
|
||||||
|
crit_chance: 0.1,
|
||||||
|
range: 1.0,
|
||||||
|
energy_efficiency: 1.0,
|
||||||
|
buff_strength: 1.0,
|
||||||
|
)),
|
||||||
|
)),
|
||||||
|
quality: Low,
|
||||||
|
tags: [],
|
||||||
|
ability_spec: Some(Custom("Gnarling Totem Red")),
|
||||||
|
)
|
@ -0,0 +1,21 @@
|
|||||||
|
ItemDef(
|
||||||
|
name: "Gnarling White Totem",
|
||||||
|
description: "Yeet",
|
||||||
|
kind: Tool((
|
||||||
|
kind: Natural,
|
||||||
|
hands: Two,
|
||||||
|
stats: Direct((
|
||||||
|
equip_time_secs: 0.01,
|
||||||
|
power: 1.0,
|
||||||
|
effect_power: 1.0,
|
||||||
|
speed: 1.0,
|
||||||
|
crit_chance: 0.1,
|
||||||
|
range: 1.0,
|
||||||
|
energy_efficiency: 1.0,
|
||||||
|
buff_strength: 1.0,
|
||||||
|
)),
|
||||||
|
)),
|
||||||
|
quality: Low,
|
||||||
|
tags: [],
|
||||||
|
ability_spec: Some(Custom("Gnarling Totem White")),
|
||||||
|
)
|
@ -21,6 +21,8 @@
|
|||||||
"buff.desc.protectingward": "You are protected, somewhat, from attacks.",
|
"buff.desc.protectingward": "You are protected, somewhat, from attacks.",
|
||||||
"buff.title.frenzied": "Frenzied",
|
"buff.title.frenzied": "Frenzied",
|
||||||
"buff.desc.frenzied": "You are imbued with unnatural speed and can ignore minor injuries.",
|
"buff.desc.frenzied": "You are imbued with unnatural speed and can ignore minor injuries.",
|
||||||
|
"buff.title.hastened": "Hastened",
|
||||||
|
"buff.desc.hastened": "Your movements and attacks are faster.",
|
||||||
// Debuffs
|
// Debuffs
|
||||||
"buff.title.bleed": "Bleeding",
|
"buff.title.bleed": "Bleeding",
|
||||||
"buff.desc.bleed": "Inflicts regular damage.",
|
"buff.desc.bleed": "Inflicts regular damage.",
|
||||||
|
BIN
assets/voxygen/voxel/object/gnarling_totem_green.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/object/gnarling_totem_green.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/object/gnarling_totem_red.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/object/gnarling_totem_red.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/object/gnarling_totem_white.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/object/gnarling_totem_white.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -829,4 +829,34 @@
|
|||||||
central: ("armor.empty"),
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
GnarlingTotemRed: (
|
||||||
|
bone0: (
|
||||||
|
offset: (-6.0, -5.0, 0.0),
|
||||||
|
central: ("object.gnarling_totem_red"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
GnarlingTotemGreen: (
|
||||||
|
bone0: (
|
||||||
|
offset: (-9.0, -5.0, 0.0),
|
||||||
|
central: ("object.gnarling_totem_green"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
GnarlingTotemWhite: (
|
||||||
|
bone0: (
|
||||||
|
offset: (-8.0, -5.0, 0.0),
|
||||||
|
central: ("object.gnarling_totem_white"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
|
)
|
||||||
|
),
|
||||||
})
|
})
|
||||||
|
@ -207,6 +207,7 @@ lazy_static! {
|
|||||||
BuffKind::Wet => "wet",
|
BuffKind::Wet => "wet",
|
||||||
BuffKind::Ensnared => "ensnared",
|
BuffKind::Ensnared => "ensnared",
|
||||||
BuffKind::Poisoned => "poisoned",
|
BuffKind::Poisoned => "poisoned",
|
||||||
|
BuffKind::Hastened => "hastened",
|
||||||
};
|
};
|
||||||
let mut buff_parser = HashMap::new();
|
let mut buff_parser = HashMap::new();
|
||||||
BuffKind::iter().for_each(|kind| {buff_parser.insert(string_from_buff(kind).to_string(), kind);});
|
BuffKind::iter().for_each(|kind| {buff_parser.insert(string_from_buff(kind).to_string(), kind);});
|
||||||
|
@ -552,12 +552,12 @@ pub enum CharacterAbility {
|
|||||||
cast_duration: f32,
|
cast_duration: f32,
|
||||||
recover_duration: f32,
|
recover_duration: f32,
|
||||||
targets: combat::GroupTarget,
|
targets: combat::GroupTarget,
|
||||||
aura: aura::AuraBuffConstructor,
|
auras: Vec<aura::AuraBuffConstructor>,
|
||||||
aura_duration: f32,
|
aura_duration: f32,
|
||||||
range: f32,
|
range: f32,
|
||||||
energy_cost: f32,
|
energy_cost: f32,
|
||||||
scales_with_combo: bool,
|
scales_with_combo: bool,
|
||||||
specifier: aura::Specifier,
|
specifier: Option<aura::Specifier>,
|
||||||
},
|
},
|
||||||
Blink {
|
Blink {
|
||||||
buildup_duration: f32,
|
buildup_duration: f32,
|
||||||
@ -964,13 +964,7 @@ impl CharacterAbility {
|
|||||||
ref mut cast_duration,
|
ref mut cast_duration,
|
||||||
ref mut recover_duration,
|
ref mut recover_duration,
|
||||||
targets: _,
|
targets: _,
|
||||||
aura:
|
ref mut auras,
|
||||||
aura::AuraBuffConstructor {
|
|
||||||
kind: _,
|
|
||||||
ref mut strength,
|
|
||||||
duration: _,
|
|
||||||
category: _,
|
|
||||||
},
|
|
||||||
aura_duration: _,
|
aura_duration: _,
|
||||||
ref mut range,
|
ref mut range,
|
||||||
ref mut energy_cost,
|
ref mut energy_cost,
|
||||||
@ -980,9 +974,18 @@ impl CharacterAbility {
|
|||||||
*buildup_duration /= stats.speed;
|
*buildup_duration /= stats.speed;
|
||||||
*cast_duration /= stats.speed;
|
*cast_duration /= stats.speed;
|
||||||
*recover_duration /= stats.speed;
|
*recover_duration /= stats.speed;
|
||||||
|
auras.iter_mut().for_each(
|
||||||
|
|aura::AuraBuffConstructor {
|
||||||
|
kind: _,
|
||||||
|
ref mut strength,
|
||||||
|
duration: _,
|
||||||
|
category: _,
|
||||||
|
}| {
|
||||||
// Do we want to make buff_strength affect this instead of power?
|
// Do we want to make buff_strength affect this instead of power?
|
||||||
// Look into during modular weapon transition
|
// Look into during modular weapon transition
|
||||||
*strength *= stats.power;
|
*strength *= stats.power;
|
||||||
|
},
|
||||||
|
);
|
||||||
*range *= stats.range;
|
*range *= stats.range;
|
||||||
*energy_cost /= stats.energy_efficiency;
|
*energy_cost /= stats.energy_efficiency;
|
||||||
},
|
},
|
||||||
@ -1079,7 +1082,6 @@ impl CharacterAbility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use = "method returns new ability and doesn't mutate the original value"]
|
#[must_use = "method returns new ability and doesn't mutate the original value"]
|
||||||
#[warn(clippy::pedantic)]
|
|
||||||
pub fn adjusted_by_skills(mut self, skillset: &SkillSet, tool: Option<ToolKind>) -> Self {
|
pub fn adjusted_by_skills(mut self, skillset: &SkillSet, tool: Option<ToolKind>) -> Self {
|
||||||
match tool {
|
match tool {
|
||||||
Some(ToolKind::Sword) => self.adjusted_by_sword_skills(skillset),
|
Some(ToolKind::Sword) => self.adjusted_by_sword_skills(skillset),
|
||||||
@ -1095,7 +1097,6 @@ impl CharacterAbility {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[warn(clippy::pedantic)]
|
|
||||||
fn adjusted_by_mining_skills(&mut self, skillset: &SkillSet) {
|
fn adjusted_by_mining_skills(&mut self, skillset: &SkillSet) {
|
||||||
use skills::MiningSkill::Speed;
|
use skills::MiningSkill::Speed;
|
||||||
|
|
||||||
@ -1117,7 +1118,6 @@ impl CharacterAbility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[warn(clippy::pedantic)]
|
|
||||||
fn adjusted_by_general_skills(&mut self, skillset: &SkillSet) {
|
fn adjusted_by_general_skills(&mut self, skillset: &SkillSet) {
|
||||||
if let CharacterAbility::Roll {
|
if let CharacterAbility::Roll {
|
||||||
ref mut energy_cost,
|
ref mut energy_cost,
|
||||||
@ -1239,7 +1239,6 @@ impl CharacterAbility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[warn(clippy::pedantic)]
|
|
||||||
fn adjusted_by_axe_skills(&mut self, skillset: &SkillSet) {
|
fn adjusted_by_axe_skills(&mut self, skillset: &SkillSet) {
|
||||||
#![allow(clippy::enum_glob_use)]
|
#![allow(clippy::enum_glob_use)]
|
||||||
use skills::{AxeSkill::*, Skill::Axe};
|
use skills::{AxeSkill::*, Skill::Axe};
|
||||||
@ -1333,7 +1332,6 @@ impl CharacterAbility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[warn(clippy::pedantic)]
|
|
||||||
fn adjusted_by_hammer_skills(&mut self, skillset: &SkillSet) {
|
fn adjusted_by_hammer_skills(&mut self, skillset: &SkillSet) {
|
||||||
#![allow(clippy::enum_glob_use)]
|
#![allow(clippy::enum_glob_use)]
|
||||||
use skills::{HammerSkill::*, Skill::Hammer};
|
use skills::{HammerSkill::*, Skill::Hammer};
|
||||||
@ -1436,7 +1434,6 @@ impl CharacterAbility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[warn(clippy::pedantic)]
|
|
||||||
fn adjusted_by_bow_skills(&mut self, skillset: &SkillSet) {
|
fn adjusted_by_bow_skills(&mut self, skillset: &SkillSet) {
|
||||||
#![allow(clippy::enum_glob_use)]
|
#![allow(clippy::enum_glob_use)]
|
||||||
use skills::{BowSkill::*, Skill::Bow};
|
use skills::{BowSkill::*, Skill::Bow};
|
||||||
@ -1537,7 +1534,6 @@ impl CharacterAbility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[warn(clippy::pedantic)]
|
|
||||||
fn adjusted_by_staff_skills(&mut self, skillset: &SkillSet) {
|
fn adjusted_by_staff_skills(&mut self, skillset: &SkillSet) {
|
||||||
#![allow(clippy::enum_glob_use)]
|
#![allow(clippy::enum_glob_use)]
|
||||||
use skills::{Skill::Staff, StaffSkill::*};
|
use skills::{Skill::Staff, StaffSkill::*};
|
||||||
@ -1607,7 +1603,6 @@ impl CharacterAbility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[warn(clippy::pedantic)]
|
|
||||||
fn adjusted_by_sceptre_skills(&mut self, skillset: &SkillSet) {
|
fn adjusted_by_sceptre_skills(&mut self, skillset: &SkillSet) {
|
||||||
#![allow(clippy::enum_glob_use)]
|
#![allow(clippy::enum_glob_use)]
|
||||||
use skills::{SceptreSkill::*, Skill::Sceptre};
|
use skills::{SceptreSkill::*, Skill::Sceptre};
|
||||||
@ -1641,20 +1636,24 @@ impl CharacterAbility {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
CharacterAbility::BasicAura {
|
CharacterAbility::BasicAura {
|
||||||
ref mut aura,
|
ref mut auras,
|
||||||
ref mut range,
|
ref mut range,
|
||||||
ref mut energy_cost,
|
ref mut energy_cost,
|
||||||
specifier: aura::Specifier::HealingAura,
|
specifier: Some(aura::Specifier::HealingAura),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let modifiers = SKILL_MODIFIERS.sceptre_tree.healing_aura;
|
let modifiers = SKILL_MODIFIERS.sceptre_tree.healing_aura;
|
||||||
if let Ok(level) = skillset.skill_level(Sceptre(HHeal)) {
|
if let Ok(level) = skillset.skill_level(Sceptre(HHeal)) {
|
||||||
|
auras.iter_mut().for_each(|ref mut aura| {
|
||||||
aura.strength *= modifiers.strength.powi(level.into());
|
aura.strength *= modifiers.strength.powi(level.into());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if let Ok(level) = skillset.skill_level(Sceptre(HDuration)) {
|
if let Ok(level) = skillset.skill_level(Sceptre(HDuration)) {
|
||||||
|
auras.iter_mut().for_each(|ref mut aura| {
|
||||||
if let Some(ref mut duration) = aura.duration {
|
if let Some(ref mut duration) = aura.duration {
|
||||||
*duration *= modifiers.duration.powi(level.into());
|
*duration *= modifiers.duration.powi(level.into());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if let Ok(level) = skillset.skill_level(Sceptre(HRange)) {
|
if let Ok(level) = skillset.skill_level(Sceptre(HRange)) {
|
||||||
*range *= modifiers.range.powi(level.into());
|
*range *= modifiers.range.powi(level.into());
|
||||||
@ -1664,20 +1663,24 @@ impl CharacterAbility {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
CharacterAbility::BasicAura {
|
CharacterAbility::BasicAura {
|
||||||
ref mut aura,
|
ref mut auras,
|
||||||
ref mut range,
|
ref mut range,
|
||||||
ref mut energy_cost,
|
ref mut energy_cost,
|
||||||
specifier: aura::Specifier::WardingAura,
|
specifier: Some(aura::Specifier::WardingAura),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let modifiers = SKILL_MODIFIERS.sceptre_tree.warding_aura;
|
let modifiers = SKILL_MODIFIERS.sceptre_tree.warding_aura;
|
||||||
if let Ok(level) = skillset.skill_level(Sceptre(AStrength)) {
|
if let Ok(level) = skillset.skill_level(Sceptre(AStrength)) {
|
||||||
|
auras.iter_mut().for_each(|ref mut aura| {
|
||||||
aura.strength *= modifiers.strength.powi(level.into());
|
aura.strength *= modifiers.strength.powi(level.into());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if let Ok(level) = skillset.skill_level(Sceptre(ADuration)) {
|
if let Ok(level) = skillset.skill_level(Sceptre(ADuration)) {
|
||||||
|
auras.iter_mut().for_each(|ref mut aura| {
|
||||||
if let Some(ref mut duration) = aura.duration {
|
if let Some(ref mut duration) = aura.duration {
|
||||||
*duration *= modifiers.duration.powi(level.into());
|
*duration *= modifiers.duration.powi(level.into());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if let Ok(level) = skillset.skill_level(Sceptre(ARange)) {
|
if let Ok(level) = skillset.skill_level(Sceptre(ARange)) {
|
||||||
*range *= modifiers.range.powi(level.into());
|
*range *= modifiers.range.powi(level.into());
|
||||||
@ -2085,7 +2088,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
|||||||
cast_duration,
|
cast_duration,
|
||||||
recover_duration,
|
recover_duration,
|
||||||
targets,
|
targets,
|
||||||
aura,
|
auras,
|
||||||
aura_duration,
|
aura_duration,
|
||||||
range,
|
range,
|
||||||
energy_cost: _,
|
energy_cost: _,
|
||||||
@ -2097,7 +2100,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
|||||||
cast_duration: Duration::from_secs_f32(*cast_duration),
|
cast_duration: Duration::from_secs_f32(*cast_duration),
|
||||||
recover_duration: Duration::from_secs_f32(*recover_duration),
|
recover_duration: Duration::from_secs_f32(*recover_duration),
|
||||||
targets: *targets,
|
targets: *targets,
|
||||||
aura: *aura,
|
auras: auras.clone(),
|
||||||
aura_duration: Duration::from_secs_f32(*aura_duration),
|
aura_duration: Duration::from_secs_f32(*aura_duration),
|
||||||
range: *range,
|
range: *range,
|
||||||
ability_info,
|
ability_info,
|
||||||
|
@ -58,7 +58,7 @@ pub enum AuraChange {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Used by the aura system to filter entities when applying an effect.
|
/// Used by the aura system to filter entities when applying an effect.
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
|
||||||
pub enum AuraTarget {
|
pub enum AuraTarget {
|
||||||
/// Targets the group of the entity specified by the `Uid`. This is useful
|
/// Targets the group of the entity specified by the `Uid`. This is useful
|
||||||
/// for auras which should only affect a player's party.
|
/// for auras which should only affect a player's party.
|
||||||
|
@ -694,6 +694,9 @@ impl Body {
|
|||||||
object::Body::Crossbow => 80,
|
object::Body::Crossbow => 80,
|
||||||
object::Body::HaniwaSentry => 60,
|
object::Body::HaniwaSentry => 60,
|
||||||
object::Body::SeaLantern => 100,
|
object::Body::SeaLantern => 100,
|
||||||
|
object::Body::GnarlingTotemRed
|
||||||
|
| object::Body::GnarlingTotemGreen
|
||||||
|
| object::Body::GnarlingTotemWhite => 25,
|
||||||
_ => 1000,
|
_ => 1000,
|
||||||
},
|
},
|
||||||
Body::Golem(golem) => match golem.species {
|
Body::Golem(golem) => match golem.species {
|
||||||
|
@ -95,6 +95,9 @@ make_case_elim!(
|
|||||||
SpitPoison = 80,
|
SpitPoison = 80,
|
||||||
BoltIcicle = 81,
|
BoltIcicle = 81,
|
||||||
Dart = 82,
|
Dart = 82,
|
||||||
|
GnarlingTotemRed = 83,
|
||||||
|
GnarlingTotemGreen = 84,
|
||||||
|
GnarlingTotemWhite = 85,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -105,7 +108,7 @@ impl Body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ALL_OBJECTS: [Body; 83] = [
|
pub const ALL_OBJECTS: [Body; 86] = [
|
||||||
Body::Arrow,
|
Body::Arrow,
|
||||||
Body::Bomb,
|
Body::Bomb,
|
||||||
Body::Scarecrow,
|
Body::Scarecrow,
|
||||||
@ -189,6 +192,9 @@ pub const ALL_OBJECTS: [Body; 83] = [
|
|||||||
Body::SpitPoison,
|
Body::SpitPoison,
|
||||||
Body::BoltIcicle,
|
Body::BoltIcicle,
|
||||||
Body::Dart,
|
Body::Dart,
|
||||||
|
Body::GnarlingTotemRed,
|
||||||
|
Body::GnarlingTotemWhite,
|
||||||
|
Body::GnarlingTotemGreen,
|
||||||
];
|
];
|
||||||
|
|
||||||
impl From<Body> for super::Body {
|
impl From<Body> for super::Body {
|
||||||
@ -281,6 +287,9 @@ impl Body {
|
|||||||
Body::SpitPoison => "spit_poison",
|
Body::SpitPoison => "spit_poison",
|
||||||
Body::BoltIcicle => "bolt_icicle",
|
Body::BoltIcicle => "bolt_icicle",
|
||||||
Body::Dart => "dart",
|
Body::Dart => "dart",
|
||||||
|
Body::GnarlingTotemRed => "gnarling_totem_red",
|
||||||
|
Body::GnarlingTotemGreen => "gnarling_totem_green",
|
||||||
|
Body::GnarlingTotemWhite => "gnarling_totem_white",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,6 +399,7 @@ impl Body {
|
|||||||
Body::Apple => 2.0,
|
Body::Apple => 2.0,
|
||||||
Body::Hive => 2.0,
|
Body::Hive => 2.0,
|
||||||
Body::Coconut => 2.0,
|
Body::Coconut => 2.0,
|
||||||
|
Body::GnarlingTotemRed | Body::GnarlingTotemGreen | Body::GnarlingTotemWhite => 100.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
Mass(m)
|
Mass(m)
|
||||||
@ -407,6 +417,9 @@ impl Body {
|
|||||||
Body::Snowball => Vec3::broadcast(2.5),
|
Body::Snowball => Vec3::broadcast(2.5),
|
||||||
Body::Tornado => Vec3::new(2.0, 2.0, 3.4),
|
Body::Tornado => Vec3::new(2.0, 2.0, 3.4),
|
||||||
Body::TrainingDummy => Vec3::new(1.5, 1.5, 3.0),
|
Body::TrainingDummy => Vec3::new(1.5, 1.5, 3.0),
|
||||||
|
Body::GnarlingTotemRed | Body::GnarlingTotemGreen | Body::GnarlingTotemWhite => {
|
||||||
|
Vec3::new(0.8, 0.8, 1.4)
|
||||||
|
},
|
||||||
// FIXME: this *must* be exhaustive match
|
// FIXME: this *must* be exhaustive match
|
||||||
_ => Vec3::broadcast(0.5),
|
_ => Vec3::broadcast(0.5),
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,10 @@ pub enum BuffKind {
|
|||||||
/// Strength scales the movement speed linearly. 0.5 is 150% speed, 1.0 is
|
/// Strength scales the movement speed linearly. 0.5 is 150% speed, 1.0 is
|
||||||
/// 200% speed. Provides regeneration at 10x the value of the strength
|
/// 200% speed. Provides regeneration at 10x the value of the strength
|
||||||
Frenzied,
|
Frenzied,
|
||||||
|
/// Increases movement and attack speed.
|
||||||
|
/// Strength scales strength of both effects linearly. 0.5 is a 50%
|
||||||
|
/// increase, 1.0 is a 100% increase.
|
||||||
|
Hastened,
|
||||||
// Debuffs
|
// Debuffs
|
||||||
/// Does damage to a creature over time
|
/// Does damage to a creature over time
|
||||||
/// Strength should be the DPS of the debuff
|
/// Strength should be the DPS of the debuff
|
||||||
@ -92,7 +96,8 @@ impl BuffKind {
|
|||||||
| BuffKind::IncreaseMaxEnergy
|
| BuffKind::IncreaseMaxEnergy
|
||||||
| BuffKind::IncreaseMaxHealth
|
| BuffKind::IncreaseMaxHealth
|
||||||
| BuffKind::Invulnerability
|
| BuffKind::Invulnerability
|
||||||
| BuffKind::ProtectingWard => true,
|
| BuffKind::ProtectingWard
|
||||||
|
| BuffKind::Hastened => true,
|
||||||
BuffKind::Bleeding
|
BuffKind::Bleeding
|
||||||
| BuffKind::Cursed
|
| BuffKind::Cursed
|
||||||
| BuffKind::Burning
|
| BuffKind::Burning
|
||||||
@ -347,6 +352,13 @@ impl Buff {
|
|||||||
vec![BuffEffect::MovementSpeed(1.0 - nn_scaling(data.strength))],
|
vec![BuffEffect::MovementSpeed(1.0 - nn_scaling(data.strength))],
|
||||||
data.duration,
|
data.duration,
|
||||||
),
|
),
|
||||||
|
BuffKind::Hastened => (
|
||||||
|
vec![
|
||||||
|
BuffEffect::MovementSpeed(1.0 + data.strength),
|
||||||
|
BuffEffect::AttackSpeed(1.0 + data.strength),
|
||||||
|
],
|
||||||
|
data.duration,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
Buff {
|
Buff {
|
||||||
kind,
|
kind,
|
||||||
|
@ -365,6 +365,15 @@ fn default_main_tool(body: &Body) -> Item {
|
|||||||
object::Body::Tornado => Some(Item::new_from_asset_expect(
|
object::Body::Tornado => Some(Item::new_from_asset_expect(
|
||||||
"common.items.npc_weapons.unique.tornado",
|
"common.items.npc_weapons.unique.tornado",
|
||||||
)),
|
)),
|
||||||
|
object::Body::GnarlingTotemRed => Some(Item::new_from_asset_expect(
|
||||||
|
"common.items.npc_weapons.biped_small.gnarling.redtotem",
|
||||||
|
)),
|
||||||
|
object::Body::GnarlingTotemGreen => Some(Item::new_from_asset_expect(
|
||||||
|
"common.items.npc_weapons.biped_small.gnarling.greentotem",
|
||||||
|
)),
|
||||||
|
object::Body::GnarlingTotemWhite => Some(Item::new_from_asset_expect(
|
||||||
|
"common.items.npc_weapons.biped_small.gnarling.whitetotem",
|
||||||
|
)),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
Body::BipedSmall(biped_small) => match (biped_small.species, biped_small.body_type) {
|
Body::BipedSmall(biped_small) => match (biped_small.species, biped_small.body_type) {
|
||||||
|
@ -16,7 +16,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
/// Separated out to condense update portions of character state
|
/// Separated out to condense update portions of character state
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct StaticData {
|
pub struct StaticData {
|
||||||
/// How long until state should create the aura
|
/// How long until state should create the aura
|
||||||
pub buildup_duration: Duration,
|
pub buildup_duration: Duration,
|
||||||
@ -26,8 +26,8 @@ pub struct StaticData {
|
|||||||
pub recover_duration: Duration,
|
pub recover_duration: Duration,
|
||||||
/// Determines how the aura selects its targets
|
/// Determines how the aura selects its targets
|
||||||
pub targets: GroupTarget,
|
pub targets: GroupTarget,
|
||||||
/// Has information used to construct the aura
|
/// Has information used to construct the auras
|
||||||
pub aura: AuraBuffConstructor,
|
pub auras: Vec<AuraBuffConstructor>,
|
||||||
/// How long aura lasts
|
/// How long aura lasts
|
||||||
pub aura_duration: Duration,
|
pub aura_duration: Duration,
|
||||||
/// Radius of aura
|
/// Radius of aura
|
||||||
@ -39,10 +39,10 @@ pub struct StaticData {
|
|||||||
/// Combo at the time the aura is first cast
|
/// Combo at the time the aura is first cast
|
||||||
pub combo_at_cast: u32,
|
pub combo_at_cast: u32,
|
||||||
/// Used to specify aura to the frontend
|
/// Used to specify aura to the frontend
|
||||||
pub specifier: Specifier,
|
pub specifier: Option<Specifier>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Data {
|
pub struct Data {
|
||||||
/// Struct containing data that does not change over the course of the
|
/// Struct containing data that does not change over the course of the
|
||||||
/// character state
|
/// character state
|
||||||
@ -66,6 +66,7 @@ impl CharacterBehavior for Data {
|
|||||||
if self.timer < self.static_data.buildup_duration {
|
if self.timer < self.static_data.buildup_duration {
|
||||||
// Build up
|
// Build up
|
||||||
update.character = CharacterState::BasicAura(Data {
|
update.character = CharacterState::BasicAura(Data {
|
||||||
|
static_data: self.static_data.clone(),
|
||||||
timer: tick_attack_or_default(data, self.timer, None),
|
timer: tick_attack_or_default(data, self.timer, None),
|
||||||
..*self
|
..*self
|
||||||
});
|
});
|
||||||
@ -73,7 +74,8 @@ impl CharacterBehavior for Data {
|
|||||||
// Creates aura
|
// Creates aura
|
||||||
let targets =
|
let targets =
|
||||||
AuraTarget::from((Some(self.static_data.targets), Some(data.uid)));
|
AuraTarget::from((Some(self.static_data.targets), Some(data.uid)));
|
||||||
let mut aura = self.static_data.aura.to_aura(
|
for aura_data in &self.static_data.auras {
|
||||||
|
let mut aura = aura_data.to_aura(
|
||||||
data.uid,
|
data.uid,
|
||||||
self.static_data.range,
|
self.static_data.range,
|
||||||
Some(self.static_data.aura_duration),
|
Some(self.static_data.aura_duration),
|
||||||
@ -87,8 +89,8 @@ impl CharacterBehavior for Data {
|
|||||||
category: _,
|
category: _,
|
||||||
source: _,
|
source: _,
|
||||||
} => {
|
} => {
|
||||||
data.strength *=
|
data.strength *= 1.0
|
||||||
1.0 + (self.static_data.combo_at_cast.max(1) as f32).log(2.0);
|
+ (self.static_data.combo_at_cast.max(1) as f32).log(2.0);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
output_events.emit_server(ServerEvent::ComboChange {
|
output_events.emit_server(ServerEvent::ComboChange {
|
||||||
@ -100,11 +102,12 @@ impl CharacterBehavior for Data {
|
|||||||
entity: data.entity,
|
entity: data.entity,
|
||||||
aura_change: AuraChange::Add(aura),
|
aura_change: AuraChange::Add(aura),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
// Build up
|
// Build up
|
||||||
update.character = CharacterState::BasicAura(Data {
|
update.character = CharacterState::BasicAura(Data {
|
||||||
|
static_data: self.static_data.clone(),
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
stage_section: StageSection::Action,
|
stage_section: StageSection::Action,
|
||||||
..*self
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -112,20 +115,22 @@ impl CharacterBehavior for Data {
|
|||||||
if self.timer < self.static_data.cast_duration {
|
if self.timer < self.static_data.cast_duration {
|
||||||
// Cast
|
// Cast
|
||||||
update.character = CharacterState::BasicAura(Data {
|
update.character = CharacterState::BasicAura(Data {
|
||||||
|
static_data: self.static_data.clone(),
|
||||||
timer: tick_attack_or_default(data, self.timer, None),
|
timer: tick_attack_or_default(data, self.timer, None),
|
||||||
..*self
|
..*self
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
update.character = CharacterState::BasicAura(Data {
|
update.character = CharacterState::BasicAura(Data {
|
||||||
|
static_data: self.static_data.clone(),
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
stage_section: StageSection::Recover,
|
stage_section: StageSection::Recover,
|
||||||
..*self
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
StageSection::Recover => {
|
StageSection::Recover => {
|
||||||
if self.timer < self.static_data.recover_duration {
|
if self.timer < self.static_data.recover_duration {
|
||||||
update.character = CharacterState::BasicAura(Data {
|
update.character = CharacterState::BasicAura(Data {
|
||||||
|
static_data: self.static_data.clone(),
|
||||||
timer: tick_attack_or_default(data, self.timer, None),
|
timer: tick_attack_or_default(data, self.timer, None),
|
||||||
..*self
|
..*self
|
||||||
});
|
});
|
||||||
|
@ -1742,7 +1742,11 @@ impl<'a> AgentData<'a> {
|
|||||||
"Minotaur" => Tactic::Minotaur,
|
"Minotaur" => Tactic::Minotaur,
|
||||||
"Clay Golem" => Tactic::ClayGolem,
|
"Clay Golem" => Tactic::ClayGolem,
|
||||||
"Tidal Warrior" => Tactic::TidalWarrior,
|
"Tidal Warrior" => Tactic::TidalWarrior,
|
||||||
"Tidal Totem" | "Tornado" => Tactic::RadialTurret,
|
"Tidal Totem"
|
||||||
|
| "Tornado"
|
||||||
|
| "Gnarling Totem Red"
|
||||||
|
| "Gnarling Totem Green"
|
||||||
|
| "Gnarling Totem White" => Tactic::RadialTurret,
|
||||||
"Yeti" => Tactic::Yeti,
|
"Yeti" => Tactic::Yeti,
|
||||||
"Harvester" => Tactic::Harvester,
|
"Harvester" => Tactic::Harvester,
|
||||||
"Gnarling Dagger" => Tactic::SimpleBackstab,
|
"Gnarling Dagger" => Tactic::SimpleBackstab,
|
||||||
@ -1750,6 +1754,7 @@ impl<'a> AgentData<'a> {
|
|||||||
"Deadwood" => Tactic::Deadwood,
|
"Deadwood" => Tactic::Deadwood,
|
||||||
"Mandragora" => Tactic::Mandragora,
|
"Mandragora" => Tactic::Mandragora,
|
||||||
"Wood Golem" => Tactic::WoodGolem,
|
"Wood Golem" => Tactic::WoodGolem,
|
||||||
|
"Gnarling Chieftain" => Tactic::GnarlingChieftain,
|
||||||
_ => Tactic::SimpleMelee,
|
_ => Tactic::SimpleMelee,
|
||||||
},
|
},
|
||||||
AbilitySpec::Tool(tool_kind) => tool_tactic(*tool_kind),
|
AbilitySpec::Tool(tool_kind) => tool_tactic(*tool_kind),
|
||||||
@ -2136,6 +2141,14 @@ impl<'a> AgentData<'a> {
|
|||||||
Tactic::WoodGolem => {
|
Tactic::WoodGolem => {
|
||||||
self.handle_wood_golem(agent, controller, &attack_data, tgt_data, read_data)
|
self.handle_wood_golem(agent, controller, &attack_data, tgt_data, read_data)
|
||||||
},
|
},
|
||||||
|
Tactic::GnarlingChieftain => self.handle_gnarling_chieftain(
|
||||||
|
agent,
|
||||||
|
controller,
|
||||||
|
&attack_data,
|
||||||
|
tgt_data,
|
||||||
|
read_data,
|
||||||
|
rng,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1237,19 +1237,12 @@ impl<'a> AgentData<'a> {
|
|||||||
&self,
|
&self,
|
||||||
_agent: &mut Agent,
|
_agent: &mut Agent,
|
||||||
controller: &mut Controller,
|
controller: &mut Controller,
|
||||||
attack_data: &AttackData,
|
_attack_data: &AttackData,
|
||||||
tgt_data: &TargetData,
|
_tgt_data: &TargetData,
|
||||||
read_data: &ReadData,
|
_read_data: &ReadData,
|
||||||
) {
|
|
||||||
if can_see_tgt(
|
|
||||||
&*read_data.terrain,
|
|
||||||
self.pos,
|
|
||||||
tgt_data.pos,
|
|
||||||
attack_data.dist_sqrd,
|
|
||||||
) {
|
) {
|
||||||
controller.push_basic_input(InputKind::Primary);
|
controller.push_basic_input(InputKind::Primary);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_mindflayer_attack(
|
pub fn handle_mindflayer_attack(
|
||||||
&self,
|
&self,
|
||||||
@ -2246,4 +2239,61 @@ impl<'a> AgentData<'a> {
|
|||||||
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None);
|
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle_gnarling_chieftain(
|
||||||
|
&self,
|
||||||
|
agent: &mut Agent,
|
||||||
|
controller: &mut Controller,
|
||||||
|
attack_data: &AttackData,
|
||||||
|
tgt_data: &TargetData,
|
||||||
|
read_data: &ReadData,
|
||||||
|
rng: &mut impl Rng,
|
||||||
|
) {
|
||||||
|
const TOTEM_TIMER: f32 = 15.0;
|
||||||
|
const HEAVY_ATTACK_WAIT_TIME: f32 = 20.0;
|
||||||
|
|
||||||
|
// Handle timers
|
||||||
|
agent.action_state.timer += read_data.dt.0;
|
||||||
|
match self.char_state {
|
||||||
|
CharacterState::BasicSummon(_) => agent.action_state.timer = 0.0,
|
||||||
|
CharacterState::Shockwave(_) | CharacterState::BasicRanged(_) => {
|
||||||
|
agent.action_state.counter = 0.0
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// If time to summon a totem, do it
|
||||||
|
if agent.action_state.timer > TOTEM_TIMER {
|
||||||
|
let input = rng.gen_range(1..=3);
|
||||||
|
controller.push_basic_input(InputKind::Ability(input));
|
||||||
|
} else if agent.action_state.counter > HEAVY_ATTACK_WAIT_TIME {
|
||||||
|
// Else if time for a heavy attack
|
||||||
|
if attack_data.in_min_range() {
|
||||||
|
// If in range, shockwave
|
||||||
|
controller.push_basic_input(InputKind::Ability(0));
|
||||||
|
} else if can_see_tgt(
|
||||||
|
&read_data.terrain,
|
||||||
|
self.pos,
|
||||||
|
tgt_data.pos,
|
||||||
|
attack_data.dist_sqrd,
|
||||||
|
) {
|
||||||
|
// Else if in sight, barrage
|
||||||
|
controller.push_basic_input(InputKind::Secondary);
|
||||||
|
}
|
||||||
|
} else if attack_data.in_min_range() {
|
||||||
|
// Else if not time to use anything fancy, if in range and angle, strike them
|
||||||
|
if attack_data.angle < 20.0 {
|
||||||
|
controller.push_basic_input(InputKind::Primary);
|
||||||
|
agent.action_state.counter += read_data.dt.0;
|
||||||
|
} else {
|
||||||
|
// If not in angle, charge heavy attack faster
|
||||||
|
agent.action_state.counter += read_data.dt.0 * 5.0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If not in range, charge heavy attack faster
|
||||||
|
agent.action_state.counter += read_data.dt.0 * 3.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.path_toward_target(agent, controller, tgt_data, read_data, false, true, None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,6 +117,7 @@ pub enum Tactic {
|
|||||||
Deadwood,
|
Deadwood,
|
||||||
Mandragora,
|
Mandragora,
|
||||||
WoodGolem,
|
WoodGolem,
|
||||||
|
GnarlingChieftain,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(SystemData)]
|
#[derive(SystemData)]
|
||||||
|
@ -777,7 +777,8 @@ fn insert_killing_buff(buff: BuffKind, localized_strings: &Localization, templat
|
|||||||
| BuffKind::IncreaseMaxHealth
|
| BuffKind::IncreaseMaxHealth
|
||||||
| BuffKind::Invulnerability
|
| BuffKind::Invulnerability
|
||||||
| BuffKind::ProtectingWard
|
| BuffKind::ProtectingWard
|
||||||
| BuffKind::Frenzied => {
|
| BuffKind::Frenzied
|
||||||
|
| BuffKind::Hastened => {
|
||||||
tracing::error!("Player was killed by a positive buff!");
|
tracing::error!("Player was killed by a positive buff!");
|
||||||
localized_strings.get("hud.outcome.mysterious")
|
localized_strings.get("hud.outcome.mysterious")
|
||||||
},
|
},
|
||||||
|
@ -4295,6 +4295,8 @@ pub fn get_buff_image(buff: BuffKind, imgs: &Imgs) -> conrod_core::image::Id {
|
|||||||
BuffKind::Invulnerability => imgs.buff_invincibility_0,
|
BuffKind::Invulnerability => imgs.buff_invincibility_0,
|
||||||
BuffKind::ProtectingWard => imgs.buff_dmg_red_0,
|
BuffKind::ProtectingWard => imgs.buff_dmg_red_0,
|
||||||
BuffKind::Frenzied { .. } => imgs.buff_frenzy_0,
|
BuffKind::Frenzied { .. } => imgs.buff_frenzy_0,
|
||||||
|
// TODO: Get unique icon
|
||||||
|
BuffKind::Hastened { .. } => imgs.buff_frenzy_0,
|
||||||
// Debuffs
|
// Debuffs
|
||||||
BuffKind::Bleeding { .. } => imgs.debuff_bleed_0,
|
BuffKind::Bleeding { .. } => imgs.debuff_bleed_0,
|
||||||
BuffKind::Cursed { .. } => imgs.debuff_skull_0,
|
BuffKind::Cursed { .. } => imgs.debuff_skull_0,
|
||||||
@ -4319,6 +4321,7 @@ pub fn get_buff_title(buff: BuffKind, localized_strings: &Localization) -> &str
|
|||||||
BuffKind::Invulnerability => localized_strings.get("buff.title.invulnerability"),
|
BuffKind::Invulnerability => localized_strings.get("buff.title.invulnerability"),
|
||||||
BuffKind::ProtectingWard => localized_strings.get("buff.title.protectingward"),
|
BuffKind::ProtectingWard => localized_strings.get("buff.title.protectingward"),
|
||||||
BuffKind::Frenzied => localized_strings.get("buff.title.frenzied"),
|
BuffKind::Frenzied => localized_strings.get("buff.title.frenzied"),
|
||||||
|
BuffKind::Hastened => localized_strings.get("buff.title.hastened"),
|
||||||
// Debuffs
|
// Debuffs
|
||||||
BuffKind::Bleeding { .. } => localized_strings.get("buff.title.bleed"),
|
BuffKind::Bleeding { .. } => localized_strings.get("buff.title.bleed"),
|
||||||
BuffKind::Cursed { .. } => localized_strings.get("buff.title.cursed"),
|
BuffKind::Cursed { .. } => localized_strings.get("buff.title.cursed"),
|
||||||
@ -4355,6 +4358,7 @@ pub fn get_buff_desc(buff: BuffKind, data: BuffData, localized_strings: &Localiz
|
|||||||
Cow::Borrowed(localized_strings.get("buff.desc.protectingward"))
|
Cow::Borrowed(localized_strings.get("buff.desc.protectingward"))
|
||||||
},
|
},
|
||||||
BuffKind::Frenzied => Cow::Borrowed(localized_strings.get("buff.desc.frenzied")),
|
BuffKind::Frenzied => Cow::Borrowed(localized_strings.get("buff.desc.frenzied")),
|
||||||
|
BuffKind::Hastened => Cow::Borrowed(localized_strings.get("buff.desc.hastened")),
|
||||||
// Debuffs
|
// Debuffs
|
||||||
BuffKind::Bleeding { .. } => Cow::Borrowed(localized_strings.get("buff.desc.bleed")),
|
BuffKind::Bleeding { .. } => Cow::Borrowed(localized_strings.get("buff.desc.bleed")),
|
||||||
BuffKind::Cursed { .. } => Cow::Borrowed(localized_strings.get("buff.desc.cursed")),
|
BuffKind::Cursed { .. } => Cow::Borrowed(localized_strings.get("buff.desc.cursed")),
|
||||||
|
@ -173,7 +173,8 @@ pub fn consumable_desc(effects: &[Effect], i18n: &Localization) -> Vec<String> {
|
|||||||
| BuffKind::Frozen
|
| BuffKind::Frozen
|
||||||
| BuffKind::Wet
|
| BuffKind::Wet
|
||||||
| BuffKind::Ensnared
|
| BuffKind::Ensnared
|
||||||
| BuffKind::Poisoned => "".to_owned(),
|
| BuffKind::Poisoned
|
||||||
|
| BuffKind::Hastened => "".to_owned(),
|
||||||
};
|
};
|
||||||
|
|
||||||
write!(&mut description, "{}", buff_desc).unwrap();
|
write!(&mut description, "{}", buff_desc).unwrap();
|
||||||
@ -199,7 +200,8 @@ pub fn consumable_desc(effects: &[Effect], i18n: &Localization) -> Vec<String> {
|
|||||||
| BuffKind::Frozen
|
| BuffKind::Frozen
|
||||||
| BuffKind::Wet
|
| BuffKind::Wet
|
||||||
| BuffKind::Ensnared
|
| BuffKind::Ensnared
|
||||||
| BuffKind::Poisoned => "".to_owned(),
|
| BuffKind::Poisoned
|
||||||
|
| BuffKind::Hastened => "".to_owned(),
|
||||||
}
|
}
|
||||||
} else if let BuffKind::Saturation | BuffKind::Regeneration = buff.kind {
|
} else if let BuffKind::Saturation | BuffKind::Regeneration = buff.kind {
|
||||||
i18n.get("buff.text.every_second").to_string()
|
i18n.get("buff.text.every_second").to_string()
|
||||||
|
@ -967,7 +967,7 @@ impl Site {
|
|||||||
PlotKind::Workshop(workshop) => workshop.render_collect(self, canvas),
|
PlotKind::Workshop(workshop) => workshop.render_collect(self, canvas),
|
||||||
PlotKind::Castle(castle) => castle.render_collect(self, canvas),
|
PlotKind::Castle(castle) => castle.render_collect(self, canvas),
|
||||||
PlotKind::Dungeon(dungeon) => dungeon.render_collect(self, canvas),
|
PlotKind::Dungeon(dungeon) => dungeon.render_collect(self, canvas),
|
||||||
PlotKind::Gnarling(gnarling) => gnarling.render_collect(self, &canvas),
|
PlotKind::Gnarling(gnarling) => gnarling.render_collect(self, canvas),
|
||||||
PlotKind::GiantTree(giant_tree) => giant_tree.render_collect(self, canvas),
|
PlotKind::GiantTree(giant_tree) => giant_tree.render_collect(self, canvas),
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
|
@ -529,7 +529,7 @@ impl Structure for GnarlingFortification {
|
|||||||
wall_par_thickness,
|
wall_par_thickness,
|
||||||
wall_par_height + parapet_z_offset as f32,
|
wall_par_height + parapet_z_offset as f32,
|
||||||
)
|
)
|
||||||
.fill(darkwood.clone());
|
.fill(darkwood);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,14 +584,14 @@ impl Structure for GnarlingFortification {
|
|||||||
tower_radius - 3.0,
|
tower_radius - 3.0,
|
||||||
tower_height,
|
tower_height,
|
||||||
))
|
))
|
||||||
.fill(darkwood.clone());
|
.fill(darkwood);
|
||||||
painter
|
painter
|
||||||
.prim(Primitive::cylinder(
|
.prim(Primitive::cylinder(
|
||||||
wpos.with_z(land.get_alt_approx(wpos) as i32),
|
wpos.with_z(land.get_alt_approx(wpos) as i32),
|
||||||
tower_radius - 4.0,
|
tower_radius - 4.0,
|
||||||
tower_height,
|
tower_height,
|
||||||
))
|
))
|
||||||
.fill(midwood.clone());
|
.fill(midwood);
|
||||||
//top layer, green above the tower
|
//top layer, green above the tower
|
||||||
painter
|
painter
|
||||||
.prim(Primitive::cylinder(
|
.prim(Primitive::cylinder(
|
||||||
@ -599,7 +599,7 @@ impl Structure for GnarlingFortification {
|
|||||||
tower_radius,
|
tower_radius,
|
||||||
2.0,
|
2.0,
|
||||||
))
|
))
|
||||||
.fill(moss.clone());
|
.fill(moss);
|
||||||
//standing area one block deeper
|
//standing area one block deeper
|
||||||
painter
|
painter
|
||||||
.prim(Primitive::cylinder(
|
.prim(Primitive::cylinder(
|
||||||
@ -705,7 +705,7 @@ impl Structure for GnarlingFortification {
|
|||||||
.with_z(land.get_alt_approx(wpos) as i32 + tower_height as i32 - 16),
|
.with_z(land.get_alt_approx(wpos) as i32 + tower_height as i32 - 16),
|
||||||
})
|
})
|
||||||
.intersect(outside)
|
.intersect(outside)
|
||||||
.fill(red.clone());
|
.fill(red);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.structure_locations
|
self.structure_locations
|
||||||
@ -763,14 +763,14 @@ impl Structure for GnarlingFortification {
|
|||||||
hut_radius - 2.0,
|
hut_radius - 2.0,
|
||||||
hut_wall_height + 3.0,
|
hut_wall_height + 3.0,
|
||||||
))
|
))
|
||||||
.fill(midwood.clone());
|
.fill(midwood);
|
||||||
painter
|
painter
|
||||||
.prim(Primitive::cylinder(
|
.prim(Primitive::cylinder(
|
||||||
floor_pos,
|
floor_pos,
|
||||||
hut_radius - 3.0,
|
hut_radius - 3.0,
|
||||||
hut_wall_height + 3.0,
|
hut_wall_height + 3.0,
|
||||||
))
|
))
|
||||||
.fill(darkwood.clone());
|
.fill(darkwood);
|
||||||
painter
|
painter
|
||||||
.prim(Primitive::cylinder(
|
.prim(Primitive::cylinder(
|
||||||
floor_pos,
|
floor_pos,
|
||||||
@ -832,7 +832,7 @@ impl Structure for GnarlingFortification {
|
|||||||
let tendril4 = tendril1.translate(Vec3::new(7, 4, 0));
|
let tendril4 = tendril1.translate(Vec3::new(7, 4, 0));
|
||||||
let tendrils = tendril1.union(tendril2).union(tendril3).union(tendril4);
|
let tendrils = tendril1.union(tendril2).union(tendril3).union(tendril4);
|
||||||
|
|
||||||
tendrils.fill(moss.clone());
|
tendrils.fill(moss);
|
||||||
|
|
||||||
//sphere to delete some hut
|
//sphere to delete some hut
|
||||||
painter
|
painter
|
||||||
@ -917,7 +917,7 @@ impl Structure for GnarlingFortification {
|
|||||||
let floor2_pos = wpos.with_z(alt + 1 + raise + height_1 as i32);
|
let floor2_pos = wpos.with_z(alt + 1 + raise + height_1 as i32);
|
||||||
painter
|
painter
|
||||||
.prim(Primitive::cylinder(floor2_pos, rad_2, height_2))
|
.prim(Primitive::cylinder(floor2_pos, rad_2, height_2))
|
||||||
.fill(midwood.clone());
|
.fill(midwood);
|
||||||
|
|
||||||
// Roof
|
// Roof
|
||||||
let roof_radius = rad_1 + 5.0;
|
let roof_radius = rad_1 + 5.0;
|
||||||
@ -934,7 +934,7 @@ impl Structure for GnarlingFortification {
|
|||||||
roof_radius,
|
roof_radius,
|
||||||
roof_height,
|
roof_height,
|
||||||
))
|
))
|
||||||
.fill(moss.clone());
|
.fill(moss);
|
||||||
let centerspot = painter.line(
|
let centerspot = painter.line(
|
||||||
(wpos + 1).with_z(alt + raise + height_1 as i32 + 2),
|
(wpos + 1).with_z(alt + raise + height_1 as i32 + 2),
|
||||||
(wpos + 1).with_z(alt + raise + height_1 as i32 + 2),
|
(wpos + 1).with_z(alt + raise + height_1 as i32 + 2),
|
||||||
@ -1094,7 +1094,7 @@ impl Structure for GnarlingFortification {
|
|||||||
})
|
})
|
||||||
.intersect(roof1)
|
.intersect(roof1)
|
||||||
.translate(Vec3::new(0, 0, -1))
|
.translate(Vec3::new(0, 0, -1))
|
||||||
.fill(darkwood.clone());
|
.fill(darkwood);
|
||||||
painter
|
painter
|
||||||
.aabb(Aabb {
|
.aabb(Aabb {
|
||||||
min: Vec2::new(wpos.x - 2, wpos.y - 23)
|
min: Vec2::new(wpos.x - 2, wpos.y - 23)
|
||||||
@ -1103,7 +1103,7 @@ impl Structure for GnarlingFortification {
|
|||||||
.with_z(alt + raise + height_1 as i32 + 7),
|
.with_z(alt + raise + height_1 as i32 + 7),
|
||||||
})
|
})
|
||||||
.intersect(roof1)
|
.intersect(roof1)
|
||||||
.fill(red.clone());
|
.fill(red);
|
||||||
painter
|
painter
|
||||||
.prim(Primitive::cylinder(floor2_pos, rad_2 - 1.0, height_2))
|
.prim(Primitive::cylinder(floor2_pos, rad_2 - 1.0, height_2))
|
||||||
.fill(Fill::Block(Block::empty()));
|
.fill(Fill::Block(Block::empty()));
|
||||||
@ -1167,8 +1167,8 @@ impl Structure for GnarlingFortification {
|
|||||||
let roof = low1.union(low2).union(top1).union(top2);
|
let roof = low1.union(low2).union(top1).union(top2);
|
||||||
let roofmoss = roof.translate(Vec3::new(0, 0, 1)).without(top).without(low);
|
let roofmoss = roof.translate(Vec3::new(0, 0, 1)).without(top).without(low);
|
||||||
top.fill(darkwood.clone());
|
top.fill(darkwood.clone());
|
||||||
low.fill(midwood.clone());
|
low.fill(midwood);
|
||||||
roofmoss.fill(moss.clone());
|
roofmoss.fill(moss);
|
||||||
painter
|
painter
|
||||||
.prim(Primitive::sphere(
|
.prim(Primitive::sphere(
|
||||||
Vec2::new(wpos.x + randy - 5, wpos.y + randz - 5)
|
Vec2::new(wpos.x + randy - 5, wpos.y + randz - 5)
|
||||||
@ -1331,7 +1331,7 @@ impl Structure for GnarlingFortification {
|
|||||||
min: Vec2::new(wpos.x + 1, wpos.y - 1).with_z(alt + 8),
|
min: Vec2::new(wpos.x + 1, wpos.y - 1).with_z(alt + 8),
|
||||||
max: Vec2::new(wpos.x + 8, wpos.y).with_z(alt + 38),
|
max: Vec2::new(wpos.x + 8, wpos.y).with_z(alt + 38),
|
||||||
});
|
});
|
||||||
flag.fill(red.clone());
|
flag.fill(red);
|
||||||
//add green streaks
|
//add green streaks
|
||||||
let streak1 = painter
|
let streak1 = painter
|
||||||
.line(
|
.line(
|
||||||
@ -1404,7 +1404,7 @@ impl Structure for GnarlingFortification {
|
|||||||
0.9,
|
0.9,
|
||||||
);
|
);
|
||||||
let flagpole = column.union(arm);
|
let flagpole = column.union(arm);
|
||||||
flagpole.fill(darkwood.clone());
|
flagpole.fill(darkwood);
|
||||||
},
|
},
|
||||||
GnarlingStructure::WatchTower => {
|
GnarlingStructure::WatchTower => {
|
||||||
let platform_1_height = 14;
|
let platform_1_height = 14;
|
||||||
|
Loading…
Reference in New Issue
Block a user