Merge branch 'snowram/more-trolls' into 'master'

Add more trolls npcs, and roc npc with tornado attack

See merge request veloren/veloren!2384
This commit is contained in:
Snowram 2021-06-15 08:35:30 +00:00
commit 8fde002189
105 changed files with 1503 additions and 190 deletions

View File

@ -264,6 +264,18 @@
(None, "common.abilities.custom.birdlargefire.fireshockwave"),
],
),
Custom("Bird Large Basic"): (
primary: "common.abilities.custom.birdlargebasic.triplestrike",
secondary: "common.abilities.custom.birdlargebasic.summontornadoes",
abilities: [
(None, "common.abilities.custom.birdlargebasic.dash"),
],
),
Custom("Tornado"): (
primary: "common.abilities.custom.tornado.spin",
secondary: "common.abilities.empty.basic",
abilities: [],
),
Tool(Debug): (
primary: "common.abilities.debug.forwardboost",
secondary: "common.abilities.debug.upboost",

View File

@ -0,0 +1,20 @@
DashMelee(
energy_cost: 0,
base_damage: 80,
scaled_damage: 150,
base_poise_damage: 50,
scaled_poise_damage: 100,
base_knockback: 6.0,
scaled_knockback: 12.0,
range: 2.0,
angle: 20.0,
energy_drain: 0,
forward_speed: 1.9,
buildup_duration: 0.5,
charge_duration: 3.0,
swing_duration: 0.1,
recover_duration: 0.7,
charge_through: false,
is_interruptible: false,
damage_kind: Crushing,
)

View File

@ -0,0 +1,18 @@
BasicSummon(
buildup_duration: 0.5,
cast_duration: 0.2,
recover_duration: 0.2,
summon_amount: 12,
summon_distance: (4, 9),
summon_info: (
body: Object(Tornado),
scale: None,
health_scaling: None,
loadout_config: None,
skillset_config: None,
),
duration: Some((
secs: 10,
nanos: 0,
)),
)

View File

@ -0,0 +1,60 @@
ComboMelee(
stage_data: [
(
stage: 1,
base_damage: 110,
damage_increase: 0,
base_poise_damage: 0,
poise_damage_increase: 0,
knockback: 5.0,
range: 4.5,
angle: 30.0,
base_buildup_duration: 0.4,
base_swing_duration: 0.1,
hit_timing: 0.5,
base_recover_duration: 0.3,
forward_movement: 3.0,
damage_kind: Crushing,
),
(
stage: 2,
base_damage: 90,
damage_increase: 0,
base_poise_damage: 0,
poise_damage_increase: 0,
knockback: 5.0,
range: 3.5,
angle: 30.0,
base_buildup_duration: 0.4,
base_swing_duration: 0.1,
hit_timing: 0.5,
base_recover_duration: 0.3,
forward_movement: 3.0,
damage_kind: Crushing,
),
(
stage: 3,
base_damage: 140,
damage_increase: 0,
base_poise_damage: 0,
poise_damage_increase: 0,
knockback: 10.0,
range: 3.5,
angle: 30.0,
base_buildup_duration: 0.65,
base_swing_duration: 0.1,
hit_timing: 0.5,
base_recover_duration: 0.3,
forward_movement: 3.5,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,
max_energy_gain: 0,
energy_increase: 0,
speed_increase: 0.0,
max_speed_increase: 0.0,
scales_from_combo: 0,
is_interruptible: false,
ori_modifier: 0.7,
)

View File

@ -3,14 +3,16 @@ BasicSummon(
cast_duration: 1.0,
recover_duration: 0.5,
summon_amount: 6,
summon_distance: (3, 3),
summon_info: (
body: BipedSmall((
species: Husk,
body_type: Male,
)),
scale: None,
health_scaling: 80,
health_scaling: Some(80),
loadout_config: Some(HuskSummon),
skillset_config: None,
),
duration: None,
)

View File

@ -3,11 +3,13 @@ BasicSummon(
cast_duration: 1.0,
recover_duration: 0.5,
summon_amount: 1,
summon_distance: (1, 1),
summon_info: (
body: Object(SeaLantern),
scale: None,
health_scaling: 0,
health_scaling: Some(0),
loadout_config: None,
skillset_config: None,
),
duration: None,
)

View File

@ -0,0 +1,19 @@
SpinMelee(
buildup_duration: 0.0,
swing_duration: 0.5,
recover_duration: 0.0,
base_damage: 400,
base_poise_damage: 0,
knockback: ( strength: 50.0, direction: Away),
range: 3.5,
damage_effect: None,
energy_cost: 0,
is_infinite: true,
movement_behavior: ForwardGround,
is_interruptible: false,
forward_speed: 0.0,
num_spins: 1,
specifier: None,
target: Some(OutOfGroup),
damage_kind: Slashing,
)

View File

@ -0,0 +1,19 @@
ItemDef(
name: "Bird Large Basic",
description: "testing123",
kind: Tool((
kind: Natural,
hands: Two,
stats: Direct((
equip_time_secs: 0.01,
power: 1.0,
poise_strength: 1.0,
speed: 1.0,
crit_chance: 0.0625,
crit_mult: 1.9142857,
)),
)),
quality: Low,
tags: [],
ability_spec: Some(Custom("Bird Large Basic")),
)

View File

@ -0,0 +1,19 @@
ItemDef(
name: "Tornado",
description: "Tornado weapon",
kind: Tool((
kind: Natural,
hands: Two,
stats: Direct((
equip_time_secs: 0.01,
power: 1.0,
poise_strength: 0.0,
speed: 1.0,
crit_chance: 0.0,
crit_mult: 0.0,
)),
)),
quality: Low,
tags: [],
ability_spec: Some(Custom("Tornado")),
)

View File

@ -0,0 +1,4 @@
[
(0.5, Item("common.items.food.meat.beast_large_raw")),
(1.0, Item("common.items.crafting_ing.animal_misc.raptor_feather")),
]

View File

@ -826,9 +826,17 @@
keyword: "wendigo",
generic: "Wendigo"
),
troll: (
keyword: "troll",
generic: "Troll"
troll_cave: (
keyword: "troll_cave",
generic: "Cave Troll"
),
troll_mountain: (
keyword: "troll_mountain",
generic: "Mountain Troll"
),
troll_swamp: (
keyword: "troll_swamp",
generic: "Swamp Troll"
),
dullahan: (
keyword: "dullahan",
@ -1080,6 +1088,10 @@
keyword: "cockatrice",
generic: "Cockatrice"
),
roc: (
keyword: "roc",
generic: "Roc"
),
)
),
quadruped_low: (

View File

@ -71,6 +71,7 @@ const int BUBBLES = 29;
const int WATER = 30;
const int ICE_SPIKES = 31;
const int DRIP = 32;
const int TORNADO = 33;
// meters per second squared (acceleration)
const float earth_gravity = 9.807;
@ -543,6 +544,15 @@ void main() {
spin_in_axis(vec3(1,0,0),0)
);
break;
case TORNADO:
f_reflect = 0.0;
attr = Attr(
spiral_motion(vec3(0, 0, 5), abs(rand0) + abs(rand1) * percent() * 3.0, percent(), 15.0 * abs(rand2), rand3),
vec3((2.5 * (1 - slow_start(0.05)))),
vec4(vec3(1.2 + 0.5 * percent()), 1),
spin_in_axis(vec3(rand6, rand7, rand8), percent() * 10 + 3 * rand9)
);
break;
default:
attr = Attr(
linear_motion(

View File

@ -156,22 +156,22 @@
central: ("armor.empty"),
)
),
(Troll, Male): (
(Cavetroll, Male): (
head: (
offset: (-8.0, -8.5, -9.0),
central: ("npc.troll.male.head"),
offset: (-8.0, -8.0, -8.5),
central: ("npc.troll_cave.male.head"),
),
torso_upper: (
offset: (-8.0, -7.5, -11.0),
central: ("npc.troll.male.torso_upper"),
offset: (-8.0, -9.5, -11.0),
central: ("npc.troll_cave.male.torso_upper"),
),
torso_lower: (
offset: (-6.0, -3.5, -5.0),
central: ("npc.troll.male.torso_lower"),
offset: (-7.0, -5.5, -7.0),
central: ("npc.troll_cave.male.torso_lower"),
),
jaw: (
offset: (-4.0, 0.0, -4.5),
central: ("npc.troll.male.jaw"),
offset: (-5.0, 0.0, -4.5),
central: ("npc.troll_cave.male.jaw"),
),
tail: (
offset: (0.0, 0.0, 0.0),
@ -182,22 +182,126 @@
central: ("armor.empty"),
)
),
(Troll, Female): (
(Cavetroll, Female): (
head: (
offset: (-8.0, -8.5, -9.0),
central: ("npc.troll.male.head"),
offset: (-8.0, -8.0, -8.5),
central: ("npc.troll_cave.male.head"),
),
torso_upper: (
offset: (-8.0, -7.5, -11.0),
central: ("npc.troll.male.torso_upper"),
offset: (-8.0, -9.5, -11.0),
central: ("npc.troll_cave.male.torso_upper"),
),
torso_lower: (
offset: (-6.0, -3.5, -5.0),
central: ("npc.troll.male.torso_lower"),
offset: (-7.0, -5.5, -7.0),
central: ("npc.troll_cave.male.torso_lower"),
),
jaw: (
offset: (-5.0, 0.0, -4.5),
central: ("npc.troll_cave.male.jaw"),
),
tail: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
),
second: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
)
),
(Mountaintroll, Male): (
head: (
offset: (-9.0, -8.5, -10.0),
central: ("npc.troll_mountain.male.head"),
),
torso_upper: (
offset: (-9.0, -10.0, -14.5),
central: ("npc.troll_mountain.male.torso_upper"),
),
torso_lower: (
offset: (-7.0, -5.5, -7.0),
central: ("npc.troll_mountain.male.torso_lower"),
),
jaw: (
offset: (-4.0, 0.0, -4.5),
central: ("npc.troll.male.jaw"),
central: ("npc.troll_mountain.male.jaw"),
),
tail: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
),
second: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
)
),
(Mountaintroll, Female): (
head: (
offset: (-9.0, -8.5, -10.0),
central: ("npc.troll_mountain.male.head"),
),
torso_upper: (
offset: (-9.0, -10.0, -14.5),
central: ("npc.troll_mountain.male.torso_upper"),
),
torso_lower: (
offset: (-7.0, -5.5, -7.0),
central: ("npc.troll_mountain.male.torso_lower"),
),
jaw: (
offset: (-4.0, 0.0, -4.5),
central: ("npc.troll_mountain.male.jaw"),
),
tail: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
),
second: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
)
),
(Swamptroll, Male): (
head: (
offset: (-10.0, -6.5, -6.0),
central: ("npc.troll_swamp.male.head"),
),
torso_upper: (
offset: (-9.0, -9.0, -12.5),
central: ("npc.troll_swamp.male.torso_upper"),
),
torso_lower: (
offset: (-8.0, -6.5, -10.0),
central: ("npc.troll_swamp.male.torso_lower"),
),
jaw: (
offset: (-6.0, 0.0, -4.0),
central: ("npc.troll_swamp.male.jaw"),
),
tail: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
),
second: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
)
),
(Swamptroll, Female): (
head: (
offset: (-10.0, -6.5, -6.0),
central: ("npc.troll_swamp.male.head"),
),
torso_upper: (
offset: (-9.0, -9.0, -12.5),
central: ("npc.troll_swamp.male.torso_upper"),
),
torso_lower: (
offset: (-8.0, -6.5, -10.0),
central: ("npc.troll_swamp.male.torso_lower"),
),
jaw: (
offset: (-6.0, 0.0, -4.0),
central: ("npc.troll_swamp.male.jaw"),
),
tail: (
offset: (0.0, 0.0, 0.0),

View File

@ -203,72 +203,208 @@
lateral: ("npc.wendigo.male.foot_r"),
),
),
(Troll, Male): (
(Cavetroll, Male): (
shoulder_l: (
offset: (-5.0, -4.5, -11.0),
lateral: ("npc.troll.male.shoulder_l"),
offset: (-5.5, -4.0, -8.0),
lateral: ("npc.troll_cave.male.shoulder_l"),
),
shoulder_r: (
offset: (-5.0, -4.5, -11.0),
lateral: ("npc.troll.male.shoulder_r"),
offset: (-5.5, -4.0, -8.0),
lateral: ("npc.troll_cave.male.shoulder_r"),
),
hand_l: (
offset: (-3.5, -4.0, -12.0),
lateral: ("npc.troll.male.hand_l"),
offset: (-4.5, -4.0, -14.0),
lateral: ("npc.troll_cave.male.hand_l"),
),
hand_r: (
offset: (-3.5, -4.0, -12.0),
lateral: ("npc.troll.male.hand_r"),
offset: (-4.5, -4.0, -14.0),
lateral: ("npc.troll_cave.male.hand_r"),
),
leg_l: (
offset: (-3.0, -2.5, -4.5),
lateral: ("npc.troll.male.leg_l"),
offset: (-3.0, -3.0, -4.0),
lateral: ("npc.troll_cave.male.leg_l"),
),
leg_r: (
offset: (-3.0, -2.5, -4.5),
lateral: ("npc.troll.male.leg_r"),
offset: (-3.0, -3.0, -4.0),
lateral: ("npc.troll_cave.male.leg_r"),
),
foot_l: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll.male.foot_l"),
lateral: ("npc.troll_cave.male.foot_l"),
),
foot_r: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll.male.foot_r"),
lateral: ("npc.troll_cave.male.foot_r"),
),
),
(Troll, Female): (
(Cavetroll, Female): (
shoulder_l: (
offset: (-5.0, -4.5, -11.0),
lateral: ("npc.troll.male.shoulder_l"),
offset: (-5.5, -4.0, -8.0),
lateral: ("npc.troll_cave.male.shoulder_l"),
),
shoulder_r: (
offset: (-5.0, -4.5, -11.0),
lateral: ("npc.troll.male.shoulder_r"),
offset: (-5.5, -4.0, -8.0),
lateral: ("npc.troll_cave.male.shoulder_r"),
),
hand_l: (
offset: (-3.5, -4.0, -12.0),
lateral: ("npc.troll.male.hand_l"),
offset: (-4.5, -4.0, -14.0),
lateral: ("npc.troll_cave.male.hand_l"),
),
hand_r: (
offset: (-3.5, -4.0, -12.0),
lateral: ("npc.troll.male.hand_r"),
offset: (-4.5, -4.0, -14.0),
lateral: ("npc.troll_cave.male.hand_r"),
),
leg_l: (
offset: (-3.0, -2.5, -4.5),
lateral: ("npc.troll.male.leg_l"),
offset: (-3.0, -3.0, -4.0),
lateral: ("npc.troll_cave.male.leg_l"),
),
leg_r: (
offset: (-3.0, -2.5, -4.5),
lateral: ("npc.troll.male.leg_r"),
offset: (-3.0, -3.0, -4.0),
lateral: ("npc.troll_cave.male.leg_r"),
),
foot_l: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll.male.foot_l"),
lateral: ("npc.troll_cave.male.foot_l"),
),
foot_r: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll.male.foot_r"),
lateral: ("npc.troll_cave.male.foot_r"),
),
),
(Mountaintroll, Male): (
shoulder_l: (
offset: (-6.5, -5.0, -8.5),
lateral: ("npc.troll_mountain.male.shoulder_l"),
),
shoulder_r: (
offset: (-6.5, -5.0, -8.5),
lateral: ("npc.troll_mountain.male.shoulder_r"),
),
hand_l: (
offset: (-5.0, -4.5, -14.0),
lateral: ("npc.troll_mountain.male.hand_l"),
),
hand_r: (
offset: (-5.0, -4.5, -14.0),
lateral: ("npc.troll_mountain.male.hand_r"),
),
leg_l: (
offset: (-3.0, -3.0, -4.0),
lateral: ("npc.troll_mountain.male.leg_l"),
),
leg_r: (
offset: (-3.0, -3.0, -4.0),
lateral: ("npc.troll_mountain.male.leg_r"),
),
foot_l: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll_mountain.male.foot_l"),
),
foot_r: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll_mountain.male.foot_r"),
),
),
(Mountaintroll, Female): (
shoulder_l: (
offset: (-6.5, -5.0, -8.5),
lateral: ("npc.troll_mountain.male.shoulder_l"),
),
shoulder_r: (
offset: (-6.5, -5.0, -8.5),
lateral: ("npc.troll_mountain.male.shoulder_r"),
),
hand_l: (
offset: (-5.0, -4.5, -14.0),
lateral: ("npc.troll_mountain.male.hand_l"),
),
hand_r: (
offset: (-5.0, -4.5, -14.0),
lateral: ("npc.troll_mountain.male.hand_r"),
),
leg_l: (
offset: (-3.0, -3.0, -4.0),
lateral: ("npc.troll_mountain.male.leg_l"),
),
leg_r: (
offset: (-3.0, -3.0, -4.0),
lateral: ("npc.troll_mountain.male.leg_r"),
),
foot_l: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll_mountain.male.foot_l"),
),
foot_r: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll_mountain.male.foot_r"),
),
),
(Swamptroll, Male): (
shoulder_l: (
offset: (-5.5, -5.0, -8.5),
lateral: ("npc.troll_swamp.male.shoulder_l"),
),
shoulder_r: (
offset: (-5.5, -5.0, -8.5),
lateral: ("npc.troll_swamp.male.shoulder_r"),
),
hand_l: (
offset: (-5.0, -4.0, -16.0),
lateral: ("npc.troll_swamp.male.hand_l"),
),
hand_r: (
offset: (-5.0, -4.0, -16.0),
lateral: ("npc.troll_swamp.male.hand_r"),
),
leg_l: (
offset: (-3.0, -3.0, -4.0),
lateral: ("npc.troll_swamp.male.leg_l"),
),
leg_r: (
offset: (-3.0, -3.0, -4.0),
lateral: ("npc.troll_swamp.male.leg_r"),
),
foot_l: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll_swamp.male.foot_l"),
),
foot_r: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll_swamp.male.foot_r"),
),
),
(Swamptroll, Female): (
shoulder_l: (
offset: (-5.5, -5.0, -8.5),
lateral: ("npc.troll_swamp.male.shoulder_l"),
),
shoulder_r: (
offset: (-5.5, -5.0, -8.5),
lateral: ("npc.troll_swamp.male.shoulder_r"),
),
hand_l: (
offset: (-5.0, -4.0, -16.0),
lateral: ("npc.troll_swamp.male.hand_l"),
),
hand_r: (
offset: (-5.0, -4.0, -16.0),
lateral: ("npc.troll_swamp.male.hand_r"),
),
leg_l: (
offset: (-3.0, -3.0, -4.0),
lateral: ("npc.troll_swamp.male.leg_l"),
),
leg_r: (
offset: (-3.0, -3.0, -4.0),
lateral: ("npc.troll_swamp.male.leg_r"),
),
foot_l: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll_swamp.male.foot_l"),
),
foot_r: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll_swamp.male.foot_r"),
),
),
(Dullahan, Male): (

View File

@ -103,4 +103,56 @@
central: ("npc.cockatrice.male.tail_rear"),
)
),
(Roc, Male): (
head: (
offset: (-4.5, -4.0, -6.0),
central: ("npc.roc.male.head"),
),
beak: (
offset: (-3.5, 0.0, -8.0),
central: ("npc.roc.male.beak"),
),
neck: (
offset: (-5.5, 0.0, -10.5),
central: ("npc.roc.male.neck"),
),
chest: (
offset: (-8.5, -12.5, -13.5),
central: ("npc.roc.male.chest"),
),
tail_front: (
offset: (-4.5, -9.0, -8.0),
central: ("npc.roc.male.tail_front"),
),
tail_rear: (
offset: (-9.5, -28.0, -6.0),
central: ("npc.roc.male.tail_rear"),
)
),
(Roc, Female): (
head: (
offset: (-4.5, -4.0, -6.0),
central: ("npc.roc.male.head"),
),
beak: (
offset: (-3.5, 0.0, -8.0),
central: ("npc.roc.male.beak"),
),
neck: (
offset: (-5.5, 0.0, -10.5),
central: ("npc.roc.male.neck"),
),
chest: (
offset: (-8.5, -12.5, -13.5),
central: ("npc.roc.male.chest"),
),
tail_front: (
offset: (-4.5, -9.0, -8.0),
central: ("npc.roc.male.tail_front"),
),
tail_rear: (
offset: (-9.5, -28.0, -6.0),
central: ("npc.roc.male.tail_rear"),
)
),
})

View File

@ -167,4 +167,88 @@
lateral: ("npc.cockatrice.male.foot_r"),
)
),
(Roc, Male): (
wing_in_l: (
offset: (-13.0, -14.0, -2.5),
lateral: ("npc.roc.male.wing_in_r"),
),
wing_in_r: (
offset: (0.0, -14.0, -2.5),
lateral: ("npc.roc.male.wing_in_r"),
),
wing_mid_l: (
offset: (-11.0, -18.0, -2.0),
lateral: ("npc.roc.male.wing_mid_r"),
),
wing_mid_r: (
offset: (0.0, -18.0, -2.0),
lateral: ("npc.roc.male.wing_mid_r"),
),
wing_out_l: (
offset: (-20.0, -18.0, -2.0),
lateral: ("npc.roc.male.wing_out_r"),
),
wing_out_r: (
offset: (0.0, -18.0, -2.0),
lateral: ("npc.roc.male.wing_out_r"),
),
leg_l: (
offset: (-4.0, -5.5, -7.5),
lateral: ("npc.roc.male.leg_r"),
),
leg_r: (
offset: (-4.0, -5.5, -7.5),
lateral: ("npc.roc.male.leg_r"),
),
foot_l: (
offset: (-5.5, -3.0, -12.0),
lateral: ("npc.roc.male.foot_r"),
),
foot_r: (
offset: (-5.5, -3.0, -12.0),
lateral: ("npc.roc.male.foot_r"),
)
),
(Roc, Female): (
wing_in_l: (
offset: (-13.0, -14.0, -2.5),
lateral: ("npc.roc.male.wing_in_r"),
),
wing_in_r: (
offset: (0.0, -14.0, -2.5),
lateral: ("npc.roc.male.wing_in_r"),
),
wing_mid_l: (
offset: (-11.0, -18.0, -2.0),
lateral: ("npc.roc.male.wing_mid_r"),
),
wing_mid_r: (
offset: (0.0, -18.0, -2.0),
lateral: ("npc.roc.male.wing_mid_r"),
),
wing_out_l: (
offset: (-20.0, -18.0, -2.0),
lateral: ("npc.roc.male.wing_out_r"),
),
wing_out_r: (
offset: (0.0, -18.0, -2.0),
lateral: ("npc.roc.male.wing_out_r"),
),
leg_l: (
offset: (-4.0, -5.5, -7.5),
lateral: ("npc.roc.male.leg_r"),
),
leg_r: (
offset: (-4.0, -5.5, -7.5),
lateral: ("npc.roc.male.leg_r"),
),
foot_l: (
offset: (-5.5, -3.0, -12.0),
lateral: ("npc.roc.male.foot_r"),
),
foot_r: (
offset: (-5.5, -3.0, -12.0),
lateral: ("npc.roc.male.foot_r"),
)
),
})

BIN
assets/voxygen/voxel/npc/roc/male/beak.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/roc/male/chest.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/roc/male/foot_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/roc/male/head.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/roc/male/leg_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/roc/male/neck.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/roc/male/tail_front.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/roc/male/tail_rear.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/roc/male/wing_in_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/roc/male/wing_mid_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/roc/male/wing_out_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_cave/male/foot_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_cave/male/foot_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_cave/male/hand_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_cave/male/hand_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_cave/male/head.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_cave/male/jaw.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_cave/male/leg_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_cave/male/leg_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_cave/male/shoulder_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_cave/male/shoulder_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_cave/male/torso_lower.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_cave/male/torso_upper.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_mountain/male/foot_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_mountain/male/foot_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_mountain/male/hand_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_mountain/male/hand_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_mountain/male/head.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_mountain/male/jaw.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_mountain/male/leg_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_mountain/male/leg_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_mountain/male/shoulder_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_mountain/male/shoulder_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_mountain/male/torso_lower.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_mountain/male/torso_upper.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_swamp/male/foot_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_swamp/male/foot_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_swamp/male/hand_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_swamp/male/hand_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_swamp/male/head.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_swamp/male/jaw.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_swamp/male/leg_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_swamp/male/leg_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_swamp/male/shoulder_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_swamp/male/shoulder_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_swamp/male/torso_lower.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/troll_swamp/male/torso_upper.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -759,4 +759,14 @@
central: ("armor.empty"),
)
),
Tornado: (
bone0: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("armor.empty"),
)
),
})

View File

@ -280,7 +280,9 @@ pub enum CharacterAbility {
cast_duration: f32,
recover_duration: f32,
summon_amount: u32,
summon_distance: (f32, f32),
summon_info: basic_summon::SummonInfo,
duration: Option<Duration>,
},
SelfBuff {
buildup_duration: f32,
@ -1737,15 +1739,19 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
cast_duration,
recover_duration,
summon_amount,
summon_distance,
summon_info,
duration,
} => CharacterState::BasicSummon(basic_summon::Data {
static_data: basic_summon::StaticData {
buildup_duration: Duration::from_secs_f32(*buildup_duration),
cast_duration: Duration::from_secs_f32(*cast_duration),
recover_duration: Duration::from_secs_f32(*recover_duration),
summon_amount: *summon_amount,
summon_distance: *summon_distance,
summon_info: *summon_info,
ability_info,
duration: *duration,
},
summon_count: 0,
timer: Duration::default(),

View File

@ -412,6 +412,7 @@ impl Body {
Body::BirdLarge(body) => match body.species {
bird_large::Species::Cockatrice => 4000,
bird_large::Species::Phoenix => 6000,
bird_large::Species::Roc => 5000,
},
Body::Humanoid(_) => 750,
_ => 1000,
@ -471,13 +472,18 @@ impl Body {
},
Body::FishMedium(_) => 250,
Body::Dragon(_) => 5000,
Body::BirdLarge(_) => 3000,
Body::BirdLarge(bird_large) => match bird_large.species {
bird_large::Species::Roc => 2800,
_ => 3000,
},
Body::FishSmall(_) => 20,
Body::BipedLarge(biped_large) => match biped_large.species {
biped_large::Species::Ogre => 3200,
biped_large::Species::Cyclops => 3200,
biped_large::Species::Wendigo => 2800,
biped_large::Species::Troll => 2400,
biped_large::Species::Cavetroll => 2400,
biped_large::Species::Mountaintroll => 2400,
biped_large::Species::Swamptroll => 2400,
biped_large::Species::Dullahan => 3000,
biped_large::Species::Mindflayer => 12500,
biped_large::Species::Tidalwarrior => 16000,
@ -588,13 +594,18 @@ impl Body {
},
Body::FishMedium(_) => 10,
Body::Dragon(_) => 500,
Body::BirdLarge(_) => 120,
Body::BirdLarge(bird_large) => match bird_large.species {
bird_large::Species::Roc => 110,
_ => 120,
},
Body::FishSmall(_) => 10,
Body::BipedLarge(biped_large) => match biped_large.species {
biped_large::Species::Ogre => 70,
biped_large::Species::Cyclops => 80,
biped_large::Species::Wendigo => 80,
biped_large::Species::Troll => 60,
biped_large::Species::Cavetroll => 60,
biped_large::Species::Mountaintroll => 60,
biped_large::Species::Swamptroll => 60,
biped_large::Species::Dullahan => 120,
biped_large::Species::Yeti => 0,
biped_large::Species::Harvester => 80,

View File

@ -37,19 +37,21 @@ make_case_elim!(
Ogre = 0,
Cyclops = 1,
Wendigo = 2,
Troll = 3,
Dullahan = 4,
Werewolf = 5,
Occultsaurok = 6,
Mightysaurok = 7,
Slysaurok = 8,
Mindflayer = 9,
Minotaur = 10,
Tidalwarrior = 11,
Yeti = 12,
Harvester = 13,
Blueoni = 14,
Redoni = 15,
Cavetroll = 3,
Mountaintroll = 4,
Swamptroll = 5,
Dullahan = 6,
Werewolf = 7,
Occultsaurok = 8,
Mightysaurok = 9,
Slysaurok = 10,
Mindflayer = 11,
Minotaur = 12,
Tidalwarrior = 13,
Yeti = 14,
Harvester = 15,
Blueoni = 16,
Redoni = 17,
}
);
@ -61,7 +63,9 @@ pub struct AllSpecies<SpeciesMeta> {
pub ogre: SpeciesMeta,
pub cyclops: SpeciesMeta,
pub wendigo: SpeciesMeta,
pub troll: SpeciesMeta,
pub troll_cave: SpeciesMeta,
pub troll_mountain: SpeciesMeta,
pub troll_swamp: SpeciesMeta,
pub dullahan: SpeciesMeta,
pub werewolf: SpeciesMeta,
pub saurok_occult: SpeciesMeta,
@ -85,7 +89,9 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta>
Species::Ogre => &self.ogre,
Species::Cyclops => &self.cyclops,
Species::Wendigo => &self.wendigo,
Species::Troll => &self.troll,
Species::Cavetroll => &self.troll_cave,
Species::Mountaintroll => &self.troll_mountain,
Species::Swamptroll => &self.troll_swamp,
Species::Dullahan => &self.dullahan,
Species::Werewolf => &self.werewolf,
Species::Occultsaurok => &self.saurok_occult,
@ -102,11 +108,13 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta>
}
}
pub const ALL_SPECIES: [Species; 16] = [
pub const ALL_SPECIES: [Species; 18] = [
Species::Ogre,
Species::Cyclops,
Species::Wendigo,
Species::Troll,
Species::Cavetroll,
Species::Mountaintroll,
Species::Swamptroll,
Species::Dullahan,
Species::Werewolf,
Species::Occultsaurok,

View File

@ -36,6 +36,7 @@ make_case_elim!(
pub enum Species {
Phoenix = 0,
Cockatrice = 1,
Roc = 2,
}
);
@ -46,6 +47,7 @@ make_case_elim!(
pub struct AllSpecies<SpeciesMeta> {
pub phoenix: SpeciesMeta,
pub cockatrice: SpeciesMeta,
pub roc: SpeciesMeta,
}
impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta> {
@ -56,11 +58,12 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta>
match index {
Species::Phoenix => &self.phoenix,
Species::Cockatrice => &self.cockatrice,
Species::Roc => &self.roc,
}
}
}
pub const ALL_SPECIES: [Species; 2] = [Species::Phoenix, Species::Cockatrice];
pub const ALL_SPECIES: [Species; 3] = [Species::Phoenix, Species::Cockatrice, Species::Roc];
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;

View File

@ -88,6 +88,7 @@ make_case_elim!(
BirdMeat = 73,
FishMeat = 74,
SmallMeat = 75,
Tornado = 76,
}
);
@ -98,7 +99,7 @@ impl Body {
}
}
pub const ALL_OBJECTS: [Body; 76] = [
pub const ALL_OBJECTS: [Body; 77] = [
Body::Arrow,
Body::Bomb,
Body::Scarecrow,
@ -175,6 +176,7 @@ pub const ALL_OBJECTS: [Body; 76] = [
Body::BirdMeat,
Body::FishMeat,
Body::SmallMeat,
Body::Tornado,
];
impl From<Body> for super::Body {
@ -260,6 +262,7 @@ impl Body {
Body::BirdMeat => "bird_meat",
Body::FishMeat => "fish_meat",
Body::SmallMeat => "small_meat",
Body::Tornado => "tornado",
}
}
@ -357,6 +360,7 @@ impl Body {
Body::FishMeat => 10.0,
Body::BirdMeat => 10.0,
Body::SmallMeat => 10.0,
Body::Tornado => 50.0,
};
Mass(m)
@ -372,6 +376,7 @@ impl Body {
Body::HaniwaSentry => Vec3::new(0.8, 0.8, 1.4),
Body::SeaLantern => Vec3::new(0.5, 0.5, 1.0),
Body::Snowball => Vec3::broadcast(2.5),
Body::Tornado => Vec3::new(2.0, 2.0, 3.4),
_ => Vec3::broadcast(0.5),
}
}

View File

@ -253,7 +253,12 @@ fn default_main_tool(body: &Body) -> Item {
(biped_large::Species::Ogre, biped_large::BodyType::Female) => Some(
Item::new_from_asset_expect("common.items.npc_weapons.staff.ogre_staff"),
),
(biped_large::Species::Troll, _) => Some(Item::new_from_asset_expect(
(
biped_large::Species::Mountaintroll
| biped_large::Species::Swamptroll
| biped_large::Species::Cavetroll,
_,
) => Some(Item::new_from_asset_expect(
"common.items.npc_weapons.hammer.troll_hammer",
)),
(biped_large::Species::Wendigo, _) => Some(Item::new_from_asset_expect(
@ -300,6 +305,9 @@ fn default_main_tool(body: &Body) -> Item {
object::Body::SeaLantern => Some(Item::new_from_asset_expect(
"common.items.npc_weapons.unique.tidal_totem",
)),
object::Body::Tornado => Some(Item::new_from_asset_expect(
"common.items.npc_weapons.unique.tornado",
)),
_ => None,
},
Body::BipedSmall(biped_small) => match (biped_small.species, biped_small.body_type) {
@ -320,6 +328,9 @@ fn default_main_tool(body: &Body) -> Item {
(bird_large::Species::Phoenix, _) => Some(Item::new_from_asset_expect(
"common.items.npc_weapons.unique.birdlargefire",
)),
(bird_large::Species::Roc, _) => Some(Item::new_from_asset_expect(
"common.items.npc_weapons.unique.birdlargebasic",
)),
},
_ => None,
};

View File

@ -117,7 +117,7 @@ pub enum ServerEvent {
pos: comp::Pos,
stats: comp::Stats,
skill_set: comp::SkillSet,
health: comp::Health,
health: Option<comp::Health>,
poise: comp::Poise,
loadout: comp::inventory::loadout::Loadout,
body: comp::Body,
@ -127,6 +127,7 @@ pub enum ServerEvent {
home_chunk: Option<comp::HomeChunk>,
drop_item: Option<Item>,
rtsim_entity: Option<RtSimEntity>,
projectile: Option<comp::Projectile>,
},
CreateShip {
pos: comp::Pos,

View File

@ -2,7 +2,7 @@ use crate::{
comp::{
self,
inventory::loadout_builder::{self, LoadoutBuilder},
Behavior, BehaviorCapability, CharacterState, StateUpdate,
Behavior, BehaviorCapability, CharacterState, Projectile, StateUpdate,
},
event::{LocalEvent, ServerEvent},
outcome::Outcome,
@ -11,9 +11,13 @@ use crate::{
behavior::{CharacterBehavior, JoinData},
utils::*,
},
terrain::Block,
vol::ReadVol,
};
use rand::Rng;
use serde::{Deserialize, Serialize};
use std::time::Duration;
use std::{f32::consts::PI, time::Duration};
use vek::*;
/// Separated out to condense update portions of character state
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -26,10 +30,14 @@ pub struct StaticData {
pub recover_duration: Duration,
/// How many creatures the state should summon
pub summon_amount: u32,
/// Range of the summons relative to the summonner
pub summon_distance: (f32, f32),
/// Information about the summoned creature
pub summon_info: SummonInfo,
/// Miscellaneous information about the ability
pub ability_info: AbilityInfo,
/// Duration of the summoned entity
pub duration: Option<Duration>,
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -102,15 +110,67 @@ impl CharacterBehavior for Data {
};
let stats = comp::Stats::new("Summon".to_string());
let health_scaling = self
.static_data
.summon_info
.health_scaling
.map(|health_scaling| comp::Health::new(body, health_scaling));
// Ray cast to check where summon should happen
let summon_frac =
self.summon_count as f32 / self.static_data.summon_amount as f32;
let length = rand::thread_rng().gen_range(
self.static_data.summon_distance.0..=self.static_data.summon_distance.1,
);
// Summon in a clockwise fashion
let ray_vector = Vec3::new(
(summon_frac * 2.0 * PI).sin() * length,
(summon_frac * 2.0 * PI).cos() * length,
data.body.eye_height(),
);
// Check for collision on the xy plane
let obstacle_xy = data
.terrain
.ray(data.pos.0, data.pos.0 + length * ray_vector)
.until(Block::is_solid)
.cast()
.0;
let collision_vector = Vec3::new(
data.pos.0.x + (summon_frac * 2.0 * PI).sin() * obstacle_xy,
data.pos.0.y + (summon_frac * 2.0 * PI).cos() * obstacle_xy,
data.pos.0.z + data.body.eye_height(),
);
// Check for collision in z up to 50 blocks
let obstacle_z = data
.terrain
.ray(collision_vector, collision_vector - Vec3::unit_z() * 50.0)
.until(Block::is_solid)
.cast()
.0;
// If a duration is specified, create a projectile componenent for the npc
let projectile = self.static_data.duration.map(|duration| Projectile {
hit_solid: Vec::new(),
hit_entity: Vec::new(),
time_left: duration,
owner: Some(*data.uid),
ignore_group: true,
is_sticky: false,
is_point: false,
});
// Send server event to create npc
update.server_events.push_front(ServerEvent::CreateNpc {
pos: *data.pos,
pos: comp::Pos(collision_vector - Vec3::unit_z() * obstacle_z),
stats,
skill_set,
health: comp::Health::new(
body,
self.static_data.summon_info.health_scaling,
),
health: health_scaling,
poise: comp::Poise::new(body),
loadout,
body,
@ -129,6 +189,7 @@ impl CharacterBehavior for Data {
home_chunk: None,
drop_item: None,
rtsim_entity: None,
projectile,
});
// Send local event used for frontend shenanigans
@ -186,7 +247,7 @@ impl CharacterBehavior for Data {
pub struct SummonInfo {
body: comp::Body,
scale: Option<comp::Scale>,
health_scaling: u16,
health_scaling: Option<u16>,
// TODO: use assets for specifying skills and loadout?
loadout_config: Option<loadout_builder::Preset>,
skillset_config: Option<skillset_builder::Preset>,

View File

@ -5,6 +5,7 @@ use crate::{
InventoryAction, Mass, Melee, Ori, PhysicsState, Pos, SkillSet, StateUpdate, Stats, Vel,
},
resources::DeltaTime,
terrain::TerrainGrid,
uid::Uid,
};
use specs::{
@ -96,6 +97,7 @@ pub struct JoinData<'a> {
pub msm: &'a MaterialStatManifest,
pub combo: &'a Combo,
pub alignment: Option<&'a comp::Alignment>,
pub terrain: &'a TerrainGrid,
}
type RestrictedMut<'a, C> = PairedStorage<
@ -128,6 +130,7 @@ pub struct JoinStruct<'a> {
pub skill_set: &'a SkillSet,
pub combo: &'a Combo,
pub alignment: Option<&'a comp::Alignment>,
pub terrain: &'a TerrainGrid,
}
impl<'a> JoinData<'a> {
@ -161,6 +164,7 @@ impl<'a> JoinData<'a> {
msm,
combo: j.combo,
alignment: j.alignment,
terrain: j.terrain,
}
}
}

View File

@ -1,6 +1,6 @@
use specs::{
shred::ResourceId, Entities, Join, LazyUpdate, Read, ReadStorage, SystemData, World, Write,
WriteStorage,
shred::ResourceId, Entities, Join, LazyUpdate, Read, ReadExpect, ReadStorage, SystemData,
World, Write, WriteStorage,
};
use common::{
@ -16,6 +16,7 @@ use common::{
self,
behavior::{CharacterBehavior, JoinData, JoinStruct},
},
terrain::TerrainGrid,
uid::Uid,
};
use common_ecs::{Job, Origin, Phase, System};
@ -67,6 +68,7 @@ pub struct ReadData<'a> {
msm: Read<'a, MaterialStatManifest>,
combos: ReadStorage<'a, Combo>,
alignments: ReadStorage<'a, comp::Alignment>,
terrain: ReadExpect<'a, TerrainGrid>,
}
/// ## Character Behavior System
@ -280,6 +282,7 @@ impl<'a> System<'a> for Sys {
skill_set: &skill_set,
combo: &combo,
alignment: read_data.alignments.get(entity),
terrain: &read_data.terrain,
};
for action in actions {

View File

@ -1014,7 +1014,7 @@ fn handle_spawn(
pos,
comp::Stats::new(get_npc_name(id, npc::BodyType::from_body(body))),
comp::SkillSet::default(),
comp::Health::new(body, 1),
Some(comp::Health::new(body, 1)),
comp::Poise::new(body),
inventory,
body,
@ -1116,7 +1116,7 @@ fn handle_spawn_training_dummy(
pos,
stats,
skill_set,
health,
Some(health),
poise,
Inventory::new_empty(),
body,

View File

@ -53,7 +53,7 @@ pub fn handle_create_npc(
pos: Pos,
stats: Stats,
skill_set: SkillSet,
health: Health,
health: Option<Health>,
poise: Poise,
loadout: Loadout,
body: Body,
@ -63,6 +63,7 @@ pub fn handle_create_npc(
drop_item: Option<Item>,
home_chunk: Option<HomeChunk>,
rtsim_entity: Option<RtSimEntity>,
projectile: Option<Projectile>,
) {
let inventory = Inventory::new_with_loadout(loadout);
@ -96,6 +97,12 @@ pub fn handle_create_npc(
entity
};
let entity = if let Some(projectile) = projectile {
entity.with(projectile)
} else {
entity
};
let new_entity = entity.build();
// Add to group system if a pet

View File

@ -423,6 +423,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
bird_large::Species::Cockatrice => {
"common.loot_tables.creature.bird_large.cockatrice"
},
bird_large::Species::Roc => "common.loot_tables.creature.bird_large.roc",
_ => "common.loot_tables.creature.bird_large.phoenix",
},
Some(common::comp::Body::FishMedium(_)) => "common.loot_tables.creature.fish",
@ -431,7 +432,11 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
biped_large::Species::Wendigo => {
"common.loot_tables.creature.biped_large.wendigo"
},
biped_large::Species::Troll => "common.loot_tables.creature.biped_large.troll",
biped_large::Species::Cavetroll
| biped_large::Species::Mountaintroll
| biped_large::Species::Swamptroll => {
"common.loot_tables.creature.biped_large.troll"
},
biped_large::Species::Occultsaurok
| biped_large::Species::Mightysaurok
| biped_large::Species::Slysaurok => {

View File

@ -147,6 +147,7 @@ impl Server {
home_chunk,
drop_item,
rtsim_entity,
projectile,
} => handle_create_npc(
self,
pos,
@ -162,6 +163,7 @@ impl Server {
drop_item,
home_chunk,
rtsim_entity,
projectile,
),
ServerEvent::CreateShip {
pos,

View File

@ -127,7 +127,7 @@ impl<'a> System<'a> for Sys {
pos: comp::Pos(spawn_pos),
stats: comp::Stats::new(entity.get_name()),
skill_set: comp::SkillSet::default(),
health: comp::Health::new(body, 10),
health: Some(comp::Health::new(body, 10)),
loadout: match body {
comp::Body::Humanoid(_) => entity.get_loadout(),
_ => LoadoutBuilder::new().build(),
@ -137,6 +137,11 @@ impl<'a> System<'a> for Sys {
agent,
alignment: match body {
comp::Body::Humanoid(_) => comp::Alignment::Npc,
comp::Body::BirdLarge(bird_large) => match bird_large.species {
comp::bird_large::Species::Roc => comp::Alignment::Enemy,
comp::bird_large::Species::Cockatrice => comp::Alignment::Enemy,
_ => comp::Alignment::Wild,
},
_ => comp::Alignment::Wild,
},
scale: match body {
@ -146,6 +151,7 @@ impl<'a> System<'a> for Sys {
drop_item: None,
home_chunk: None,
rtsim_entity,
projectile: None,
},
};
server_emitter.emit(event);

View File

@ -39,7 +39,7 @@ pub trait StateExt {
pos: comp::Pos,
stats: comp::Stats,
skill_set: comp::SkillSet,
health: comp::Health,
health: Option<comp::Health>,
poise: comp::Poise,
inventory: comp::Inventory,
body: comp::Body,
@ -175,7 +175,7 @@ impl StateExt for State {
pos: comp::Pos,
stats: comp::Stats,
skill_set: comp::SkillSet,
health: comp::Health,
health: Option<comp::Health>,
poise: comp::Poise,
inventory: comp::Inventory,
body: comp::Body,
@ -215,7 +215,7 @@ impl StateExt for State {
))
.with(stats)
.with(skill_set)
.with(health)
.maybe_with(health)
.with(poise)
.with(comp::Alignment::Npc)
.with(comp::CharacterState::default())

View File

@ -116,10 +116,12 @@ pub enum Tactic {
Mindflayer,
BirdLargeBreathe,
BirdLargeFire,
BirdLargeBasic,
Minotaur,
ClayGolem,
TidalWarrior,
Yeti,
Tornado,
}
#[derive(SystemData)]
@ -1605,6 +1607,7 @@ impl<'a> AgentData<'a> {
"Haniwa Sentry" => Tactic::RotatingTurret,
"Bird Large Breathe" => Tactic::BirdLargeBreathe,
"Bird Large Fire" => Tactic::BirdLargeFire,
"Bird Large Basic" => Tactic::BirdLargeBasic,
"Mindflayer" => Tactic::Mindflayer,
"Minotaur" => Tactic::Minotaur,
"Clay Golem" => Tactic::ClayGolem,
@ -1833,6 +1836,7 @@ impl<'a> AgentData<'a> {
&tgt_data,
&read_data,
),
Tactic::Tornado => self.handle_tornado_attack(controller),
Tactic::Mindflayer => self.handle_mindflayer_attack(
agent,
controller,
@ -1855,6 +1859,13 @@ impl<'a> AgentData<'a> {
&tgt_data,
&read_data,
),
Tactic::BirdLargeBasic => self.handle_birdlarge_basic_attack(
agent,
controller,
&attack_data,
&tgt_data,
&read_data,
),
Tactic::Minotaur => {
self.handle_minotaur_attack(agent, controller, &attack_data, &tgt_data, &read_data)
},
@ -2906,6 +2917,12 @@ impl<'a> AgentData<'a> {
}
}
fn handle_tornado_attack(&self, controller: &mut Controller) {
controller
.actions
.push(ControlAction::basic_input(InputKind::Primary));
}
fn handle_mindflayer_attack(
&self,
agent: &mut Agent,
@ -3261,6 +3278,76 @@ impl<'a> AgentData<'a> {
}
}
fn handle_birdlarge_basic_attack(
&self,
agent: &mut Agent,
controller: &mut Controller,
attack_data: &AttackData,
tgt_data: &TargetData,
read_data: &ReadData,
) {
const BIRD_ATTACK_RANGE: f32 = 4.0;
const BIRD_CHARGE_DISTANCE: f32 = 15.0;
let bird_attack_distance = self.body.map_or(0.0, |b| b.radius()) + BIRD_ATTACK_RANGE;
// Increase action timer
agent.action_state.timer += read_data.dt.0;
// If higher than 2 blocks
if !read_data
.terrain
.ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * 2.0))
.until(Block::is_solid)
.cast()
.1
.map_or(true, |b| b.is_some())
{
// Fly to target and land
controller
.actions
.push(ControlAction::basic_input(InputKind::Fly));
let move_dir = tgt_data.pos.0 - self.pos.0;
controller.inputs.move_dir =
move_dir.xy().try_normalized().unwrap_or_else(Vec2::zero) * 2.0;
controller.inputs.move_z = move_dir.z - 0.5;
} else if agent.action_state.timer > 8.0 {
// If action timer higher than 8, make bird summon tornadoes
controller
.actions
.push(ControlAction::basic_input(InputKind::Secondary));
if matches!(self.char_state, CharacterState::BasicSummon(c) if matches!(c.stage_section, StageSection::Recover))
{
// Reset timer
agent.action_state.timer = 0.0;
}
} else if matches!(self.char_state, CharacterState::DashMelee(c) if !matches!(c.stage_section, StageSection::Recover))
{
// If already in dash, keep dashing if not in recover
controller
.actions
.push(ControlAction::basic_input(InputKind::Ability(0)));
} else if matches!(self.char_state, CharacterState::ComboMelee(c) if matches!(c.stage_section, StageSection::Recover))
{
// If already in combo keep comboing if not in recover
controller
.actions
.push(ControlAction::basic_input(InputKind::Primary));
} else if attack_data.dist_sqrd > BIRD_CHARGE_DISTANCE.powi(2) {
// Charges at target if they are far enough away
if attack_data.angle < 60.0 {
controller
.actions
.push(ControlAction::basic_input(InputKind::Ability(0)));
}
} else if attack_data.dist_sqrd < bird_attack_distance.powi(2) {
// Combo melee target
controller
.actions
.push(ControlAction::basic_input(InputKind::Primary));
agent.action_state.condition = true;
}
// Make bird move towards target
self.path_toward_target(agent, controller, tgt_data, read_data, true, None);
}
fn handle_minotaur_attack(
&self,
agent: &mut Agent,

View File

@ -239,7 +239,7 @@ impl<'a> System<'a> for Sys {
loadout_builder.build()
};
let health = comp::Health::new(body, entity.level.unwrap_or(0));
let health = Some(comp::Health::new(body, entity.level.unwrap_or(0)));
let poise = comp::Poise::new(body);
let can_speak = match body {
@ -293,6 +293,7 @@ impl<'a> System<'a> for Sys {
home_chunk: Some(comp::HomeChunk(key)),
drop_item: entity.loot_drop,
rtsim_entity: None,
projectile: None,
})
}

View File

@ -210,7 +210,9 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Ogre, Female) => (1.0, 7.5),
(Cyclops, _) => (9.5, 7.5),
(Wendigo, _) => (3.0, 7.5),
(Troll, _) => (6.0, 10.0),
(Cavetroll, _) => (9.0, 7.0),
(Mountaintroll, _) => (13.0, 2.0),
(Swamptroll, _) => (11.0, 2.0),
(Dullahan, _) => (3.0, 6.0),
(Werewolf, _) => (11.5, 1.0),
(Occultsaurok, _) => (6.0, 3.5),
@ -228,7 +230,9 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Ogre, _) => (0.0, 0.0),
(Cyclops, _) => (-4.5, -6.0),
(Wendigo, _) => (0.0, 0.0),
(Troll, _) => (2.0, -4.0),
(Cavetroll, _) => (0.0, -4.0),
(Mountaintroll, _) => (-1.0, -8.0),
(Swamptroll, _) => (-4.0, -4.5),
(Dullahan, _) => (0.0, 0.0),
(Werewolf, _) => (5.0, -4.5),
(Occultsaurok, _) => (1.0, -2.5),
@ -247,7 +251,9 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Ogre, Female) => (0.0, 28.0),
(Cyclops, _) => (-2.0, 31.0),
(Wendigo, _) => (-1.0, 29.0),
(Troll, _) => (-1.0, 26.5),
(Cavetroll, _) => (-1.0, 26.5),
(Mountaintroll, _) => (-1.0, 30.5),
(Swamptroll, _) => (-1.0, 28.5),
(Dullahan, _) => (0.0, 29.0),
(Werewolf, _) => (3.0, 26.0),
(Occultsaurok, _) => (3.0, 24.0),
@ -266,7 +272,9 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Ogre, Female) => (0.0, -6.0),
(Cyclops, _) => (1.0, -8.5),
(Wendigo, _) => (-1.5, -6.0),
(Troll, _) => (1.0, -10.5),
(Cavetroll, _) => (1.0, -9.5),
(Mountaintroll, _) => (1.0, -13.5),
(Swamptroll, _) => (1.5, -11.5),
(Dullahan, _) => (0.0, -6.5),
(Werewolf, _) => (1.0, -10.0),
(Occultsaurok, _) => (0.0, -5.0),
@ -293,7 +301,9 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Ogre, Female) => (8.0, 0.5, 2.0),
(Cyclops, _) => (15.0, 3.5, 1.5),
(Wendigo, _) => (9.0, 0.5, 2.5),
(Troll, _) => (11.0, 0.5, 4.5),
(Cavetroll, _) => (13.0, 0.0, 0.5),
(Mountaintroll, _) => (14.0, -0.5, -2.0),
(Swamptroll, _) => (14.0, 0.0, 0.0),
(Dullahan, _) => (14.0, 0.5, 3.5),
(Werewolf, _) => (9.0, 4.0, -3.0),
(Occultsaurok, _) => (7.5, 1.0, 1.5),
@ -312,7 +322,9 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Ogre, Female) => (9.0, 0.5, -4.5),
(Cyclops, _) => (14.0, 2.0, -5.5),
(Wendigo, _) => (12.0, 0.0, -3.5),
(Troll, _) => (11.5, 0.0, -5.5),
(Cavetroll, _) => (13.5, 1.0, -6.0),
(Mountaintroll, _) => (13.5, 0.0, -10.0),
(Swamptroll, _) => (17.0, 1.0, -8.0),
(Dullahan, _) => (14.5, 0.0, -2.5),
(Werewolf, _) => (10.0, 2.5, -11.0),
(Occultsaurok, _) => (8.0, 1.5, -5.5),
@ -331,7 +343,9 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Ogre, Female) => (0.0, 0.0, -2.0),
(Cyclops, _) => (4.5, 1.0, -8.5),
(Wendigo, _) => (2.0, 2.0, -2.5),
(Troll, _) => (5.0, 0.0, -6.0),
(Cavetroll, _) => (4.5, -1.0, -7.5),
(Mountaintroll, _) => (3.5, 0.0, -7.5),
(Swamptroll, _) => (4.5, -0.5, -7.5),
(Dullahan, _) => (0.0, 0.0, -5.0),
(Werewolf, _) => (4.5, 1.0, -5.0),
(Occultsaurok, _) => (3.0, 0.5, -4.0),
@ -350,7 +364,9 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Ogre, Female) => (4.0, 0.5, -13.5),
(Cyclops, _) => (6.0, 3.5, -15.5),
(Wendigo, _) => (5.0, 2.5, -17.0),
(Troll, _) => (6.0, 1.5, -13.0),
(Cavetroll, _) => (5.5, 0.0, -14.0),
(Mountaintroll, _) => (4.5, 1.0, -14.0),
(Swamptroll, _) => (5.5, 0.0, -14.0),
(Dullahan, _) => (4.0, 2.5, -14.0),
(Werewolf, _) => (5.5, 3.0, -6.5),
(Occultsaurok, _) => (3.5, 3.5, -10.0),
@ -369,7 +385,9 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Ogre, Female) => 1.12,
(Cyclops, _) => 1.28,
(Wendigo, _) => 1.1,
(Troll, _) => 1.1,
(Cavetroll, _) => 1.1,
(Mountaintroll, _) => 1.1,
(Swamptroll, _) => 1.1,
(Dullahan, _) => 1.12,
(Werewolf, _) => 1.0,
(Occultsaurok, _) => 1.0,
@ -387,7 +405,9 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Ogre, Male) => 0.9,
(Ogre, Female) => 0.9,
(Cyclops, _) => 0.8,
(Troll, _) => 0.9,
(Cavetroll, _) => 0.9,
(Mountaintroll, _) => 0.9,
(Swamptroll, _) => 0.9,
(Dullahan, _) => 0.8,
(Minotaur, _) => 0.8,
_ => 1.0,
@ -397,7 +417,9 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Ogre, Female) => (8.0, 0.0),
(Cyclops, _) => (12.0, 0.0),
(Wendigo, _) => (15.0, 0.0),
(Troll, _) => (12.0, 0.0),
(Cavetroll, _) => (13.0, 1.5),
(Mountaintroll, _) => (13.0, 1.5),
(Swamptroll, _) => (15.0, 0.5),
(Dullahan, _) => (15.0, 0.0),
(Werewolf, _) => (13.0, 0.0),
(Occultsaurok, _) => (10.0, 0.0),
@ -428,29 +450,14 @@ impl<'a> From<&'a Body> for SkeletonAttr {
},
hhl: match (body.species, body.body_type) {
(Ogre, Male) => (-9.0, -10.0, 23.0, 1.57, -0.57, 0.0),
(Cyclops, _) => (-6.0, -10.0, 17.0, 1.57, -0.57, 0.0),
(Troll, _) => (-6.0, -10.0, 17.0, 1.57, -0.57, 0.0),
(Yeti, _) => (-6.0, -10.0, 17.0, 1.57, -0.57, 0.0),
(Blueoni, _) => (-6.0, -10.0, 17.0, 1.57, -0.57, 0.0),
(Redoni, _) => (-6.0, -10.0, 17.0, 1.57, -0.57, 0.0),
_ => (-6.0, -10.0, 17.0, 1.57, -0.57, 0.0),
},
hhr: match (body.species, body.body_type) {
(Ogre, Male) => (-5.0, -13.0, 0.0, 1.57, -0.57, 0.0),
(Cyclops, _) => (-6.0, -10.0, 0.0, 1.57, -0.57, 0.0),
(Troll, _) => (-6.0, -10.0, 0.0, 1.57, -0.57, 0.0),
(Yeti, _) => (-6.0, -10.0, 0.0, 1.57, -0.57, 0.0),
(Blueoni, _) => (-6.0, -10.0, 0.0, 1.57, -0.57, 0.0),
(Redoni, _) => (-6.0, -10.0, 0.0, 1.57, -0.57, 0.0),
_ => (-6.0, -10.0, 0.0, 1.57, -0.57, 0.0),
},
hc: match (body.species, body.body_type) {
(Ogre, Male) => (11.5, 9.0, -13.0, -0.57, -1.57, 1.0),
(Cyclops, _) => (8.5, 6.0, -12.0, -0.57, -1.57, 1.0),
(Troll, _) => (8.5, 6.0, -12.0, -0.57, -1.57, 1.0),
(Yeti, _) => (8.5, 6.0, -12.0, -0.57, -1.57, 1.0),
(Blueoni, _) => (8.5, 6.0, -12.0, -0.57, -1.57, 1.0),
(Redoni, _) => (8.5, 6.0, -12.0, -0.57, -1.57, 1.0),
_ => (8.5, 6.0, -12.0, -0.57, -1.57, 1.0),
},
sthl: match (body.species, body.body_type) {

View File

@ -0,0 +1,177 @@
use super::{
super::{vek::*, Animation},
BirdLargeSkeleton, SkeletonAttr,
};
use common::states::utils::StageSection;
use std::f32::consts::PI;
pub struct DashAnimation;
type DashAnimationDependency<'a> = (
Vec3<f32>,
Vec3<f32>,
Vec3<f32>,
f32,
Option<StageSection>,
f32,
f32,
);
impl Animation for DashAnimation {
type Dependency<'a> = DashAnimationDependency<'a>;
type Skeleton = BirdLargeSkeleton;
#[cfg(feature = "use-dyn-lib")]
const UPDATE_FN: &'static [u8] = b"bird_large_dash\0";
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_dash")]
fn update_skeleton_inner<'a>(
skeleton: &Self::Skeleton,
(velocity, orientation, last_ori, acc_vel, stage_section, global_time, timer): Self::Dependency<'a>,
anim_time: f32,
rate: &mut f32,
s_a: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
let speed = (Vec2::<f32>::from(velocity).magnitude()).min(22.0);
*rate = 1.0;
let (movement1base, chargemovementbase, movement2base, movement3, legtell) =
match stage_section {
Some(StageSection::Buildup) => (anim_time.sqrt(), 0.0, 0.0, 0.0, anim_time),
Some(StageSection::Charge) => (1.0, 1.0, 0.0, 0.0, 0.0),
Some(StageSection::Swing) => (1.0, 0.0, anim_time.powi(4), 0.0, 1.0),
Some(StageSection::Recover) => (1.0, 0.0, 1.0, anim_time, 1.0),
_ => (0.0, 0.0, 0.0, 0.0, 0.0),
};
let pullback = 1.0 - movement3;
let subtract = global_time - timer;
let check = subtract - subtract.trunc();
let mirror = (check - 0.5).signum();
let movement1abs = movement1base * pullback;
let movement2abs = movement2base * pullback;
let legtwitch = (legtell * 6.0).sin() * pullback;
let legswing = legtell * pullback;
let chargeanim = (chargemovementbase * anim_time * 15.0).sin();
//let speednorm = speed / 13.0;
let speednorm = (speed / 13.0).powf(0.25);
let speedmult = 0.8;
let lab: f32 = 0.6; //6
// acc_vel and anim_time mix to make sure phase lenght isn't starting at
// +infinite
let mixed_vel = acc_vel + anim_time * 5.0; //sets run frequency using speed, with anim_time setting a floor
let short = ((1.0
/ (0.72
+ 0.28 * ((mixed_vel * 1.0 * lab * speedmult + PI * -0.15 - 0.5).sin()).powi(2)))
.sqrt())
* ((mixed_vel * 1.0 * lab * speedmult + PI * -0.15 - 0.5).sin())
* speednorm;
//
let shortalt = (mixed_vel * 1.0 * lab * speedmult + PI * 3.0 / 8.0 - 0.5).sin() * speednorm;
let ori: Vec2<f32> = Vec2::from(orientation);
let last_ori = Vec2::from(last_ori);
let tilt = if ::vek::Vec2::new(ori, last_ori)
.map(|o| o.magnitude_squared())
.map(|m| m > 0.001 && m.is_finite())
.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.head.scale = Vec3::one() * 0.98;
next.neck.scale = Vec3::one() * 1.02;
next.leg_l.scale = Vec3::one() / 8.0 * 0.98;
next.leg_r.scale = Vec3::one() / 8.0 * 0.98;
next.foot_l.scale = Vec3::one() * 1.02;
next.foot_r.scale = Vec3::one() * 1.02;
next.chest.scale = Vec3::one() * s_a.scaler / 8.0;
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
next.head.orientation = Quaternion::rotation_x(
-0.1 * speednorm + short * -0.05 + movement1abs * -0.8 + movement2abs * 0.2,
) * Quaternion::rotation_y(tilt * 0.2)
* Quaternion::rotation_z(shortalt * -0.05 - tilt * 1.5);
next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1);
next.beak.orientation =
Quaternion::rotation_x(short * -0.02 - 0.02 + movement1abs * -0.4 + movement2abs * 0.4);
next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1);
next.neck.orientation = Quaternion::rotation_x(-0.1 * speednorm + short * -0.04)
* Quaternion::rotation_y(tilt * 0.1)
* Quaternion::rotation_z(shortalt * -0.1 - tilt * 0.5);
next.chest.position = Vec3::new(
0.0,
s_a.chest.0,
s_a.chest.1 + short * 0.5 + 0.5 * speednorm,
) * s_a.scaler
/ 8.0;
next.chest.orientation =
Quaternion::rotation_x(short * 0.07 + movement1abs * 0.8 + movement2abs * -1.2)
* Quaternion::rotation_y(tilt * 0.8)
* Quaternion::rotation_z(shortalt * 0.10);
next.tail_front.position = Vec3::new(0.0, s_a.tail_front.0, s_a.tail_front.1);
next.tail_front.orientation =
Quaternion::rotation_x(0.6 + short * -0.02 + movement1abs * -0.8 + movement2abs * 0.8);
next.tail_rear.position = Vec3::new(0.0, s_a.tail_rear.0, s_a.tail_rear.1);
next.tail_rear.orientation = Quaternion::rotation_x(-0.2 + short * -0.1);
next.wing_in_l.position = Vec3::new(-s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2);
next.wing_in_r.position = Vec3::new(s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2);
next.wing_in_l.orientation =
Quaternion::rotation_y(
-0.8 + movement1abs * 1.0 + chargeanim * 0.2 - movement2abs * 0.6,
) * Quaternion::rotation_z(0.2 - movement1abs * 0.6 - movement2abs * 0.6);
next.wing_in_r.orientation =
Quaternion::rotation_y(
0.8 - movement1abs * 1.0 - chargeanim * 0.2 + movement2abs * 0.6,
) * Quaternion::rotation_z(-0.2 + movement1abs * 0.6 + movement2abs * 0.6);
next.wing_mid_l.position = Vec3::new(-s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2);
next.wing_mid_r.position = Vec3::new(s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2);
next.wing_mid_l.orientation = Quaternion::rotation_y(-0.1) * Quaternion::rotation_z(0.7);
next.wing_mid_r.orientation = Quaternion::rotation_y(0.1) * Quaternion::rotation_z(-0.7);
next.wing_out_l.position = Vec3::new(-s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2);
next.wing_out_r.position = Vec3::new(s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2);
next.wing_out_l.orientation =
Quaternion::rotation_y(-0.2 + short * 0.05) * Quaternion::rotation_z(0.2);
next.wing_out_r.orientation =
Quaternion::rotation_y(0.2 + short * -0.05) * Quaternion::rotation_z(-0.2);
if legtell > 0.0 {
if mirror.is_sign_positive() {
next.leg_l.orientation = Quaternion::rotation_x(legswing * 1.1);
next.foot_l.orientation = Quaternion::rotation_x(legswing * -1.1 + legtwitch * 0.5);
next.leg_r.orientation = Quaternion::rotation_x(0.0);
next.foot_r.orientation = Quaternion::rotation_x(0.0);
} else {
next.leg_l.orientation = Quaternion::rotation_x(0.0);
next.foot_l.orientation = Quaternion::rotation_x(0.0);
next.leg_r.orientation = Quaternion::rotation_x(legswing * 1.1);
next.foot_r.orientation = Quaternion::rotation_x(legswing * -1.1 + legtwitch * 0.5);
}
}
next
}
}

View File

@ -1,5 +1,6 @@
pub mod alpha;
pub mod breathe;
pub mod dash;
pub mod feed;
pub mod fly;
pub mod idle;
@ -7,13 +8,14 @@ pub mod run;
pub mod shockwave;
pub mod shoot;
pub mod stunned;
pub mod summon;
pub mod swim;
// Reexports
pub use self::{
alpha::AlphaAnimation, breathe::BreatheAnimation, feed::FeedAnimation, fly::FlyAnimation,
idle::IdleAnimation, run::RunAnimation, shockwave::ShockwaveAnimation, shoot::ShootAnimation,
stunned::StunnedAnimation, swim::SwimAnimation,
alpha::AlphaAnimation, breathe::BreatheAnimation, dash::DashAnimation, feed::FeedAnimation,
fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation, shockwave::ShockwaveAnimation,
shoot::ShootAnimation, stunned::StunnedAnimation, summon::SummonAnimation, swim::SwimAnimation,
};
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
@ -149,54 +151,67 @@ impl<'a> From<&'a Body> for SkeletonAttr {
chest: match (body.species, body.body_type) {
(Phoenix, _) => (2.5, 16.0),
(Cockatrice, _) => (2.5, 16.0),
(Roc, _) => (2.5, 27.5),
},
neck: match (body.species, body.body_type) {
(Phoenix, _) => (2.5, -5.5),
(Cockatrice, _) => (5.0, -1.5),
(Roc, _) => (9.5, -1.5),
},
head: match (body.species, body.body_type) {
(Phoenix, _) => (6.0, 12.0),
(Cockatrice, _) => (8.0, 4.5),
(Roc, _) => (17.0, -3.5),
},
beak: match (body.species, body.body_type) {
(Phoenix, _) => (5.0, 3.0),
(Cockatrice, _) => (2.0, -3.0),
(Roc, _) => (0.0, -3.0),
},
tail_front: match (body.species, body.body_type) {
(Phoenix, _) => (-9.5, -1.0),
(Cockatrice, _) => (-5.0, -2.5),
(Roc, _) => (-7.5, -3.5),
},
tail_rear: match (body.species, body.body_type) {
(Phoenix, _) => (-11.0, 0.0),
(Cockatrice, _) => (-8.0, -3.0),
(Roc, _) => (-8.0, -3.0),
},
wing_in: match (body.species, body.body_type) {
(Phoenix, _) => (3.0, 2.5, 2.0),
(Cockatrice, _) => (3.5, 7.0, 3.5),
(Roc, _) => (5.5, 7.5, -1.0),
},
wing_mid: match (body.species, body.body_type) {
(Phoenix, _) => (10.0, 1.0, 0.0),
(Cockatrice, _) => (6.0, 0.0, 0.0),
(Roc, _) => (12.0, 1.0, -0.5),
},
wing_out: match (body.species, body.body_type) {
(Phoenix, _) => (7.0, 2.0, 1.5),
(Cockatrice, _) => (4.0, -1.0, 1.0),
(Roc, _) => (10.0, -2.0, 0.0),
},
leg: match (body.species, body.body_type) {
(Phoenix, _) => (4.0, 1.5, 12.0),
(Cockatrice, _) => (3.5, 2.5, 13.0),
(Roc, _) => (5.5, -1.5, 17.5),
},
foot: match (body.species, body.body_type) {
(Phoenix, _) => (0.5, -0.5, -2.5),
(Cockatrice, _) => (0.5, -3.0, -3.0),
(Roc, _) => (2.5, -2.5, -5.5),
},
scaler: match (body.species, body.body_type) {
(Phoenix, _) => (1.0),
(Cockatrice, _) => (1.0),
(Roc, _) => (1.0),
},
feed: match (body.species, body.body_type) {
(Phoenix, _) => (-0.65),
(Cockatrice, _) => (-0.5),
(Roc, _) => (-0.4),
},
}
}

View File

@ -0,0 +1,114 @@
use super::{
super::{vek::*, Animation},
BirdLargeSkeleton, SkeletonAttr,
};
use common::{states::utils::StageSection, util::Dir};
pub struct SummonAnimation;
type SummonAnimationDependency = (f32, Option<StageSection>, f32, Dir, bool);
impl Animation for SummonAnimation {
type Dependency<'a> = SummonAnimationDependency;
type Skeleton = BirdLargeSkeleton;
#[cfg(feature = "use-dyn-lib")]
const UPDATE_FN: &'static [u8] = b"bird_large_summon\0";
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_summon")]
#[allow(clippy::approx_constant)] // TODO: Pending review in #587
fn update_skeleton_inner<'a>(
skeleton: &Self::Skeleton,
(global_time, stage_section, timer, look_dir, on_ground): Self::Dependency<'a>,
anim_time: f32,
rate: &mut f32,
s_a: &SkeletonAttr,
) -> Self::Skeleton {
*rate = 1.0;
let mut next = (*skeleton).clone();
let (movement1base, movement2base, movement3, twitch) = match stage_section {
Some(StageSection::Buildup) => (anim_time.powf(0.25), 0.0, 0.0, 0.0),
Some(StageSection::Cast) => (1.0, anim_time.min(1.0).powf(0.1), 0.0, anim_time),
Some(StageSection::Recover) => (1.0, 1.0, anim_time.min(1.0).powi(2), 1.0),
_ => (0.0, 0.0, 0.0, 0.0),
};
let pullback = 1.0 - movement3;
let subtract = global_time - timer;
let check = subtract - subtract.trunc();
let mirror = (check - 0.5).signum();
let twitch2 = mirror * (twitch * 20.0).sin() * pullback;
let movement1abs = movement1base * pullback;
let movement2abs = movement2base * pullback;
let wave_slow_cos = (anim_time * 4.5).cos();
next.head.scale = Vec3::one() * 0.98;
next.neck.scale = Vec3::one() * 1.02;
next.leg_l.scale = Vec3::one() / 8.0 * 0.98;
next.leg_r.scale = Vec3::one() / 8.0 * 0.98;
next.foot_l.scale = Vec3::one() * 1.02;
next.foot_r.scale = Vec3::one() * 1.02;
next.chest.scale = Vec3::one() * s_a.scaler / 8.0;
next.chest.position = Vec3::new(
0.0,
s_a.chest.0,
s_a.chest.1 + wave_slow_cos * 0.06 + twitch2 * 0.1,
) * s_a.scaler
/ 8.0;
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
next.head.orientation =
Quaternion::rotation_x(movement1abs * -1.0 - movement2abs * 0.1 + look_dir.z * 0.4);
next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1);
next.beak.orientation = Quaternion::rotation_x(movement1abs * -0.7 + twitch2 * 0.1);
if on_ground {
next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1);
next.neck.orientation = Quaternion::rotation_x(movement1abs * 0.5 - movement2abs * 0.5);
next.chest.orientation =
Quaternion::rotation_x(movement1abs * 1.1 - movement2abs * 0.1);
next.wing_in_l.position = Vec3::new(-s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2);
next.wing_in_r.position = Vec3::new(s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2);
next.wing_in_l.orientation =
Quaternion::rotation_x(movement1abs * 0.4 - movement2abs * 0.4)
* Quaternion::rotation_y(-1.0 + movement1abs * 1.6 - movement2abs * 1.8)
* Quaternion::rotation_z(0.2 - movement1abs * 1.8 + movement2abs * 0.4);
next.wing_in_r.orientation =
Quaternion::rotation_x(movement1abs * 0.4 - movement2abs * 0.4)
* Quaternion::rotation_y(1.0 - movement1abs * 1.6 + movement2abs * 1.8)
* Quaternion::rotation_z(-0.2 + movement1abs * 1.8 - movement2abs * 0.4);
next.wing_mid_l.position = Vec3::new(-s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2);
next.wing_mid_r.position = Vec3::new(s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2);
next.wing_mid_l.orientation =
Quaternion::rotation_y(-0.1 - movement2abs * 0.4) * Quaternion::rotation_z(0.7);
next.wing_mid_r.orientation =
Quaternion::rotation_y(0.1 + movement2abs * 0.4) * Quaternion::rotation_z(-0.7);
next.wing_out_l.position = Vec3::new(-s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2);
next.wing_out_r.position = Vec3::new(s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2);
next.wing_out_l.orientation =
Quaternion::rotation_y(-0.2 - movement2abs * 0.4) * Quaternion::rotation_z(0.2);
next.wing_out_r.orientation =
Quaternion::rotation_y(0.2 + movement2abs * 0.4) * Quaternion::rotation_z(-0.2);
next.tail_front.position = Vec3::new(0.0, s_a.tail_front.0, s_a.tail_front.1);
next.tail_front.orientation =
Quaternion::rotation_x(-movement1abs * 0.1 + movement2abs * 0.1 + twitch2 * 0.02);
next.tail_rear.position = Vec3::new(0.0, s_a.tail_rear.0, s_a.tail_rear.1);
next.tail_rear.orientation =
Quaternion::rotation_x(-movement1abs * 0.1 + movement2abs * 0.1 + twitch2 * 0.02);
} else {
}
next
}
}

View File

@ -80,7 +80,7 @@ impl Default for BoneData {
}
pub struct FigureModel {
pub opaque: Model<Vertex>,
pub opaque: Option<Model<Vertex>>,
/* TODO: Consider using mipmaps instead of storing multiple texture atlases for different
* LOD levels. */
}

View File

@ -83,6 +83,7 @@ pub enum ParticleMode {
Water = 30,
IceSpikes = 31,
Drip = 32,
Tornado = 33,
}
impl ParticleMode {

Some files were not shown because too many files have changed in this diff Show More