Various fixes to object animation, cleanup

This commit is contained in:
Snowram 2021-01-30 15:14:25 +01:00
parent f25b2b1500
commit 4078eeb877
29 changed files with 519 additions and 1672 deletions

View File

@ -0,0 +1,15 @@
BasicRanged(
energy_cost: 0,
buildup_duration: 1.0,
recover_duration: 0.3,
projectile: Arrow(
damage: 200.0,
knockback: 5.0,
energy_regen: 100,
),
projectile_body: Object(ArrowTurret),
projectile_light: None,
projectile_gravity: Some(Gravity(0.1)),
projectile_speed: 100.0,
can_continue: true,
)

View File

@ -1,12 +1,12 @@
BasicBeam( BasicBeam(
buildup_duration: 250, buildup_duration: 0.25,
recover_duration: 250, recover_duration: 0.25,
beam_duration: 500, beam_duration: 0.5,
base_hps: 0, base_hps: 0,
base_dps: 150, base_dps: 9001,
tick_rate: 3.0, tick_rate: 3.0,
range: 30.0, range: 30.0,
max_angle: 5.0, max_angle: 1.0,
lifesteal_eff: 0.0, lifesteal_eff: 0.0,
energy_regen: 0, energy_regen: 0,
energy_cost: 0, energy_cost: 0,

View File

@ -132,10 +132,10 @@
secondary: "common.abilities.unique.theropodbird.triplestrike", secondary: "common.abilities.unique.theropodbird.triplestrike",
abilities: [], abilities: [],
), ),
Unique(Turret): ( Unique(ObjectTurret): (
primary: "common.abilities.unique.turret.basic", primary: "common.abilities.unique.turret.arrows",
secondary: "common.abilities.unique.turret.basic", secondary: "common.abilities.unique.turret.arrows",
skills: [], abilities: [],
), ),
Debug: ( Debug: (
primary: "common.abilities.debug.forwardboost", primary: "common.abilities.debug.forwardboost",

View File

@ -3,13 +3,16 @@ ItemDef(
description: "Turret weapon", description: "Turret weapon",
kind: Tool( kind: Tool(
( (
kind: Unique(Turret), kind: Unique(ObjectTurret),
stats: ( hands: Two,
stats: Direct((
equip_time_millis: 10, equip_time_millis: 10,
power: 1.00, power: 1.00,
poise_strength: 1.00,
speed: 1.00, speed: 1.00,
), )),
) )
), ),
quality: Low, quality: Low,
tags: [],
) )

BIN
assets/voxygen/voxel/object/crossbow.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/voxel/object/crossbow/bone0.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/object/crossbow/bone1.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -3,390 +3,650 @@
bone0: ( bone0: (
offset: (-0.5, -6.0, -1.5), offset: (-0.5, -6.0, -1.5),
central: ("weapon.projectile.simple-arrow"), central: ("weapon.projectile.simple-arrow"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Bomb: ( Bomb: (
bone0: ( bone0: (
offset: (-5.5, -5.5, 0.0), offset: (-5.5, -5.5, 0.0),
central: ("object.bomb"), central: ("object.bomb"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
FireworkBlue: ( FireworkBlue: (
bone0: ( bone0: (
offset: (0.0, 0.0, 0.0), offset: (0.0, 0.0, 0.0),
central: ("weapon.projectile.fireworks_blue-0"), central: ("weapon.projectile.fireworks_blue-0"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
FireworkGreen: ( FireworkGreen: (
bone0: ( bone0: (
offset: (0.0, 0.0, 0.0), offset: (0.0, 0.0, 0.0),
central: ("weapon.projectile.fireworks_green-0"), central: ("weapon.projectile.fireworks_green-0"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
FireworkPurple: ( FireworkPurple: (
bone0: ( bone0: (
offset: (0.0, 0.0, 0.0), offset: (0.0, 0.0, 0.0),
central: ("weapon.projectile.fireworks_purple-0"), central: ("weapon.projectile.fireworks_purple-0"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
FireworkRed: ( FireworkRed: (
bone0: ( bone0: (
offset: (0.0, 0.0, 0.0), offset: (0.0, 0.0, 0.0),
central: ("weapon.projectile.fireworks_red-0"), central: ("weapon.projectile.fireworks_red-0"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
FireworkYellow: ( FireworkYellow: (
bone0: ( bone0: (
offset: (0.0, 0.0, 0.0), offset: (0.0, 0.0, 0.0),
central: ("weapon.projectile.fireworks_yellow-0"), central: ("weapon.projectile.fireworks_yellow-0"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Scarecrow: ( Scarecrow: (
bone0: ( bone0: (
offset: (-9.5, -4.0, 0.0), offset: (-9.5, -4.0, 0.0),
central: ("object.scarecrow"), central: ("object.scarecrow"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Cauldron: ( Cauldron: (
bone0: ( bone0: (
offset: (-10.0, -10.0, 0.0), offset: (-10.0, -10.0, 0.0),
central: ("object.cauldron"), central: ("object.cauldron"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
ChestVines: ( ChestVines: (
bone0: ( bone0: (
offset: (-7.5, -6.0, 0.0), offset: (-7.5, -6.0, 0.0),
central: ("object.chest_vines"), central: ("object.chest_vines"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Chest: ( Chest: (
bone0: ( bone0: (
offset: (-7.5, -6.0, 0.0), offset: (-7.5, -6.0, 0.0),
central: ("object.chest"), central: ("object.chest"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
ChestDark: ( ChestDark: (
bone0: ( bone0: (
offset: (-7.5, -6.0, 0.0), offset: (-7.5, -6.0, 0.0),
central: ("object.chest_dark"), central: ("object.chest_dark"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
ChestDemon: ( ChestDemon: (
bone0: ( bone0: (
offset: (-7.5, -6.0, 0.0), offset: (-7.5, -6.0, 0.0),
central: ("object.chest_demon"), central: ("object.chest_demon"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
ChestGold: ( ChestGold: (
bone0: ( bone0: (
offset: (-7.5, -6.0, 0.0), offset: (-7.5, -6.0, 0.0),
central: ("object.chest_gold"), central: ("object.chest_gold"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
ChestLight: ( ChestLight: (
bone0: ( bone0: (
offset: (-7.5, -6.0, 0.0), offset: (-7.5, -6.0, 0.0),
central: ("object.chest_light"), central: ("object.chest_light"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
ChestOpen: ( ChestOpen: (
bone0: ( bone0: (
offset: (-7.5, -6.0, 0.0), offset: (-7.5, -6.0, 0.0),
central: ("object.chest_open"), central: ("object.chest_open"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
ChestSkull: ( ChestSkull: (
bone0: ( bone0: (
offset: (-7.5, -6.0, 0.0), offset: (-7.5, -6.0, 0.0),
central: ("object.chest_skull"), central: ("object.chest_skull"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Pumpkin: ( Pumpkin: (
bone0: ( bone0: (
offset: (-5.5, -4.0, 0.0), offset: (-5.5, -4.0, 0.0),
central: ("object.pumpkin"), central: ("object.pumpkin"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Pumpkin2: ( Pumpkin2: (
bone0: ( bone0: (
offset: (-5.0, -4.0, 0.0), offset: (-5.0, -4.0, 0.0),
central: ("object.pumpkin_2"), central: ("object.pumpkin_2"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Pumpkin3: ( Pumpkin3: (
bone0: ( bone0: (
offset: (-5.0, -4.0, 0.0), offset: (-5.0, -4.0, 0.0),
central: ("object.pumpkin_3"), central: ("object.pumpkin_3"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Pumpkin4: ( Pumpkin4: (
bone0: ( bone0: (
offset: (-5.0, -4.0, 0.0), offset: (-5.0, -4.0, 0.0),
central: ("object.pumpkin_4"), central: ("object.pumpkin_4"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Pumpkin5: ( Pumpkin5: (
bone0: ( bone0: (
offset: (-4.0, -5.0, 0.0), offset: (-4.0, -5.0, 0.0),
central: ("object.pumpkin_5"), central: ("object.pumpkin_5"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Campfire: ( Campfire: (
bone0: ( bone0: (
offset: (-9.0, -10.0, 0.0), offset: (-9.0, -10.0, 0.0),
central: ("object.campfire"), central: ("object.campfire"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
CampfireLit: ( CampfireLit: (
bone0: ( bone0: (
offset: (-9.0, -10.0, 0.0), offset: (-9.0, -10.0, 0.0),
central: ("object.campfire_lit"), central: ("object.campfire_lit"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
LanternGround: ( LanternGround: (
bone0: ( bone0: (
offset: (-3.5, -3.5, 0.0), offset: (-3.5, -3.5, 0.0),
central: ("object.lantern_ground"), central: ("object.lantern_ground"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
LanternGroundOpen: ( LanternGroundOpen: (
bone0: ( bone0: (
offset: (-3.5, -3.5, 0.0), offset: (-3.5, -3.5, 0.0),
central: ("object.lantern_ground_open"), central: ("object.lantern_ground_open"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
LanternStanding: ( LanternStanding: (
bone0: ( bone0: (
offset: (-7.5, -3.5, 0.0), offset: (-7.5, -3.5, 0.0),
central: ("object.lantern_standing"), central: ("object.lantern_standing"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
LanternStanding2: ( LanternStanding2: (
bone0: ( bone0: (
offset: (-11.5, -3.5, 0.0), offset: (-11.5, -3.5, 0.0),
central: ("object.lantern_standing_2"), central: ("object.lantern_standing_2"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
PotionRed: ( PotionRed: (
bone0: ( bone0: (
offset: (-2.0, -2.0, 0.0), offset: (-2.0, -2.0, 0.0),
central: ("object.potion_red"), central: ("object.potion_red"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
PotionBlue: ( PotionBlue: (
bone0: ( bone0: (
offset: (-2.0, -2.0, 0.0), offset: (-2.0, -2.0, 0.0),
central: ("object.potion_blue"), central: ("object.potion_blue"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
PotionGreen: ( PotionGreen: (
bone0: ( bone0: (
offset: (-2.0, -2.0, 0.0), offset: (-2.0, -2.0, 0.0),
central: ("object.potion_green"), central: ("object.potion_green"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Crate: ( Crate: (
bone0: ( bone0: (
offset: (-7.0, -7.0, 0.0), offset: (-7.0, -7.0, 0.0),
central: ("object.crate"), central: ("object.crate"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Tent: ( Tent: (
bone0: ( bone0: (
offset: (-18.5, -19.5, 0.0), offset: (-18.5, -19.5, 0.0),
central: ("object.tent"), central: ("object.tent"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
WindowSpooky: ( WindowSpooky: (
bone0: ( bone0: (
offset: (-15.0, -1.5, -1.0), offset: (-15.0, -1.5, -1.0),
central: ("object.window_spooky"), central: ("object.window_spooky"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
DoorSpooky: ( DoorSpooky: (
bone0: ( bone0: (
offset: (-15.0, -4.5, 0.0), offset: (-15.0, -4.5, 0.0),
central: ("object.door_spooky"), central: ("object.door_spooky"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Table: ( Table: (
bone0: ( bone0: (
offset: (-12.0, -8.0, 0.0), offset: (-12.0, -8.0, 0.0),
central: ("object.table"), central: ("object.table"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Table2: ( Table2: (
bone0: ( bone0: (
offset: (-8.0, -8.0, 0.0), offset: (-8.0, -8.0, 0.0),
central: ("object.table_2"), central: ("object.table_2"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Table3: ( Table3: (
bone0: ( bone0: (
offset: (-10.0, -10.0, 0.0), offset: (-10.0, -10.0, 0.0),
central: ("object.table_3"), central: ("object.table_3"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Drawer: ( Drawer: (
bone0: ( bone0: (
offset: (-11.0, -7.5, 0.0), offset: (-11.0, -7.5, 0.0),
central: ("object.drawer"), central: ("object.drawer"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
BedBlue: ( BedBlue: (
bone0: ( bone0: (
offset: (-11.0, -15.0, 0.0), offset: (-11.0, -15.0, 0.0),
central: ("object.bed_human_blue"), central: ("object.bed_human_blue"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Anvil: ( Anvil: (
bone0: ( bone0: (
offset: (-3.0, -7.0, 0.0), offset: (-3.0, -7.0, 0.0),
central: ("object.anvil"), central: ("object.anvil"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Gravestone: ( Gravestone: (
bone0: ( bone0: (
offset: (-5.0, -2.0, 0.0), offset: (-5.0, -2.0, 0.0),
central: ("object.gravestone"), central: ("object.gravestone"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Gravestone2: ( Gravestone2: (
bone0: ( bone0: (
offset: (-8.5, -3.0, 0.0), offset: (-8.5, -3.0, 0.0),
central: ("object.gravestone_2"), central: ("object.gravestone_2"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Chair: ( Chair: (
bone0: ( bone0: (
offset: (-5.0, -4.5, 0.0), offset: (-5.0, -4.5, 0.0),
central: ("object.chair"), central: ("object.chair"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Chair2: ( Chair2: (
bone0: ( bone0: (
offset: (-5.0, -4.5, 0.0), offset: (-5.0, -4.5, 0.0),
central: ("object.chair_2"), central: ("object.chair_2"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Chair3: ( Chair3: (
bone0: ( bone0: (
offset: (-5.0, -4.5, 0.0), offset: (-5.0, -4.5, 0.0),
central: ("object.chair_3"), central: ("object.chair_3"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Bench: ( Bench: (
bone0: ( bone0: (
offset: (-8.8, -5.0, 0.0), offset: (-8.8, -5.0, 0.0),
central: ("object.bench"), central: ("object.bench"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Carpet: ( Carpet: (
bone0: ( bone0: (
offset: (-14.0, -14.0, -0.5), offset: (-14.0, -14.0, -0.5),
central: ("object.carpet"), central: ("object.carpet"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Bedroll: ( Bedroll: (
bone0: ( bone0: (
offset: (-11.0, -19.5, -0.5), offset: (-11.0, -19.5, -0.5),
central: ("object.bedroll"), central: ("object.bedroll"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
CarpetHumanRound: ( CarpetHumanRound: (
bone0: ( bone0: (
offset: (-14.0, -14.0, -0.5), offset: (-14.0, -14.0, -0.5),
central: ("object.carpet_human_round"), central: ("object.carpet_human_round"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
CarpetHumanSquare: ( CarpetHumanSquare: (
bone0: ( bone0: (
offset: (-13.5, -14.0, -0.5), offset: (-13.5, -14.0, -0.5),
central: ("object.carpet_human_square"), central: ("object.carpet_human_square"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
CarpetHumanSquare2: ( CarpetHumanSquare2: (
bone0: ( bone0: (
offset: (-13.5, -14.0, -0.5), offset: (-13.5, -14.0, -0.5),
central: ("object.carpet_human_square_2"), central: ("object.carpet_human_square_2"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
CarpetHumanSquircle: ( CarpetHumanSquircle: (
bone0: ( bone0: (
offset: (-21.0, -21.0, -0.5), offset: (-21.0, -21.0, -0.5),
central: ("object.carpet_human_squircle"), central: ("object.carpet_human_squircle"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Pouch: ( Pouch: (
bone0: ( bone0: (
offset: (-5.5, -4.5, 0.0), offset: (-5.5, -4.5, 0.0),
central: ("object.pouch"), central: ("object.pouch"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
CraftingBench: ( CraftingBench: (
bone0: ( bone0: (
offset: (-9.5, -7.0, 0.0), offset: (-9.5, -7.0, 0.0),
central: ("object.crafting_bench"), central: ("object.crafting_bench"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
ArrowSnake: ( ArrowSnake: (
bone0: ( bone0: (
offset: (-1.5, -6.5, 0.0), offset: (-1.5, -6.5, 0.0),
central: ("weapon.projectile.snake-arrow"), central: ("weapon.projectile.snake-arrow"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
BoltFire: ( BoltFire: (
bone0: ( bone0: (
offset: (-3.0, -5.5, -3.0), offset: (-3.0, -5.5, -3.0),
central: ("weapon.projectile.fire-bolt-0"), central: ("weapon.projectile.fire-bolt-0"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
BoltFireBig: ( BoltFireBig: (
bone0: ( bone0: (
offset: (-6.0, -6.0, -6.0), offset: (-6.0, -6.0, -6.0),
central: ("weapon.projectile.fire-bolt-1"), central: ("weapon.projectile.fire-bolt-1"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
TrainingDummy: ( TrainingDummy: (
bone0: ( bone0: (
offset: (-7.0, -5.0, 0.0), offset: (-7.0, -5.0, 0.0),
central: ("object.training_dummy"), central: ("object.training_dummy"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
MultiArrow: ( MultiArrow: (
bone0: ( bone0: (
offset: (-4.0, -9.5, -5.0), offset: (-4.0, -9.5, -5.0),
central: ("weapon.projectile.multi-arrow"), central: ("weapon.projectile.multi-arrow"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
BoltNature: ( BoltNature: (
bone0: ( bone0: (
offset: (-6.0, -6.0, -6.0), offset: (-6.0, -6.0, -6.0),
central: ("weapon.projectile.nature-bolt"), central: ("weapon.projectile.nature-bolt"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
MeatDrop: ( MeatDrop: (
bone0: ( bone0: (
offset: (-3.5, -8.0, 0.0), offset: (-3.5, -8.0, 0.0),
central: ("object.meat_drop"), central: ("object.meat_drop"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Steak: ( Steak: (
bone0: ( bone0: (
offset: (-3.5, -6.0, 0.0), offset: (-3.5, -6.0, 0.0),
central: ("object.steak"), central: ("object.steak"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
Crossbow: ( Crossbow: (
bone0: ( bone0: (
offset: (-18.0, -15.5, 0.0), offset: (-18.0, -15.5, -8.0),
central: ("object.crossbow"), central: ("object.crossbow.bone0"),
),
bone1: (
offset: (-9.0, -7.0, -5.0 ),
central: ("object.crossbow.bone1"),
) )
), ),
ArrowTurret: ( ArrowTurret: (
bone0: ( bone0: (
offset: (-1.5, -6.5, -1.5), offset: (-1.5, -6.5, -1.5),
central: ("weapon.projectile.turret-arrow"), central: ("weapon.projectile.turret-arrow"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
) )
), ),
}) })

View File

@ -222,9 +222,9 @@ pub enum CharacterAbility {
range: f32, range: f32,
max_angle: f32, max_angle: f32,
lifesteal_eff: f32, lifesteal_eff: f32,
energy_regen: u32, energy_regen: f32,
energy_cost: u32, energy_cost: f32,
energy_drain: u32, energy_drain: f32,
orientation_behavior: basic_beam::MovementBehavior, orientation_behavior: basic_beam::MovementBehavior,
}, },
} }

View File

@ -29,6 +29,9 @@ pub enum Tactic {
QuadMedBasic, QuadMedBasic,
Lavadrake, Lavadrake,
Theropod, Theropod,
Turret,
FixedTurret,
RotatingTurret,
} }
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]

View File

@ -339,7 +339,11 @@ impl Body {
biped_large::Species::Mindflayer => 8000, biped_large::Species::Mindflayer => 8000,
_ => 1000, _ => 1000,
}, },
Body::Object(_) => 10000, Body::Object(object) => match object {
object::Body::TrainingDummy => 10000,
object::Body::Crossbow => 800,
_ => 10000,
},
Body::Golem(_) => 2740, Body::Golem(_) => 2740,
Body::Theropod(theropod) => match theropod.species { Body::Theropod(theropod) => match theropod.species {
theropod::Species::Archaeos => 3000, theropod::Species::Archaeos => 3000,

View File

@ -295,5 +295,5 @@ pub enum UniqueKind {
QuadSmallBasic, QuadSmallBasic,
TheropodBasic, TheropodBasic,
TheropodBird, TheropodBird,
Turret, ObjectTurret,
} }

View File

@ -227,16 +227,12 @@ impl LoadoutBuilder {
)); ));
}, },
}, },
#[allow(clippy::collapsible_match)] // to be removed when more entries are added Body::Object(object::Body::Crossbow) => {
Body::Object(object) => match object {
object::Body::Crossbow => {
main_tool = Some(Item::new_from_asset_expect( main_tool = Some(Item::new_from_asset_expect(
"common.items.npc_weapons.unique.turret", "common.items.npc_weapons.unique.turret",
)); ));
}, },
_ => {}, _ => {},
},
_ => {},
}; };
} }

View File

@ -10,7 +10,6 @@ use crate::{
utils::*, utils::*,
}, },
uid::Uid, uid::Uid,
Damage, DamageSource, GroupTarget,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::time::Duration; use std::time::Duration;
@ -43,7 +42,7 @@ pub struct StaticData {
/// Energy consumed per second for heal ticks /// Energy consumed per second for heal ticks
pub energy_cost: f32, pub energy_cost: f32,
/// Energy drained per /// Energy drained per
pub energy_drain: u32, pub energy_drain: f32,
/// Used to dictate how orientation functions in this state /// Used to dictate how orientation functions in this state
pub orientation_behavior: MovementBehavior, pub orientation_behavior: MovementBehavior,
/// What key is used to press ability /// What key is used to press ability
@ -70,7 +69,7 @@ impl CharacterBehavior for Data {
match self.static_data.orientation_behavior { match self.static_data.orientation_behavior {
MovementBehavior::Normal => {}, MovementBehavior::Normal => {},
MovementBehavior::Turret => { MovementBehavior::Turret => {
update.ori.0 = data.inputs.look_dir; update.ori = Ori::from(data.inputs.look_dir);
}, },
} }
@ -106,8 +105,8 @@ impl CharacterBehavior for Data {
}); });
// Gets offsets // Gets offsets
let body_offsets = Vec3::new( let body_offsets = Vec3::new(
(data.body.radius() + 1.0) * data.ori.0.x, (data.body.radius() + 1.0) * data.inputs.look_dir.x,
(data.body.radius() + 1.0) * data.ori.0.y, (data.body.radius() + 1.0) * data.inputs.look_dir.y,
data.body.eye_height(), data.body.eye_height(),
) * 0.55; ) * 0.55;
// Build up // Build up

View File

@ -116,7 +116,7 @@ impl Body {
Body::BirdSmall(_) => 35.0, Body::BirdSmall(_) => 35.0,
Body::FishSmall(_) => 10.0, Body::FishSmall(_) => 10.0,
Body::BipedLarge(_) => 12.0, Body::BipedLarge(_) => 12.0,
Body::Object(_) => 0.0, Body::Object(_) => 10.0,
Body::Golem(_) => 8.0, Body::Golem(_) => 8.0,
Body::Theropod(theropod) => match theropod.species { Body::Theropod(theropod) => match theropod.species {
theropod::Species::Archaeos => 2.5, theropod::Species::Archaeos => 2.5,

File diff suppressed because it is too large Load Diff

View File

@ -525,6 +525,7 @@ impl<'a> System<'a> for Sys {
Some(ToolKind::Unique(UniqueKind::QuadLowBreathe)) => Tactic::Lavadrake, Some(ToolKind::Unique(UniqueKind::QuadLowBreathe)) => Tactic::Lavadrake,
Some(ToolKind::Unique(UniqueKind::TheropodBasic)) => Tactic::Theropod, Some(ToolKind::Unique(UniqueKind::TheropodBasic)) => Tactic::Theropod,
Some(ToolKind::Unique(UniqueKind::TheropodBird)) => Tactic::Theropod, Some(ToolKind::Unique(UniqueKind::TheropodBird)) => Tactic::Theropod,
Some(ToolKind::Unique(UniqueKind::ObjectTurret)) => Tactic::Turret,
_ => Tactic::Melee, _ => Tactic::Melee,
}; };
@ -1429,6 +1430,38 @@ impl<'a> System<'a> for Sys {
do_idle = true; do_idle = true;
} }
}, },
Tactic::Turret => {
if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd)
{
inputs.primary.set_state(true);
} else {
do_idle = true;
}
},
Tactic::FixedTurret => {
inputs.look_dir = ori.look_dir();
if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd)
{
inputs.primary.set_state(true);
} else {
do_idle = true;
}
},
Tactic::RotatingTurret => {
inputs.look_dir = Dir::new(
Quaternion::from_xyzw(ori.look_dir().x, ori.look_dir().y, 0.0, 0.0)
.rotated_z(6.0 * dt.0 as f32)
.into_vec3()
.try_normalized()
.unwrap_or_default(),
);
if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd)
{
inputs.primary.set_state(true);
} else {
do_idle = true;
}
},
} }
} else { } else {
do_idle = true; do_idle = true;

View File

@ -160,11 +160,7 @@ impl Animation for RunAnimation {
Quaternion::rotation_x(0.6 * speednorm + (footrotr * -1.2) * speednorm) Quaternion::rotation_x(0.6 * speednorm + (footrotr * -1.2) * speednorm)
* Quaternion::rotation_y(footrotr * 0.4 * speednorm); * Quaternion::rotation_y(footrotr * 0.4 * speednorm);
next.hand_r.position = Vec3::new( next.hand_r.position = -next.hand_l.position;
s_a.hand.0 + foothoril * 1.3 * speednorm,
3.0 * speednorm + s_a.hand.1 + foothoril * -7.0 * speednorm,
1.5 * speednorm + s_a.hand.2 - foothoril * 5.5 * speednorm,
);
next.hand_r.orientation = next.hand_r.orientation =
Quaternion::rotation_x(0.6 * speednorm + (footrotl * -1.2) * speednorm) Quaternion::rotation_x(0.6 * speednorm + (footrotl * -1.2) * speednorm)
* Quaternion::rotation_y(footrotl * -0.4 * speednorm); * Quaternion::rotation_y(footrotl * -0.4 * speednorm);

View File

@ -0,0 +1,45 @@
use super::{
super::{vek::*, Animation},
ObjectSkeleton, SkeletonAttr,
};
use common::{
comp::{item::ToolKind, object::Body},
states::utils::StageSection,
};
pub struct BeamAnimation;
type BeamAnimationDependency = (
Option<ToolKind>,
Option<ToolKind>,
Option<StageSection>,
Body,
);
impl Animation for BeamAnimation {
type Dependency = BeamAnimationDependency;
type Skeleton = ObjectSkeleton;
#[cfg(feature = "use-dyn-lib")]
const UPDATE_FN: &'static [u8] = b"object_beam\0";
#[cfg_attr(feature = "be-dyn-lib", export_name = "object_beam")]
#[allow(clippy::approx_constant)] // TODO: Pending review in #587
fn update_skeleton_inner(
skeleton: &Self::Skeleton,
(_active_tool_kind, _second_tool_kind, _stage_section, _body): Self::Dependency,
_anim_time: f64,
rate: &mut f32,
s_a: &SkeletonAttr,
) -> Self::Skeleton {
*rate = 1.0;
let mut next = (*skeleton).clone();
next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2) / 11.0;
next.bone0.orientation = Quaternion::rotation_z(0.0);
next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2) / 11.0;
next.bone1.orientation = Quaternion::rotation_z(0.0);
next
}
}

View File

@ -24,8 +24,9 @@ impl Animation for IdleAnimation {
) -> Self::Skeleton { ) -> Self::Skeleton {
let mut next = (*skeleton).clone(); let mut next = (*skeleton).clone();
next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2); next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2) / 11.0;
next.bone0.orientation = Quaternion::rotation_z(0.0);
next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2) / 11.0;
next next
} }

View File

@ -1,8 +1,9 @@
pub mod beam;
pub mod idle; pub mod idle;
pub mod shoot; pub mod shoot;
// Reexports // Reexports
pub use self::{idle::IdleAnimation, shoot::ShootAnimation}; pub use self::{beam::BeamAnimation, idle::IdleAnimation, shoot::ShootAnimation};
use super::{make_bone, vek::*, FigureBoneData, Skeleton}; use super::{make_bone, vek::*, FigureBoneData, Skeleton};
use common::comp::{self}; use common::comp::{self};
@ -12,13 +13,14 @@ pub type Body = comp::object::Body;
skeleton_impls!(struct ObjectSkeleton { skeleton_impls!(struct ObjectSkeleton {
+ bone0, + bone0,
+ bone1,
}); });
impl Skeleton for ObjectSkeleton { impl Skeleton for ObjectSkeleton {
type Attr = SkeletonAttr; type Attr = SkeletonAttr;
type Body = Body; type Body = Body;
const BONE_COUNT: usize = 1; const BONE_COUNT: usize = 2;
#[cfg(feature = "use-dyn-lib")] #[cfg(feature = "use-dyn-lib")]
const COMPUTE_FN: &'static [u8] = b"object_compute_mats\0"; const COMPUTE_FN: &'static [u8] = b"object_compute_mats\0";
@ -30,14 +32,17 @@ impl Skeleton for ObjectSkeleton {
) -> Vec3<f32> { ) -> Vec3<f32> {
let bone0_mat = base_mat * Mat4::<f32>::from(self.bone0); let bone0_mat = base_mat * Mat4::<f32>::from(self.bone0);
*(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
[make_bone(bone0_mat * Mat4::scaling_3d(1.0 / 11.0))]; make_bone(bone0_mat * Mat4::scaling_3d(1.0 / 11.0)),
make_bone(Mat4::<f32>::from(self.bone1) * Mat4::scaling_3d(1.0 / 11.0)), /* Decorellated from ori */
];
Vec3::default() Vec3::default()
} }
} }
pub struct SkeletonAttr { pub struct SkeletonAttr {
bone0: (f32, f32, f32), bone0: (f32, f32, f32),
bone1: (f32, f32, f32),
} }
impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr { impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr {
@ -55,6 +60,7 @@ impl Default for SkeletonAttr {
fn default() -> Self { fn default() -> Self {
Self { Self {
bone0: (0.0, 0.0, 0.0), bone0: (0.0, 0.0, 0.0),
bone1: (0.0, 0.0, 0.0),
} }
} }
} }
@ -64,8 +70,11 @@ impl<'a> From<&'a Body> for SkeletonAttr {
use comp::object::Body::*; use comp::object::Body::*;
Self { Self {
bone0: match body { bone0: match body {
CampfireLit => (2.0, 0.5, 1.0), Crossbow => (0.0, 0.0, 14.0),
Pouch => (2.0, 0.5, 1.0), _ => (0.0, 0.0, 0.0),
},
bone1: match body {
Crossbow => (0.0, 0.0, 8.0),
_ => (0.0, 0.0, 0.0), _ => (0.0, 0.0, 0.0),
}, },
} }

View File

@ -2,17 +2,17 @@ use super::{
super::{vek::*, Animation}, super::{vek::*, Animation},
ObjectSkeleton, SkeletonAttr, ObjectSkeleton, SkeletonAttr,
}; };
use common::{comp::item::ToolKind, states::utils::StageSection}; use common::{
comp::{item::ToolKind, object::Body},
states::utils::StageSection,
};
pub struct ShootAnimation; pub struct ShootAnimation;
type ShootAnimationDependency = ( type ShootAnimationDependency = (
Option<ToolKind>, Option<ToolKind>,
Option<ToolKind>, Option<ToolKind>,
f32,
Vec3<f32>,
Vec3<f32>,
f64,
Option<StageSection>, Option<StageSection>,
Body,
); );
impl Animation for ShootAnimation { impl Animation for ShootAnimation {
type Dependency = ShootAnimationDependency; type Dependency = ShootAnimationDependency;
@ -25,15 +25,7 @@ impl Animation for ShootAnimation {
#[allow(clippy::approx_constant)] // TODO: Pending review in #587 #[allow(clippy::approx_constant)] // TODO: Pending review in #587
fn update_skeleton_inner( fn update_skeleton_inner(
skeleton: &Self::Skeleton, skeleton: &Self::Skeleton,
( (_active_tool_kind, _second_tool_kind, stage_section, body): Self::Dependency,
_active_tool_kind,
_second_tool_kind,
_velocity,
orientation,
last_ori,
_global_time,
_stage_section,
): Self::Dependency,
anim_time: f64, anim_time: f64,
rate: &mut f32, rate: &mut f32,
s_a: &SkeletonAttr, s_a: &SkeletonAttr,
@ -42,22 +34,28 @@ impl Animation for ShootAnimation {
let mut next = (*skeleton).clone(); let mut next = (*skeleton).clone();
let ori: Vec2<f32> = Vec2::from(orientation); let (movement1, movement2, movement3) = match stage_section {
let last_ori = Vec2::from(last_ori); Some(StageSection::Buildup) => (anim_time as f32, 0.0, 0.0),
let _tilt = if ::vek::Vec2::new(ori, last_ori) Some(StageSection::Swing) => (1.0, (anim_time as f32).powf(0.25), 0.0),
.map(|o| o.magnitude_squared()) Some(StageSection::Recover) => (1.0, 1.0, anim_time as f32),
.map(|m| m > 0.001 && m.is_finite()) _ => (0.0, 0.0, 0.0),
.reduce_and() };
&& ori.angle_between(last_ori).is_finite()
{
ori.angle_between(last_ori).min(0.2)
* last_ori.determine_side(Vec2::zero(), ori).signum()
} else {
0.0
} * 1.3;
next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2); next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2) / 11.0;
next.bone0.orientation = Quaternion::rotation_z(anim_time as f32 * 1.0); next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2) / 11.0;
#[allow(clippy::single_match)]
match body {
Body::Crossbow => {
next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2) / 11.0;
next.bone0.orientation =
Quaternion::rotation_x(movement1 * 0.05 + movement2 * 0.1) * (1.0 - movement3);
next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2) / 11.0;
next.bone1.orientation = Quaternion::rotation_z(0.0);
},
_ => {},
}
next next
} }

View File

@ -317,7 +317,10 @@ impl SfxMgr {
// TODO: from sfx config? // TODO: from sfx config?
match body { match body {
Body::Object( Body::Object(
object::Body::Arrow | object::Body::MultiArrow | object::Body::ArrowSnake, object::Body::Arrow
| object::Body::MultiArrow
| object::Body::ArrowSnake
| object::Body::ArrowTurret,
) => { ) => {
let file_ref = vec![ let file_ref = vec![
"voxygen.audio.sfx.abilities.arrow_shot_1", "voxygen.audio.sfx.abilities.arrow_shot_1",

View File

@ -23,22 +23,22 @@ impl<'a> System<'a> for Sys {
fn run( fn run(
&mut self, &mut self,
(entities, dt, positions, orientations, velocities, mut interpolated, bodies): Self::SystemData, (entities, dt, positions, orientations, velocities, bodies, mut interpolated): Self::SystemData,
) { ) {
// Update interpolated positions and orientations // Update interpolated positions and orientations
for (pos, ori, i, vel, body) in ( for (pos, ori, i, body, vel) in (
&positions, &positions,
&orientations, &orientations,
&mut interpolated, &mut interpolated,
&velocities,
&bodies, &bodies,
&velocities,
) )
.join() .join()
{ {
// Update interpolation values // Update interpolation values
if i.pos.distance_squared(pos.0) < 64.0 * 64.0 { if i.pos.distance_squared(pos.0) < 64.0 * 64.0 {
i.pos = Lerp::lerp(i.pos, pos.0 + vel.0 * 0.03, 5.0 * dt.0); i.pos = Lerp::lerp(i.pos, pos.0 + vel.0 * 0.03, 10.0 * dt.0);
i.ori = Dir::slerp(i.ori, ori.0, base_ori_interp(body) * dt.0); i.ori = Ori::slerp(i.ori, *ori, base_ori_interp(body) * dt.0);
} else { } else {
i.pos = pos.0; i.pos = pos.0;
i.ori = *ori; i.ori = *ori;

View File

@ -3747,6 +3747,7 @@ struct ObjectCentralSpec(HashMap<object::Body, SidedObjectCentralVoxSpec>);
#[derive(Deserialize)] #[derive(Deserialize)]
struct SidedObjectCentralVoxSpec { struct SidedObjectCentralVoxSpec {
bone0: ObjectCentralSubSpec, bone0: ObjectCentralSubSpec,
bone1: ObjectCentralSubSpec,
} }
#[derive(Deserialize)] #[derive(Deserialize)]
struct ObjectCentralSubSpec { struct ObjectCentralSubSpec {
@ -3764,7 +3765,9 @@ make_vox_spec!(
Some(spec.central.read().0.mesh_bone0( Some(spec.central.read().0.mesh_bone0(
body, body,
)), )),
None, Some(spec.central.read().0.mesh_bone1(
body,
)),
None, None,
None, None,
None, None,
@ -3796,4 +3799,17 @@ impl ObjectCentralSpec {
(central, Vec3::from(spec.bone0.offset)) (central, Vec3::from(spec.bone0.offset))
} }
fn mesh_bone1(&self, obj: &object::Body) -> BoneMeshes {
let spec = match self.0.get(&obj) {
Some(spec) => spec,
None => {
error!("No specification exists for {:?}", obj);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
},
};
let central = graceful_load_segment(&spec.bone1.central.0);
(central, Vec3::from(spec.bone1.offset))
}
} }

View File

@ -3490,7 +3490,9 @@ impl FigureMgr {
let (character, last_character) = match (character, last_character) { let (character, last_character) = match (character, last_character) {
(Some(c), Some(l)) => (c, l), (Some(c), Some(l)) => (c, l),
_ => continue, _ => (&CharacterState::Idle, &Last {
0: CharacterState::Idle,
}),
}; };
if !character.same_variant(&last_character.0) { if !character.same_variant(&last_character.0) {
@ -3538,11 +3540,33 @@ impl FigureMgr {
( (
active_tool_kind, active_tool_kind,
second_tool_kind, second_tool_kind,
vel.0.magnitude(),
ori,
state.last_ori,
time,
Some(s.stage_section), Some(s.stage_section),
*body,
),
stage_progress,
&mut state_animation_rate,
skeleton_attr,
)
},
CharacterState::BasicBeam(s) => {
let stage_time = s.timer.as_secs_f64();
let stage_progress = match s.stage_section {
StageSection::Buildup => {
stage_time / s.static_data.buildup_duration.as_secs_f64()
},
StageSection::Cast => s.timer.as_secs_f64(),
StageSection::Recover => {
stage_time / s.static_data.recover_duration.as_secs_f64()
},
_ => 0.0,
};
anim::object::BeamAnimation::update_skeleton(
&target_base,
(
active_tool_kind,
second_tool_kind,
Some(s.stage_section),
*body,
), ),
stage_progress, stage_progress,
&mut state_animation_rate, &mut state_animation_rate,

View File

@ -8,6 +8,7 @@ use crate::{
}; };
use common::{ use common::{
assets::{AssetExt, DotVoxAsset}, assets::{AssetExt, DotVoxAsset},
combat::CombatEffect,
comp::{item::Reagent, object, BeamSegment, Body, CharacterState, Ori, Pos, Shockwave}, comp::{item::Reagent, object, BeamSegment, Body, CharacterState, Ori, Pos, Shockwave},
figure::Segment, figure::Segment,
outcome::Outcome, outcome::Outcome,
@ -376,7 +377,12 @@ impl ParticleMgr {
.filter(|(_, _, b)| b.creation.map_or(true, |c| (c + dt as f64) >= time)) .filter(|(_, _, b)| b.creation.map_or(true, |c| (c + dt as f64) >= time))
{ {
let range = beam.properties.speed * beam.properties.duration.as_secs_f32(); let range = beam.properties.speed * beam.properties.duration.as_secs_f32();
if beam.properties.lifesteal_eff > 0.0 { if beam
.properties
.attack
.effects()
.any(|e| matches!(e.effect(), CombatEffect::Heal(h) if *h > 0.0))
{
// Emit a light when using healing // Emit a light when using healing
lights.push(Light::new(pos.0, Rgb::new(0.1, 1.0, 0.15), 1.0)); lights.push(Light::new(pos.0, Rgb::new(0.1, 1.0, 0.15), 1.0));
for i in 0..self.scheduler.heartbeats(Duration::from_millis(1)) { for i in 0..self.scheduler.heartbeats(Duration::from_millis(1)) {
@ -385,25 +391,25 @@ impl ParticleMgr {
time + i as f64 / 1000.0, time + i as f64 / 1000.0,
ParticleMode::HealingBeam, ParticleMode::HealingBeam,
pos.0, pos.0,
pos.0 + *ori.0 * range, pos.0 + *ori.look_dir() * range,
)); ));
} }
} else { } else {
let mut rng = thread_rng(); let mut rng = thread_rng();
let (from, to) = (Vec3::<f32>::unit_z(), *ori.0); let (from, to) = (Vec3::<f32>::unit_z(), *ori.look_dir());
let m = Mat3::<f32>::rotation_from_to_3d(from, to); let m = Mat3::<f32>::rotation_from_to_3d(from, to);
// Emit a light when using flames // Emit a light when using flames
lights.push(Light::new( lights.push(Light::new(
pos.0, pos.0,
Rgb::new(1.0, 0.25, 0.05).map(|e| e * rng.gen_range(0.8, 1.2)), Rgb::new(1.0, 0.25, 0.05).map(|e| e * rng.gen_range(0.8..1.2)),
2.0, 2.0,
)); ));
self.particles.resize_with( self.particles.resize_with(
self.particles.len() self.particles.len()
+ 2 * usize::from(self.scheduler.heartbeats(Duration::from_millis(1))), + 2 * usize::from(self.scheduler.heartbeats(Duration::from_millis(1))),
|| { || {
let phi: f32 = rng.gen_range(0.0, beam.properties.angle.to_radians()); let phi: f32 = rng.gen_range(0.0..beam.properties.angle.to_radians());
let theta: f32 = rng.gen_range(0.0, 2.0 * PI); let theta: f32 = rng.gen_range(0.0..2.0 * PI);
let offset_z = let offset_z =
Vec3::new(phi.sin() * theta.cos(), phi.sin() * theta.sin(), phi.cos()); Vec3::new(phi.sin() * theta.cos(), phi.sin() * theta.sin(), phi.cos());
let random_ori = offset_z * m * Vec3::new(-1.0, -1.0, 1.0); let random_ori = offset_z * m * Vec3::new(-1.0, -1.0, 1.0);

View File

@ -701,6 +701,12 @@ impl Floor {
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
"common.items.weapons.staff.cultist_staff", "common.items.weapons.staff.cultist_staff",
)), )),
1 => entity
.with_body(comp::Body::Object(comp::object::Body::Crossbow))
.with_name("Possessed Turret".to_string())
.with_loot_drop(comp::Item::new_from_asset_expect(
"common.items.crafting_ing.twigs",
)),
_ => entity _ => entity
.with_name("Cultist Warlord") .with_name("Cultist Warlord")
.with_loadout_config(loadout_builder::LoadoutConfig::Warlord) .with_loadout_config(loadout_builder::LoadoutConfig::Warlord)

View File

@ -884,7 +884,7 @@ impl Settlement {
.with_body(match dynamic_rng.gen_range(0..5) { .with_body(match dynamic_rng.gen_range(0..5) {
_ if is_dummy => { _ if is_dummy => {
is_human = false; is_human = false;
object::Body::Crossbow.into() object::Body::TrainingDummy.into()
}, },
0 => { 0 => {
let species = match dynamic_rng.gen_range(0..3) { let species = match dynamic_rng.gen_range(0..3) {
@ -916,9 +916,9 @@ impl Settlement {
comp::Body::Humanoid(humanoid::Body::random()) comp::Body::Humanoid(humanoid::Body::random())
}, },
}) })
.with_agency(true) // TEMPORARY .with_agency(!is_dummy)
.with_alignment(if is_dummy { .with_alignment(if is_dummy {
comp::Alignment::Enemy // TEMPORARY comp::Alignment::Passive
} else if is_human { } else if is_human {
comp::Alignment::Npc comp::Alignment::Npc
} else { } else {