mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'halloween' into 'master'
Halloween event See merge request veloren/veloren!3668
This commit is contained in:
commit
51d4c8dd51
@ -121,6 +121,11 @@
|
||||
(None, "common.abilities.custom.woodgolem.shockwave")
|
||||
],
|
||||
),
|
||||
Custom("Simple Flying Melee"): (
|
||||
primary: "common.abilities.custom.simpleflyingmelee.singlestrike",
|
||||
secondary: "common.abilities.custom.simpleflyingmelee.singlestrike",
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Sword Simple"): (
|
||||
primary: "common.abilities.swordsimple.doublestrike",
|
||||
secondary: "common.abilities.swordsimple.dash",
|
||||
|
@ -0,0 +1,28 @@
|
||||
ComboMelee(
|
||||
stage_data: [
|
||||
(
|
||||
stage: 1,
|
||||
base_damage: 1.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 0.0,
|
||||
range: 2.5,
|
||||
angle: 150.0,
|
||||
base_buildup_duration: 0.1,
|
||||
base_swing_duration: 0.07,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.2,
|
||||
forward_movement: 0.0,
|
||||
damage_kind: Piercing,
|
||||
),
|
||||
],
|
||||
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.6,
|
||||
)
|
@ -0,0 +1,11 @@
|
||||
#![enable(implicit_some)]
|
||||
(
|
||||
name: Name("Dullahan"),
|
||||
body: RandomWith("dullahan"),
|
||||
alignment: Alignment(Enemy),
|
||||
loot: LootTable("common.loot_tables.calendar.halloween.halloween_dullahan"),
|
||||
inventory: (
|
||||
loadout: FromBody,
|
||||
),
|
||||
meta: [],
|
||||
)
|
@ -0,0 +1,11 @@
|
||||
#![enable(implicit_some)]
|
||||
(
|
||||
name: Name("Harvester"),
|
||||
body: RandomWith("harvester"),
|
||||
alignment: Alignment(Enemy),
|
||||
loot: LootTable("common.loot_tables.calendar.halloween.halloween_harvester"),
|
||||
inventory: (
|
||||
loadout: FromBody,
|
||||
),
|
||||
meta: [],
|
||||
)
|
@ -0,0 +1,24 @@
|
||||
#![enable(implicit_some)]
|
||||
(
|
||||
name: Name("Trickster"),
|
||||
body: RandomWith("draugr"),
|
||||
alignment: Alignment(Enemy),
|
||||
loot: LootTable("common.loot_tables.calendar.halloween.trickster"),
|
||||
inventory: (
|
||||
loadout: Inline((
|
||||
inherit: Asset("common.loadout.calendar.halloween.trickster"),
|
||||
active_hands: InHands((Choice([
|
||||
(1, Item("common.items.tool.instruments.bass")),
|
||||
(1, Item("common.items.tool.instruments.flute")),
|
||||
(1, Item("common.items.tool.instruments.harp")),
|
||||
(1, Item("common.items.tool.instruments.kalimba")),
|
||||
(1, Item("common.items.tool.instruments.sitar")),
|
||||
(1, Item("common.items.tool.instruments.perc")),
|
||||
(1, Item("common.items.tool.instruments.lute")),
|
||||
(1, Item("common.items.tool.instruments.guitar")),
|
||||
(1, Item("common.items.tool.instruments.melodica")),
|
||||
]), None)),
|
||||
)),
|
||||
),
|
||||
meta: [],
|
||||
)
|
11
assets/common/entity/wild/aggressive/bat.ron
Normal file
11
assets/common/entity/wild/aggressive/bat.ron
Normal file
@ -0,0 +1,11 @@
|
||||
#![enable(implicit_some)]
|
||||
(
|
||||
name: Automatic,
|
||||
body: RandomWith("bat"),
|
||||
alignment: Alignment(Enemy),
|
||||
loot: LootTable("common.loot_tables.creature.bat"),
|
||||
inventory: (
|
||||
loadout: FromBody,
|
||||
),
|
||||
meta: [],
|
||||
)
|
13
assets/common/items/armor/misc/head/facegourd.ron
Normal file
13
assets/common/items/armor/misc/head/facegourd.ron
Normal file
@ -0,0 +1,13 @@
|
||||
ItemDef(
|
||||
name: "Pumpkin Head.",
|
||||
description: "Halloween attire.",
|
||||
kind: Armor((
|
||||
kind: Head,
|
||||
stats: Direct((
|
||||
energy_max: Some(4.0),
|
||||
energy_reward: Some(0.04),
|
||||
)),
|
||||
)),
|
||||
quality: Common,
|
||||
tags: [],
|
||||
)
|
22
assets/common/items/food/honeycorn.ron
Normal file
22
assets/common/items/food/honeycorn.ron
Normal file
@ -0,0 +1,22 @@
|
||||
ItemDef(
|
||||
name: "Honeycorn",
|
||||
description: "Sweeet",
|
||||
kind: Consumable(
|
||||
kind: Food,
|
||||
effects: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
data: (
|
||||
strength: 4.0,
|
||||
duration: Some((
|
||||
secs: 5,
|
||||
nanos: 0,
|
||||
)),
|
||||
),
|
||||
cat_ids: [Natural],
|
||||
)),
|
||||
]
|
||||
),
|
||||
quality: Common,
|
||||
tags: [Food],
|
||||
)
|
22
assets/common/items/food/pumpkin_spice_brew.ron
Normal file
22
assets/common/items/food/pumpkin_spice_brew.ron
Normal file
@ -0,0 +1,22 @@
|
||||
ItemDef(
|
||||
name: "Pumpkin Spice Brew",
|
||||
description: "Brewed from moldy pumpkins.",
|
||||
kind: Consumable(
|
||||
kind: Drink,
|
||||
effects: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
data: (
|
||||
strength: 10.0,
|
||||
duration: Some((
|
||||
secs: 5,
|
||||
nanos: 0,
|
||||
)),
|
||||
),
|
||||
cat_ids: [Natural],
|
||||
)),
|
||||
]
|
||||
),
|
||||
quality: Moderate,
|
||||
tags: [Food],
|
||||
)
|
21
assets/common/items/npc_weapons/unique/simpleflyingbasic.ron
Normal file
21
assets/common/items/npc_weapons/unique/simpleflyingbasic.ron
Normal file
@ -0,0 +1,21 @@
|
||||
ItemDef(
|
||||
name: "Simple Flying Melee",
|
||||
description: "I believe I can fly!!!!!",
|
||||
kind: Tool((
|
||||
kind: Natural,
|
||||
hands: Two,
|
||||
stats: (
|
||||
equip_time_secs: 0.01,
|
||||
power: 1.0,
|
||||
effect_power: 1.0,
|
||||
speed: 1.0,
|
||||
crit_chance: 0.0625,
|
||||
range: 1.0,
|
||||
energy_efficiency: 1.0,
|
||||
buff_strength: 1.0,
|
||||
),
|
||||
)),
|
||||
quality: Low,
|
||||
tags: [],
|
||||
ability_spec: Some(Custom("Simple Flying Melee")),
|
||||
)
|
30
assets/common/loadout/calendar/halloween/trickster.ron
Normal file
30
assets/common/loadout/calendar/halloween/trickster.ron
Normal file
@ -0,0 +1,30 @@
|
||||
#![enable(implicit_some)]
|
||||
(
|
||||
head: Choice([
|
||||
(1, Item("common.items.armor.misc.head.bamboo_twig")),
|
||||
(1, Item("common.items.armor.misc.head.boreal_warhelm")),
|
||||
(1, Item("common.items.armor.misc.head.crown")),
|
||||
(1, Item("common.items.armor.misc.head.facegourd")),
|
||||
(1, Item("common.items.armor.misc.head.helmet")),
|
||||
(1, Item("common.items.armor.misc.head.hog_hood")),
|
||||
(1, Item("common.items.armor.misc.head.hood")),
|
||||
(1, Item("common.items.armor.misc.head.hood_dark")),
|
||||
(1, Item("common.items.armor.misc.head.mitre")),
|
||||
(1, Item("common.items.armor.misc.head.spikeguard")),
|
||||
(1, Item("common.items.armor.misc.head.straw")),
|
||||
(1, Item("common.items.armor.misc.head.wanderers_hat")),
|
||||
(1, Item("common.items.armor.misc.head.winged_coronet")),
|
||||
(1, Item("common.items.armor.misc.head.bandana.red")),
|
||||
(1, Item("common.items.armor.misc.head.bandana.thief")),
|
||||
]),
|
||||
chest: Choice([
|
||||
(1, Item("common.items.armor.leather_plate.chest")),
|
||||
]),
|
||||
legs: Choice([
|
||||
(1, Item("common.items.armor.leather_plate.pants")),
|
||||
]),
|
||||
feet: Choice([
|
||||
(1, Item("common.items.armor.misc.foot.sandals")),
|
||||
(1, Item("common.items.armor.cloth_blue.foot")),
|
||||
]),
|
||||
)
|
@ -0,0 +1,4 @@
|
||||
[
|
||||
(1.0, Item("common.items.food.pumpkin_spice_brew")),
|
||||
(5.0, Item("common.items.food.honeycorn")),
|
||||
]
|
@ -0,0 +1,9 @@
|
||||
[
|
||||
// Weapons
|
||||
(5.0, LootTable("common.loot_tables.weapons.tier-3")),
|
||||
// Armor
|
||||
(5.0, LootTable("common.loot_tables.armor.tier-3")),
|
||||
// Misc
|
||||
(2.0, Item("common.items.armor.misc.head.facegourd")),
|
||||
(2.0, Item("common.items.lantern.pumpkin")),
|
||||
]
|
@ -0,0 +1,4 @@
|
||||
[
|
||||
(1.0, Item("common.items.food.pumpkin_spice_brew")),
|
||||
(5.0, Item("common.items.food.honeycorn")),
|
||||
]
|
9
assets/common/loot_tables/creature/bat.ron
Normal file
9
assets/common/loot_tables/creature/bat.ron
Normal file
@ -0,0 +1,9 @@
|
||||
[
|
||||
// halloween event loot
|
||||
(2.0, Item("common.items.food.pumpkin_spice_brew")),
|
||||
(5.0, Item("common.items.food.honeycorn")),
|
||||
|
||||
// crafting
|
||||
(1.0, Item("common.items.crafting_ing.hide.animal_hide")),
|
||||
(1.0, Item("common.items.crafting_ing.animal_misc.sharp_fang")),
|
||||
]
|
@ -824,6 +824,10 @@
|
||||
keyword: "penguin",
|
||||
generic: "Penguin"
|
||||
),
|
||||
bat: (
|
||||
keyword: "bat",
|
||||
generic: "Bat"
|
||||
),
|
||||
)
|
||||
),
|
||||
biped_large: (
|
||||
|
@ -992,6 +992,18 @@
|
||||
],
|
||||
threshold: 0.3,
|
||||
),
|
||||
Inventory(Consumed("Honeycorn")): (
|
||||
files: [
|
||||
"voxygen.audio.sfx.inventory.consumable.food",
|
||||
],
|
||||
threshold: 0.3,
|
||||
),
|
||||
Inventory(Consumed("Pumpkin Spice Brew")): (
|
||||
files: [
|
||||
"voxygen.audio.sfx.inventory.consumable.liquid",
|
||||
],
|
||||
threshold: 0.3,
|
||||
),
|
||||
|
||||
//
|
||||
//Combat
|
||||
|
@ -2858,6 +2858,10 @@
|
||||
"voxel.armor.misc.head.spikeguard",
|
||||
(0.0, 0.0, 0.0), (-120.0, 210.0,15.0), 1.3,
|
||||
),
|
||||
Simple("common.items.armor.misc.head.facegourd"): VoxTrans(
|
||||
"voxel.armor.misc.head.facegourd",
|
||||
(0.0, 0.0, 0.0), (-120.0, 210.0,15.0), 1.3,
|
||||
),
|
||||
Simple("common.items.armor.misc.head.winged_coronet"): VoxTrans(
|
||||
"voxel.armor.misc.head.winged_coronet",
|
||||
(0.0, 0.0, 0.0), (-120.0, 210.0,15.0), 1.3,
|
||||
@ -3129,6 +3133,14 @@
|
||||
"voxel.object.sunflower_ice_tea",
|
||||
(0.0, 0.0, 0.0), (-50.0, -60.0, -35.0), 0.9,
|
||||
),
|
||||
Simple("common.items.food.pumpkin_spice_brew"): VoxTrans(
|
||||
"voxel.object.pumpkin_spice_brew",
|
||||
(0.0, 0.0, 0.0), (-50.0, -60.0, -35.0), 0.9,
|
||||
),
|
||||
Simple("common.items.food.honeycorn"): VoxTrans(
|
||||
"voxel.object.honeycorn",
|
||||
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9,
|
||||
),
|
||||
Simple("common.items.food.carrot"): VoxTrans(
|
||||
"voxel.sprite.carrot.carrot",
|
||||
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9,
|
||||
|
BIN
assets/voxygen/voxel/armor/misc/head/facegourd.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/misc/head/facegourd.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -223,4 +223,32 @@
|
||||
central: ("npc.penguin.male.tail"),
|
||||
)
|
||||
),
|
||||
(Bat, Male): (
|
||||
head: (
|
||||
offset: (-4.5, 2.0, -11.0),
|
||||
central: ("npc.bat.male.head"),
|
||||
),
|
||||
torso: (
|
||||
offset: (-3.5, -5.0, -6.5),
|
||||
central: ("npc.bat.male.torso"),
|
||||
),
|
||||
tail: (
|
||||
offset: (-2.5, -1.5, -1.5),
|
||||
central: ("npc.bat.male.tail"),
|
||||
)
|
||||
),
|
||||
(Bat, Female): (
|
||||
head: (
|
||||
offset: (-4.5, 2.0, -11.0),
|
||||
central: ("npc.bat.male.head"),
|
||||
),
|
||||
torso: (
|
||||
offset: (-3.5, -5.0, -6.5),
|
||||
central: ("npc.bat.male.torso"),
|
||||
),
|
||||
tail: (
|
||||
offset: (-2.5, -1.5, -1.5),
|
||||
central: ("npc.bat.male.tail"),
|
||||
)
|
||||
),
|
||||
})
|
@ -287,4 +287,40 @@
|
||||
lateral: ("npc.penguin.male.leg_r"),
|
||||
)
|
||||
),
|
||||
(Bat, Male): (
|
||||
wing_l: (
|
||||
offset: (-13.0, 2.5, -3.5),
|
||||
lateral: ("npc.bat.male.wing_r"),
|
||||
),
|
||||
wing_r: (
|
||||
offset: (-1.0, 2.5, -3.5),
|
||||
lateral: ("npc.bat.male.wing_r"),
|
||||
),
|
||||
foot_l: (
|
||||
offset: (-2.0, 2.0, -8.5),
|
||||
lateral: ("npc.bat.male.leg_r"),
|
||||
),
|
||||
foot_r: (
|
||||
offset: (-2.0, 2.0, -8.5),
|
||||
lateral: ("npc.bat.male.leg_r"),
|
||||
)
|
||||
),
|
||||
(Bat, Female): (
|
||||
wing_l: (
|
||||
offset: (-13.0, 2.5, -3.5),
|
||||
lateral: ("npc.bat.male.wing_r"),
|
||||
),
|
||||
wing_r: (
|
||||
offset: (-1.0, 2.5, -3.5),
|
||||
lateral: ("npc.bat.male.wing_r"),
|
||||
),
|
||||
foot_l: (
|
||||
offset: (-2.0, 2.0, -8.5),
|
||||
lateral: ("npc.bat.male.leg_r"),
|
||||
),
|
||||
foot_r: (
|
||||
offset: (-2.0, 2.0, -8.5),
|
||||
lateral: ("npc.bat.male.leg_r"),
|
||||
)
|
||||
),
|
||||
})
|
@ -635,7 +635,7 @@
|
||||
color: None
|
||||
),
|
||||
(Orc, Female, "common.items.armor.misc.head.helmet"): (
|
||||
vox_spec: ("armor.misc.head.helmet", (-3.0, -3.0, -1.0)),
|
||||
vox_spec: ("armor.misc.head.helmet", (-3.0, -6.0, -1.0)),
|
||||
color: None
|
||||
),
|
||||
(Orc, Male, "common.items.armor.misc.head.helmet"): (
|
||||
@ -960,6 +960,55 @@
|
||||
vox_spec: ("armor.misc.head.spikeguard", (-3.0, -5.0, 7.0)),
|
||||
color: None
|
||||
),
|
||||
//
|
||||
(Human, Female, "common.items.armor.misc.head.facegourd"): (
|
||||
vox_spec: ("armor.misc.head.facegourd", (-4.0, -5.0, -1.0)),
|
||||
color: None
|
||||
),
|
||||
(Human, Male, "common.items.armor.misc.head.facegourd"): (
|
||||
vox_spec: ("armor.misc.head.facegourd", (-4.0, -5.0, -1.0)),
|
||||
color: None
|
||||
),
|
||||
(Elf, Female, "common.items.armor.misc.head.facegourd"): (
|
||||
vox_spec: ("armor.misc.head.facegourd", (-3.0, -5.0, -1.0)),
|
||||
color: None
|
||||
),
|
||||
(Elf, Male, "common.items.armor.misc.head.facegourd"): (
|
||||
vox_spec: ("armor.misc.head.facegourd", (-3.0, -5.0, -1.0)),
|
||||
color: None
|
||||
),
|
||||
(Orc, Female, "common.items.armor.misc.head.facegourd"): (
|
||||
vox_spec: ("armor.misc.head.facegourd", (-3.0, -6.0, -1.0)),
|
||||
color: None
|
||||
),
|
||||
(Orc, Male, "common.items.armor.misc.head.facegourd"): (
|
||||
vox_spec: ("armor.misc.head.facegourd", (-3.0, -6.0, 2.0)),
|
||||
color: None
|
||||
),
|
||||
(Dwarf, Female, "common.items.armor.misc.head.facegourd"): (
|
||||
vox_spec: ("armor.misc.head.facegourd", (-5.0, -4.0, -1.0)),
|
||||
color: None
|
||||
),
|
||||
(Dwarf, Male, "common.items.armor.misc.head.facegourd"): (
|
||||
vox_spec: ("armor.misc.head.facegourd", (-3.0, -3.0, -1.0)),
|
||||
color: None
|
||||
),
|
||||
(Draugr, Female, "common.items.armor.misc.head.facegourd"): (
|
||||
vox_spec: ("armor.misc.head.facegourd", (-6.0, -5.0, -1.0)),
|
||||
color: None
|
||||
),
|
||||
(Draugr, Male, "common.items.armor.misc.head.facegourd"): (
|
||||
vox_spec: ("armor.misc.head.facegourd", (-6.0, -5.0, 1.0)),
|
||||
color: None
|
||||
),
|
||||
(Danari, Female, "common.items.armor.misc.head.facegourd"): (
|
||||
vox_spec: ("armor.misc.head.facegourd", (-2.0, -5.0, 1.0)),
|
||||
color: None
|
||||
),
|
||||
(Danari, Male, "common.items.armor.misc.head.facegourd"): (
|
||||
vox_spec: ("armor.misc.head.facegourd", (-2.0, -5.0, -1.0)),
|
||||
color: None
|
||||
),
|
||||
// Merchant Turban
|
||||
(Human, Male, "common.items.armor.merchant.turban"): (
|
||||
vox_spec: ("armor.merchant.turban", (-4.0, -7.0, -6.0)),
|
||||
|
@ -720,6 +720,7 @@
|
||||
Simple("common.items.armor.misc.head.crown"): "voxel.armor.misc.head.crown",
|
||||
Simple("common.items.armor.misc.head.mitre"): "voxel.armor.misc.head.mitre",
|
||||
Simple("common.items.armor.misc.head.spikeguard"): "voxel.armor.misc.head.spikeguard",
|
||||
Simple("common.items.armor.misc.head.facegourd"): "voxel.armor.misc.head.facegourd",
|
||||
Simple("common.items.armor.misc.head.winged_coronet"): "voxel.armor.misc.head.winged_coronet",
|
||||
Simple("common.items.armor.misc.head.boreal_warhelm"): "voxel.armor.misc.head.boreal_warhelm",
|
||||
Simple("common.items.calendar.christmas.armor.misc.head.woolly_wintercap"): "voxel.armor.misc.head.woolly_wintercap",
|
||||
@ -793,6 +794,8 @@
|
||||
Simple("common.items.food.apple_stick"): "voxel.object.apple_stick",
|
||||
Simple("common.items.food.mushroom_stick"): "voxel.object.mushroom_stick",
|
||||
Simple("common.items.food.sunflower_icetea"): "voxel.object.sunflower_ice_tea",
|
||||
Simple("common.items.food.pumpkin_spice_brew"): "voxel.object.pumpkin_spice_brew",
|
||||
Simple("common.items.food.honeycorn"): "voxel.object.honeycorn",
|
||||
Simple("common.items.food.carrot"): "voxel.sprite.carrot.carrot",
|
||||
Simple("common.items.food.tomato"): "voxel.sprite.tomato.tomato",
|
||||
Simple("common.items.food.lettuce"): "voxel.sprite.cabbage.cabbage",
|
||||
|
BIN
assets/voxygen/voxel/npc/bat/male/head.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/bat/male/head.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/bat/male/leg_r.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/bat/male/leg_r.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/bat/male/tail.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/bat/male/tail.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/bat/male/torso.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/bat/male/torso.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/bat/male/wing_r.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/bat/male/wing_r.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/object/honeycorn.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/object/honeycorn.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/object/pumpkin_spice_brew.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/object/pumpkin_spice_brew.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,17 @@
|
||||
SpawnEntry (
|
||||
name: "Halloween Jungle Area",
|
||||
note: "Halloween NPCs",
|
||||
rules: [
|
||||
Pack(
|
||||
groups: [
|
||||
(1, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_harvester")),
|
||||
(2, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_dullahan")),
|
||||
(3, (4, 8, "common.entity.wild.aggressive.bat")),
|
||||
(3, (3, 6, "common.entity.calendar.halloween.aggressive.trickster")),
|
||||
],
|
||||
spawn_mode: Land,
|
||||
calendar_events: Some([Halloween]),
|
||||
day_period: [Night, Morning, Noon, Evening],
|
||||
),
|
||||
],
|
||||
)
|
@ -0,0 +1,17 @@
|
||||
SpawnEntry (
|
||||
name: "Halloween Taiga Core",
|
||||
note: "Halloween NPCs",
|
||||
rules: [
|
||||
Pack(
|
||||
groups: [
|
||||
(1, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_harvester")),
|
||||
(2, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_dullahan")),
|
||||
(3, (4, 8, "common.entity.wild.aggressive.bat")),
|
||||
(3, (3, 6, "common.entity.calendar.halloween.aggressive.trickster")),
|
||||
],
|
||||
spawn_mode: Land,
|
||||
calendar_events: Some([Halloween]),
|
||||
day_period: [Night, Morning, Noon, Evening],
|
||||
),
|
||||
],
|
||||
)
|
@ -0,0 +1,17 @@
|
||||
SpawnEntry (
|
||||
name: "Halloween Temperate Rainforest",
|
||||
note: "Halloween NPCs",
|
||||
rules: [
|
||||
Pack(
|
||||
groups: [
|
||||
(1, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_harvester")),
|
||||
(2, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_dullahan")),
|
||||
(3, (4, 8, "common.entity.wild.aggressive.bat")),
|
||||
(3, (3, 6, "common.entity.calendar.halloween.aggressive.trickster")),
|
||||
],
|
||||
spawn_mode: Land,
|
||||
calendar_events: Some([Halloween]),
|
||||
day_period: [Night, Morning, Noon, Evening],
|
||||
),
|
||||
],
|
||||
)
|
@ -0,0 +1,17 @@
|
||||
SpawnEntry (
|
||||
name: "Halloween Tropical Rainforest",
|
||||
note: "Halloween NPCs",
|
||||
rules: [
|
||||
Pack(
|
||||
groups: [
|
||||
(1, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_harvester")),
|
||||
(2, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_dullahan")),
|
||||
(3, (4, 8, "common.entity.wild.aggressive.bat")),
|
||||
(3, (3, 6, "common.entity.calendar.halloween.aggressive.trickster")),
|
||||
],
|
||||
spawn_mode: Land,
|
||||
calendar_events: Some([Halloween]),
|
||||
day_period: [Night, Morning, Noon, Evening],
|
||||
),
|
||||
],
|
||||
)
|
@ -0,0 +1,17 @@
|
||||
SpawnEntry (
|
||||
name: "Halloween Tundra Core",
|
||||
note: "Halloween NPCs",
|
||||
rules: [
|
||||
Pack(
|
||||
groups: [
|
||||
(1, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_harvester")),
|
||||
(2, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_dullahan")),
|
||||
(3, (4, 8, "common.entity.wild.aggressive.bat")),
|
||||
(3, (3, 6, "common.entity.calendar.halloween.aggressive.trickster")),
|
||||
],
|
||||
spawn_mode: Land,
|
||||
calendar_events: Some([Halloween]),
|
||||
day_period: [Night, Morning, Noon, Evening],
|
||||
),
|
||||
],
|
||||
)
|
@ -0,0 +1,17 @@
|
||||
SpawnEntry (
|
||||
name: "Halloween Tundra Forest",
|
||||
note: "Halloween NPCs",
|
||||
rules: [
|
||||
Pack(
|
||||
groups: [
|
||||
(1, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_harvester")),
|
||||
(2, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_dullahan")),
|
||||
(3, (4, 8, "common.entity.wild.aggressive.bat")),
|
||||
(3, (3, 6, "common.entity.calendar.halloween.aggressive.trickster")),
|
||||
],
|
||||
spawn_mode: Land,
|
||||
calendar_events: Some([Halloween]),
|
||||
day_period: [Night, Morning, Noon, Evening],
|
||||
),
|
||||
],
|
||||
)
|
@ -0,0 +1,17 @@
|
||||
SpawnEntry (
|
||||
name: "Halloween Tundra Snow",
|
||||
note: "Halloween NPCs",
|
||||
rules: [
|
||||
Pack(
|
||||
groups: [
|
||||
(1, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_harvester")),
|
||||
(2, (1, 1, "common.entity.calendar.halloween.aggressive.halloween_dullahan")),
|
||||
(3, (4, 8, "common.entity.wild.aggressive.bat")),
|
||||
(3, (3, 6, "common.entity.calendar.halloween.aggressive.trickster")),
|
||||
],
|
||||
spawn_mode: Land,
|
||||
calendar_events: Some([Halloween]),
|
||||
day_period: [Night, Morning, Noon, Evening],
|
||||
),
|
||||
],
|
||||
)
|
@ -20,6 +20,7 @@ SpawnEntry (
|
||||
(1, (1, 1, "common.entity.wild.peaceful.holladon")),
|
||||
(1, (1, 1, "common.entity.wild.peaceful.porcupine")),
|
||||
(1, (1, 1, "common.entity.wild.peaceful.pangolin")),
|
||||
(1, (4, 8, "common.entity.wild.aggressive.bat")),
|
||||
],
|
||||
spawn_mode: Land,
|
||||
day_period: [Night],
|
||||
|
@ -22,6 +22,7 @@ SpawnEntry (
|
||||
groups: [
|
||||
(5, (1, 1, "common.entity.wild.peaceful.quokka")),
|
||||
(1, (1, 1, "common.entity.wild.peaceful.tortoise")),
|
||||
(5, (4, 8, "common.entity.wild.aggressive.bat")),
|
||||
],
|
||||
spawn_mode: Land,
|
||||
day_period: [Night],
|
||||
|
@ -45,6 +45,7 @@ SpawnEntry (
|
||||
// Pack
|
||||
(5, (1, 3, "common.entity.wild.peaceful.rat")),
|
||||
(5, (1, 3, "common.entity.wild.peaceful.squirrel")),
|
||||
(10, (4, 8, "common.entity.wild.aggressive.bat")),
|
||||
],
|
||||
spawn_mode: Land,
|
||||
day_period: [Night],
|
||||
|
@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize};
|
||||
#[repr(u16)]
|
||||
pub enum CalendarEvent {
|
||||
Christmas = 0,
|
||||
Halloween = 1,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@ -37,6 +38,10 @@ impl Calendar {
|
||||
this.events.push(CalendarEvent::Christmas);
|
||||
}
|
||||
|
||||
if now.month() == 10 && (24..=31).contains(&now.day()) {
|
||||
this.events.push(CalendarEvent::Halloween);
|
||||
}
|
||||
|
||||
this
|
||||
}
|
||||
}
|
||||
|
@ -310,6 +310,7 @@ impl<'a> From<&'a Body> for Psyche {
|
||||
bird_medium::Species::Peacock => 0.4,
|
||||
bird_medium::Species::Eagle => 0.3,
|
||||
bird_medium::Species::Parrot => 0.8,
|
||||
bird_medium::Species::Bat => 0.0,
|
||||
_ => 0.5,
|
||||
},
|
||||
Body::BirdLarge(_) => 0.1,
|
||||
|
@ -27,7 +27,7 @@ use specs::{Component, DerefFlaggedStorage};
|
||||
use strum::Display;
|
||||
use vek::*;
|
||||
|
||||
use super::{BuffKind, Collider, Density, Mass};
|
||||
use super::{BuffKind, Collider, Density, Mass, Scale};
|
||||
|
||||
make_case_elim!(
|
||||
body,
|
||||
@ -231,6 +231,17 @@ impl Body {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn scale(&self) -> Scale {
|
||||
let s = match self {
|
||||
Body::BirdMedium(bird_medium) => match bird_medium.species {
|
||||
bird_medium::Species::Bat => 0.5,
|
||||
_ => 1.0,
|
||||
},
|
||||
_ => 1.0,
|
||||
};
|
||||
Scale(s)
|
||||
}
|
||||
|
||||
/// Average density of the body
|
||||
// Units are based on kg/m³
|
||||
pub fn density(&self) -> Density {
|
||||
@ -280,6 +291,7 @@ impl Body {
|
||||
bird_medium::Species::Parrot => 2.0,
|
||||
bird_medium::Species::Penguin => 8.0,
|
||||
bird_medium::Species::Peacock => 5.0,
|
||||
bird_medium::Species::Bat => 2.0,
|
||||
},
|
||||
Body::BirdLarge(_) => 100.0,
|
||||
|
||||
@ -412,6 +424,7 @@ impl Body {
|
||||
bird_medium::Species::Duck => Vec3::new(0.9, 1.0, 1.4),
|
||||
bird_medium::Species::Goose => Vec3::new(1.0, 1.2, 1.5),
|
||||
bird_medium::Species::Peacock => Vec3::new(1.3, 1.1, 1.4),
|
||||
bird_medium::Species::Bat => Vec3::new(2.0, 2.0, 1.5),
|
||||
_ => Vec3::new(2.0, 1.0, 1.5),
|
||||
},
|
||||
Body::BirdLarge(body) => match body.species {
|
||||
@ -702,6 +715,7 @@ impl Body {
|
||||
bird_medium::Species::Eagle => 45,
|
||||
bird_medium::Species::Owl => 45,
|
||||
bird_medium::Species::Duck => 10,
|
||||
bird_medium::Species::Bat => 20,
|
||||
_ => 15,
|
||||
},
|
||||
Body::FishMedium(_) => 15,
|
||||
|
@ -45,6 +45,7 @@ make_case_elim!(
|
||||
Owl = 5,
|
||||
Parrot = 6,
|
||||
Penguin = 7,
|
||||
Bat = 8,
|
||||
}
|
||||
);
|
||||
|
||||
@ -61,6 +62,7 @@ pub struct AllSpecies<SpeciesMeta> {
|
||||
pub owl: SpeciesMeta,
|
||||
pub parrot: SpeciesMeta,
|
||||
pub penguin: SpeciesMeta,
|
||||
pub bat: SpeciesMeta,
|
||||
}
|
||||
|
||||
impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta> {
|
||||
@ -77,11 +79,12 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta>
|
||||
Species::Owl => &self.owl,
|
||||
Species::Parrot => &self.parrot,
|
||||
Species::Penguin => &self.penguin,
|
||||
Species::Bat => &self.bat,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const ALL_SPECIES: [Species; 8] = [
|
||||
pub const ALL_SPECIES: [Species; 9] = [
|
||||
Species::Duck,
|
||||
Species::Chicken,
|
||||
Species::Goose,
|
||||
@ -90,6 +93,7 @@ pub const ALL_SPECIES: [Species; 8] = [
|
||||
Species::Owl,
|
||||
Species::Parrot,
|
||||
Species::Penguin,
|
||||
Species::Bat,
|
||||
];
|
||||
|
||||
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
assets::{self, AssetExt},
|
||||
comp::{
|
||||
arthropod, biped_large, biped_small, bird_large, golem,
|
||||
arthropod, biped_large, biped_small, bird_large, bird_medium, golem,
|
||||
inventory::{
|
||||
loadout::Loadout,
|
||||
slot::{ArmorSlot, EquipSlot},
|
||||
@ -778,6 +778,12 @@ fn default_main_tool(body: &Body) -> Item {
|
||||
"common.items.npc_weapons.unique.birdlargebasic",
|
||||
)),
|
||||
},
|
||||
Body::BirdMedium(bird_medium) => match bird_medium.species {
|
||||
bird_medium::Species::Bat => Some(Item::new_from_asset_expect(
|
||||
"common.items.npc_weapons.unique.simpleflyingbasic",
|
||||
)),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
|
||||
|
@ -325,6 +325,43 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Bats should fly
|
||||
// Use a proportional controller as the bouncing effect mimics bat flight
|
||||
if self.traversal_config.can_fly
|
||||
&& self
|
||||
.inventory
|
||||
.equipped(EquipSlot::ActiveMainhand)
|
||||
.as_ref()
|
||||
.map_or(false, |item| {
|
||||
item.ability_spec().map_or(false, |a_s| match &*a_s {
|
||||
AbilitySpec::Custom(spec) => {
|
||||
matches!(spec.as_str(), "Simple Flying Melee")
|
||||
},
|
||||
_ => false,
|
||||
})
|
||||
})
|
||||
{
|
||||
// Bats don't like the ground, so make sure they are always flying
|
||||
controller.push_basic_input(InputKind::Fly);
|
||||
if read_data
|
||||
.terrain
|
||||
.ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * 5.0))
|
||||
.until(Block::is_solid)
|
||||
.cast()
|
||||
.1
|
||||
.map_or(true, |b| b.is_some())
|
||||
{
|
||||
// Fly up
|
||||
controller.inputs.move_z = 1.0;
|
||||
// If on the ground, jump
|
||||
if self.physics_state.on_ground.is_some() {
|
||||
controller.push_basic_input(InputKind::Jump);
|
||||
}
|
||||
} else {
|
||||
// Fly down
|
||||
controller.inputs.move_z = -1.0;
|
||||
}
|
||||
}
|
||||
agent.bearing += Vec2::new(rng.gen::<f32>() - 0.5, rng.gen::<f32>() - 0.5) * 0.1
|
||||
- agent.bearing * 0.003
|
||||
- agent.patrol_origin.map_or(Vec2::zero(), |patrol_origin| {
|
||||
@ -774,6 +811,7 @@ impl<'a> AgentData<'a> {
|
||||
AbilitySpec::Custom(spec) => match spec.as_str() {
|
||||
"Oni" | "Sword Simple" => Tactic::Sword,
|
||||
"Staff Simple" => Tactic::Staff,
|
||||
"Simple Flying Melee" => Tactic::SimpleFlyingMelee,
|
||||
"Bow Simple" => Tactic::Bow,
|
||||
"Stone Golem" => Tactic::StoneGolem,
|
||||
"Quad Med Quick" => Tactic::CircleCharge {
|
||||
@ -1006,6 +1044,14 @@ impl<'a> AgentData<'a> {
|
||||
// Match on tactic. Each tactic has different controls depending on the distance
|
||||
// from the agent to the target.
|
||||
match tactic {
|
||||
Tactic::SimpleFlyingMelee => self.handle_simple_flying_melee(
|
||||
agent,
|
||||
controller,
|
||||
&attack_data,
|
||||
tgt_data,
|
||||
read_data,
|
||||
rng,
|
||||
),
|
||||
Tactic::SimpleMelee => {
|
||||
self.handle_simple_melee(agent, controller, &attack_data, tgt_data, read_data, rng)
|
||||
},
|
||||
|
@ -53,6 +53,64 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
// Intended for any agent that has one attack, that attack is a melee attack,
|
||||
// and the agent is able to freely fly around
|
||||
pub fn handle_simple_flying_melee(
|
||||
&self,
|
||||
_agent: &mut Agent,
|
||||
controller: &mut Controller,
|
||||
attack_data: &AttackData,
|
||||
tgt_data: &TargetData,
|
||||
read_data: &ReadData,
|
||||
_rng: &mut impl Rng,
|
||||
) {
|
||||
// Fly to target
|
||||
let dir_to_target = ((tgt_data.pos.0 + Vec3::unit_z() * 1.5) - self.pos.0)
|
||||
.try_normalized()
|
||||
.unwrap_or_else(Vec3::zero);
|
||||
let speed = 1.0;
|
||||
controller.inputs.move_dir = dir_to_target.xy() * speed;
|
||||
|
||||
// Always fly! If the floor can't touch you, it can't hurt you...
|
||||
controller.push_basic_input(InputKind::Fly);
|
||||
// Flee from the ground! The internet told me it was lava!
|
||||
// If on the ground, jump with every last ounce of energy, holding onto all that
|
||||
// is dear in life and straining for the wide open skies.
|
||||
if self.physics_state.on_ground.is_some() {
|
||||
controller.push_basic_input(InputKind::Jump);
|
||||
} else {
|
||||
// Only fly down if close enough to target in the xy plane
|
||||
// Otherwise fly towards the target bouncing around a 5 block altitude
|
||||
let mut maintain_altitude = |altitude| {
|
||||
if read_data
|
||||
.terrain
|
||||
.ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * altitude))
|
||||
.until(Block::is_solid)
|
||||
.cast()
|
||||
.1
|
||||
.map_or(true, |b| b.is_some())
|
||||
{
|
||||
// Fly up
|
||||
controller.inputs.move_z = 1.0;
|
||||
} else {
|
||||
// Fly down
|
||||
controller.inputs.move_z = -1.0;
|
||||
}
|
||||
};
|
||||
if (tgt_data.pos.0 - self.pos.0).xy().magnitude_squared() > (5.0_f32).powi(2) {
|
||||
// If above 5 blocks, fly down
|
||||
maintain_altitude(5.0);
|
||||
} else {
|
||||
maintain_altitude(2.0);
|
||||
|
||||
// Attack if in range
|
||||
if attack_data.dist_sqrd < 3.5_f32.powi(2) && attack_data.angle < 150.0 {
|
||||
controller.push_basic_input(InputKind::Primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Intended for any agent that has one attack, that attack is a melee attack,
|
||||
// the agent is able to freely walk around, and the agent is trying to attack
|
||||
// from behind its target
|
||||
|
@ -74,6 +74,7 @@ impl AttackData {
|
||||
pub enum Tactic {
|
||||
// General tactics
|
||||
SimpleMelee,
|
||||
SimpleFlyingMelee,
|
||||
SimpleBackstab,
|
||||
ElevatedRanged,
|
||||
Turret,
|
||||
|
@ -1212,6 +1212,7 @@ fn handle_spawn(
|
||||
body,
|
||||
)
|
||||
.with(comp::Vel(vel))
|
||||
.with(body.scale())
|
||||
.with(alignment);
|
||||
|
||||
if ai {
|
||||
|
@ -114,6 +114,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
(Owl, Female) => (2.5, 7.0),
|
||||
(Parrot, _) => (0.5, 4.5),
|
||||
(Penguin, _) => (1.5, 6.0),
|
||||
(Bat, _) => (2.5, 5.0),
|
||||
},
|
||||
chest: match (body.species, body.body_type) {
|
||||
(Duck, _) => (0.0, 6.0),
|
||||
@ -126,6 +127,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
(Owl, Female) => (0.0, 4.5),
|
||||
(Parrot, _) => (0.0, 5.0),
|
||||
(Penguin, _) => (0.0, 8.0),
|
||||
(Bat, _) => (0.0, 8.0),
|
||||
},
|
||||
tail: match (body.species, body.body_type) {
|
||||
(Duck, _) => (-5.0, 1.0),
|
||||
@ -138,6 +140,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
(Owl, Female) => (-6.0, -2.5),
|
||||
(Parrot, _) => (-8.0, -2.0),
|
||||
(Penguin, _) => (-3.0, -4.0),
|
||||
(Bat, _) => (-8.0, -4.0),
|
||||
},
|
||||
wing: match (body.species, body.body_type) {
|
||||
(Duck, _) => (3.5, -0.5, 2.0),
|
||||
@ -150,6 +153,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
(Owl, Female) => (3.5, -6.0, 3.5),
|
||||
(Parrot, _) => (2.0, -4.5, 3.0),
|
||||
(Penguin, _) => (4.0, 0.5, 1.0),
|
||||
(Bat, _) => (3.0, -8.0, -1.0),
|
||||
},
|
||||
foot: match (body.species, body.body_type) {
|
||||
(Duck, _) => (2.5, -2.0, 4.0),
|
||||
@ -162,6 +166,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
(Owl, Female) => (1.5, -3.0, 6.5),
|
||||
(Parrot, _) => (1.5, -3.0, 3.0),
|
||||
(Penguin, _) => (2.5, -2.0, 6.0),
|
||||
(Bat, _) => (5.0, -1.0, 8.0),
|
||||
},
|
||||
feed: match (body.species, body.body_type) {
|
||||
(Chicken, _) => 1.2,
|
||||
|
@ -265,6 +265,19 @@ pub fn block_from_structure(
|
||||
&& field.chance(pos + structure_pos, 0.025)
|
||||
{
|
||||
Block::new(BlockKind::GlowingWeakRock, Rgb::new(255, 0, 0))
|
||||
} else if calendar.map_or(false, |c| c.is_event(CalendarEvent::Halloween))
|
||||
&& sblock != StructureBlock::PineLeaves
|
||||
{
|
||||
let (c0, c1) = match structure_seed % 6 {
|
||||
0 => (Rgb::new(165.0, 150.0, 11.0), Rgb::new(170.0, 165.0, 16.0)),
|
||||
1 | 2 => (Rgb::new(218.0, 53.0, 3.0), Rgb::new(226.0, 62.0, 5.0)),
|
||||
_ => (Rgb::new(230.0, 120.0, 20.0), Rgb::new(242.0, 130.0, 25.0)),
|
||||
};
|
||||
|
||||
Block::new(
|
||||
BlockKind::Leaves,
|
||||
Rgb::<f32>::lerp(c0, c1, lerp).map(|e| e as u8),
|
||||
)
|
||||
} else {
|
||||
Block::new(
|
||||
BlockKind::Leaves,
|
||||
|
@ -828,6 +828,10 @@ fn apply_entity_spawns<R: Rng>(canvas: &mut Canvas, wpos: Vec3<i32>, biome: &Bio
|
||||
Some("common.entity.wild.peaceful.fungome"),
|
||||
(biome.mushroom + 0.02) * 0.5,
|
||||
),
|
||||
(
|
||||
Some("common.entity.wild.aggressive.bat"),
|
||||
(biome.mushroom + 0.1) * 0.5,
|
||||
),
|
||||
// Leafy biome
|
||||
(
|
||||
Some("common.entity.wild.peaceful.holladon"),
|
||||
@ -869,6 +873,10 @@ fn apply_entity_spawns<R: Rng>(canvas: &mut Canvas, wpos: Vec3<i32>, biome: &Bio
|
||||
Some("common.entity.wild.aggressive.swamp_troll"),
|
||||
(biome.leafy + 0.0) * 0.1,
|
||||
),
|
||||
(
|
||||
Some("common.entity.wild.aggressive.bat"),
|
||||
(biome.leafy + 0.1) * 0.5,
|
||||
),
|
||||
// Dusty biome
|
||||
(
|
||||
Some("common.entity.wild.aggressive.dodarock"),
|
||||
@ -890,6 +898,10 @@ fn apply_entity_spawns<R: Rng>(canvas: &mut Canvas, wpos: Vec3<i32>, biome: &Bio
|
||||
Some("common.entity.wild.peaceful.rat"),
|
||||
(biome.dusty + 0.1) * 0.3,
|
||||
),
|
||||
(
|
||||
Some("common.entity.wild.aggressive.bat"),
|
||||
(biome.dusty + 0.1) * 0.5,
|
||||
),
|
||||
// Icy biome
|
||||
(
|
||||
Some("common.entity.wild.aggressive.blue_oni"),
|
||||
|
@ -1,5 +1,8 @@
|
||||
use crate::{column::ColumnSample, sim::SimChunk, Canvas, CONFIG};
|
||||
use common::terrain::{Block, BlockKind, SpriteKind};
|
||||
use common::{
|
||||
calendar::{Calendar, CalendarEvent},
|
||||
terrain::{Block, BlockKind, SpriteKind},
|
||||
};
|
||||
use noise::NoiseFn;
|
||||
use num::traits::Pow;
|
||||
use rand::prelude::*;
|
||||
@ -27,7 +30,7 @@ pub fn density_factor_by_altitude(lower_limit: f32, altitude: f32, upper_limit:
|
||||
const MUSH_FACT: f32 = 1.0e-4; // To balance things around the mushroom spawning rate
|
||||
const GRASS_FACT: f32 = 1.0e-3; // To balance things around the grass spawning rate
|
||||
const DEPTH_WATER_NORM: f32 = 15.0; // Water depth at which regular underwater sprites start spawning
|
||||
pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
|
||||
pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng, calendar: Option<&Calendar>) {
|
||||
enum WaterMode {
|
||||
Underwater,
|
||||
Floating,
|
||||
@ -283,16 +286,22 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) {
|
||||
kind: Pumpkin,
|
||||
water_mode: Ground,
|
||||
permit: |b| matches!(b, BlockKind::Grass),
|
||||
f: |_, col| {
|
||||
(
|
||||
close(col.temp, CONFIG.temperate_temp, 0.5).min(close(
|
||||
col.humidity,
|
||||
CONFIG.forest_hum,
|
||||
0.5,
|
||||
)) * MUSH_FACT
|
||||
* 500.0,
|
||||
Some((0.0, 512.0, 0.05)),
|
||||
)
|
||||
f: if calendar.map_or(false, |calendar| {
|
||||
calendar.is_event(CalendarEvent::Halloween)
|
||||
}) {
|
||||
|_, _| (0.1, Some((0.0003, 128.0, 0.1)))
|
||||
} else {
|
||||
|_, col| {
|
||||
(
|
||||
close(col.temp, CONFIG.temperate_temp, 0.5).min(close(
|
||||
col.humidity,
|
||||
CONFIG.forest_hum,
|
||||
0.5,
|
||||
)) * MUSH_FACT
|
||||
* 500.0,
|
||||
Some((0.0, 512.0, 0.05)),
|
||||
)
|
||||
}
|
||||
},
|
||||
},
|
||||
// Collectable Objects
|
||||
|
@ -167,6 +167,10 @@ pub fn spawn_manifest() -> Vec<(&'static str, DensityFn)> {
|
||||
"world.wildlife.spawn.calendar.christmas.tundra.core",
|
||||
|c, _col| close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.5,
|
||||
),
|
||||
(
|
||||
"world.wildlife.spawn.calendar.halloween.tundra.core",
|
||||
|c, _col| close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.5,
|
||||
),
|
||||
// Snowy animals
|
||||
("world.wildlife.spawn.tundra.snow", |c, col| {
|
||||
close(c.temp, CONFIG.snow_temp, 0.3) * BASE_DENSITY * col.snow_cover as i32 as f32 * 1.0
|
||||
@ -181,6 +185,15 @@ pub fn spawn_manifest() -> Vec<(&'static str, DensityFn)> {
|
||||
* 1.0
|
||||
},
|
||||
),
|
||||
(
|
||||
"world.wildlife.spawn.calendar.halloween.tundra.snow",
|
||||
|c, col| {
|
||||
close(c.temp, CONFIG.snow_temp, 0.3)
|
||||
* BASE_DENSITY
|
||||
* col.snow_cover as i32 as f32
|
||||
* 1.0
|
||||
},
|
||||
),
|
||||
// Forest animals
|
||||
("world.wildlife.spawn.tundra.forest", |c, col| {
|
||||
close(c.temp, CONFIG.snow_temp, 0.3) * col.tree_density * BASE_DENSITY * 1.4
|
||||
@ -190,6 +203,10 @@ pub fn spawn_manifest() -> Vec<(&'static str, DensityFn)> {
|
||||
"world.wildlife.spawn.calendar.christmas.tundra.forest",
|
||||
|c, col| close(c.temp, CONFIG.snow_temp, 0.3) * col.tree_density * BASE_DENSITY * 1.4,
|
||||
),
|
||||
(
|
||||
"world.wildlife.spawn.calendar.halloween.tundra.forest",
|
||||
|c, col| close(c.temp, CONFIG.snow_temp, 0.3) * col.tree_density * BASE_DENSITY * 1.4,
|
||||
),
|
||||
// **Taiga**
|
||||
// Forest core animals
|
||||
("world.wildlife.spawn.taiga.core_forest", |c, col| {
|
||||
@ -202,6 +219,12 @@ pub fn spawn_manifest() -> Vec<(&'static str, DensityFn)> {
|
||||
close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * col.tree_density * BASE_DENSITY * 0.4
|
||||
},
|
||||
),
|
||||
(
|
||||
"world.wildlife.spawn.calendar.halloween.taiga.core",
|
||||
|c, col| {
|
||||
close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * col.tree_density * BASE_DENSITY * 0.4
|
||||
},
|
||||
),
|
||||
// Core animals
|
||||
("world.wildlife.spawn.taiga.core", |c, _col| {
|
||||
close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * BASE_DENSITY * 1.0
|
||||
@ -243,6 +266,16 @@ pub fn spawn_manifest() -> Vec<(&'static str, DensityFn)> {
|
||||
* BASE_DENSITY
|
||||
* 4.0
|
||||
}),
|
||||
// Temperate Rainforest animals event
|
||||
(
|
||||
"world.wildlife.spawn.calendar.halloween.temperate.rainforest",
|
||||
|c, _col| {
|
||||
close(c.temp, CONFIG.temperate_temp + 0.1, 0.6)
|
||||
* close(c.humidity, CONFIG.forest_hum, 0.6)
|
||||
* BASE_DENSITY
|
||||
* 4.0
|
||||
},
|
||||
),
|
||||
// Water animals
|
||||
("world.wildlife.spawn.temperate.water", |c, col| {
|
||||
close(c.temp, CONFIG.temperate_temp, 1.0) * col.tree_density * BASE_DENSITY * 5.0
|
||||
@ -262,6 +295,16 @@ pub fn spawn_manifest() -> Vec<(&'static str, DensityFn)> {
|
||||
* BASE_DENSITY
|
||||
* 8.0
|
||||
}),
|
||||
// Jungle animals event
|
||||
(
|
||||
"world.wildlife.spawn.calendar.halloween.jungle.area",
|
||||
|c, _col| {
|
||||
close(c.temp, CONFIG.tropical_temp + 0.2, 0.3)
|
||||
* close(c.humidity, CONFIG.jungle_hum, 0.2)
|
||||
* BASE_DENSITY
|
||||
* 8.0
|
||||
},
|
||||
),
|
||||
// **Tropical**
|
||||
// Rare river animals
|
||||
("world.wildlife.spawn.tropical.river_rare", |_c, col| {
|
||||
@ -308,6 +351,16 @@ pub fn spawn_manifest() -> Vec<(&'static str, DensityFn)> {
|
||||
* BASE_DENSITY
|
||||
* 2.0
|
||||
}),
|
||||
// Tropical Rainforest animals event
|
||||
(
|
||||
"world.wildlife.spawn.calendar.halloween.tropical.rainforest",
|
||||
|c, _col| {
|
||||
close(c.temp, CONFIG.tropical_temp + 0.1, 0.4)
|
||||
* close(c.humidity, CONFIG.desert_hum, 0.4)
|
||||
* BASE_DENSITY
|
||||
* 2.0
|
||||
},
|
||||
),
|
||||
// Rock animals
|
||||
("world.wildlife.spawn.tropical.rock", |c, col| {
|
||||
close(c.temp, CONFIG.tropical_temp + 0.1, 0.5) * col.rock_density * BASE_DENSITY * 5.0
|
||||
|
@ -375,7 +375,7 @@ impl World {
|
||||
layer::apply_trees_to(&mut canvas, &mut dynamic_rng, calendar);
|
||||
}
|
||||
if index.features.scatter {
|
||||
layer::apply_scatter_to(&mut canvas, &mut dynamic_rng);
|
||||
layer::apply_scatter_to(&mut canvas, &mut dynamic_rng, calendar);
|
||||
}
|
||||
if index.features.paths {
|
||||
layer::apply_paths_to(&mut canvas);
|
||||
|
Loading…
Reference in New Issue
Block a user