Merge branch 'master' of gitlab.com:veloren/veloren into sharp/small-fixes

This commit is contained in:
Joshua Yanovski 2020-08-12 20:19:04 +02:00
commit f51dfdeb44
58 changed files with 490 additions and 104 deletions

View File

@ -52,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add detection of entities under the cursor - Add detection of entities under the cursor
- Functional group-system with exp-sharing and disabled damage to group members - Functional group-system with exp-sharing and disabled damage to group members
- Some Campfire, fireball & bomb; particle, light & sound effects. - Some Campfire, fireball & bomb; particle, light & sound effects.
- Added firework recipe
- Added setting to change resolution - Added setting to change resolution
### Changed ### Changed

View File

@ -0,0 +1,12 @@
Item(
name: "Purple Admin Cape",
description: "Where did I put my banhammer again?",
kind: Armor(
(
kind: Back("DungPurp0"),
stats: (
protection: Invincible,
),
)
),
)

View File

@ -0,0 +1,7 @@
Item(
name: "Firework Blue",
description: "Recommended clearance: 42 chonks\n\n<Right-Click to use>",
kind: Throwable(
kind: Firework(Blue),
),
)

View File

@ -0,0 +1,7 @@
Item(
name: "Firework Green",
description: "Watch out for trees.\n\n<Right-Click to use>",
kind: Throwable(
kind: Firework(Green),
),
)

View File

@ -0,0 +1,7 @@
Item(
name: "Firework Purple",
description: "Cult favourite.\n\n<Right-Click to use>",
kind: Throwable(
kind: Firework(Purple),
),
)

View File

@ -0,0 +1,7 @@
Item(
name: "Firework Red",
description: "Humans sometimes use these\nas a flare in a pinch.\n\n<Right-Click to use>",
kind: Throwable(
kind: Firework(Red),
),
)

View File

@ -0,0 +1,7 @@
Item(
name: "Firework Yellow",
description: "The Great Dr. passed away after\ntesting this contraption indoors.\n\n<Right-Click to use>",
kind: Throwable(
kind: Firework(Yellow),
),
)

View File

@ -0,0 +1,13 @@
Item(
name: "Magical Cultist Warhammer",
description: "This belonged to an evil Cult Leader.",
kind: Tool(
(
kind: Hammer("CultPurp0"),
stats: (
equip_time_millis: 500,
power: 2.00,
),
)
),
)

View File

@ -6,6 +6,11 @@
"potion_m": (("common.items.consumable.potion_med", 1), [("common.items.consumable.potion_minor", 2), ("common.items.ore.veloritefrag", 4)]), "potion_m": (("common.items.consumable.potion_med", 1), [("common.items.consumable.potion_minor", 2), ("common.items.ore.veloritefrag", 4)]),
"collar_basic": (("common.items.utility.collar", 1), [("common.items.crafting_ing.leather_scraps", 5), ("common.items.crafting_ing.shiny_gem", 1)]), "collar_basic": (("common.items.utility.collar", 1), [("common.items.crafting_ing.leather_scraps", 5), ("common.items.crafting_ing.shiny_gem", 1)]),
"bomb_coconut": (("common.items.utility.bomb", 1), [("common.items.crafting_ing.stones", 10), ("common.items.food.coconut", 2), ("common.items.ore.veloritefrag", 2), ("common.items.crafting_tools.mortar_pestle", 0)]), "bomb_coconut": (("common.items.utility.bomb", 1), [("common.items.crafting_ing.stones", 10), ("common.items.food.coconut", 2), ("common.items.ore.veloritefrag", 2), ("common.items.crafting_tools.mortar_pestle", 0)]),
"firework_blue": (("common.items.utility.firework_blue", 1), [("common.items.crafting_ing.twigs", 1), ("common.items.crafting_ing.stones", 1), ("common.items.food.coconut", 1), ("common.items.ore.veloritefrag", 1), ("common.items.crafting_tools.mortar_pestle", 0)]),
"firework_green": (("common.items.utility.firework_green", 1), [("common.items.crafting_ing.twigs", 1), ("common.items.crafting_ing.stones", 1), ("common.items.food.coconut", 1), ("common.items.ore.veloritefrag", 1), ("common.items.crafting_tools.mortar_pestle", 0)]),
"firework_purple": (("common.items.utility.firework_purple", 1), [("common.items.crafting_ing.twigs", 1), ("common.items.crafting_ing.stones", 1), ("common.items.food.coconut", 1), ("common.items.ore.veloritefrag", 1), ("common.items.crafting_tools.mortar_pestle", 0)]),
"firework_red": (("common.items.utility.firework_red", 1), [("common.items.crafting_ing.twigs", 1), ("common.items.crafting_ing.stones", 1), ("common.items.food.coconut", 1), ("common.items.ore.veloritefrag", 1), ("common.items.crafting_tools.mortar_pestle", 0)]),
"firework_yellow": (("common.items.utility.firework_yellow", 1), [("common.items.crafting_ing.twigs", 1), ("common.items.crafting_ing.stones", 1), ("common.items.food.coconut", 1), ("common.items.ore.veloritefrag", 1), ("common.items.crafting_tools.mortar_pestle", 0)]),
"apple_shroom_curry": (("common.items.food.apple_mushroom_curry", 1), [("common.items.food.mushroom", 10), ("common.items.food.coconut", 1), ("common.items.food.apple", 5), ("common.items.crafting_tools.mortar_pestle", 0)]), "apple_shroom_curry": (("common.items.food.apple_mushroom_curry", 1), [("common.items.food.mushroom", 10), ("common.items.food.coconut", 1), ("common.items.food.apple", 5), ("common.items.crafting_tools.mortar_pestle", 0)]),
"apples_stick": (("common.items.food.apple_stick", 1),[("common.items.crafting_ing.twigs", 1), ("common.items.food.apple", 3)]), "apples_stick": (("common.items.food.apple_stick", 1),[("common.items.crafting_ing.twigs", 1), ("common.items.food.apple", 3)]),
"mushroom_stick": (("common.items.food.mushroom_stick", 1),[("common.items.crafting_ing.twigs", 1), ("common.items.food.mushroom", 5)]), "mushroom_stick": (("common.items.food.mushroom_stick", 1),[("common.items.crafting_ing.twigs", 1), ("common.items.food.mushroom", 5)]),

View File

@ -10,6 +10,13 @@
timing: Some(Day), timing: Some(Day),
artist: "https://www.youtube.com/watch?v=FwVTkB-BIvM", artist: "https://www.youtube.com/watch?v=FwVTkB-BIvM",
), ),
(
title: "A Solemn Quest Day",
path: "voxygen.audio.ambient.a_solemn_quest",
length: 206.0,
timing: Some(Day),
artist: "Eden",
),
( (
title: "Into The Dark Forest", title: "Into The Dark Forest",
path: "voxygen.audio.soundtrack.into_the_dark_forest", path: "voxygen.audio.soundtrack.into_the_dark_forest",

BIN
assets/voxygen/audio/soundtrack/a_solemn_quest.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_9.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_main.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/element/help.png (Stored with Git LFS)

Binary file not shown.

View File

@ -393,7 +393,7 @@ magischen Gegenstände ergattern?"#,
"gameinput.wallleap": "Wandsprung", "gameinput.wallleap": "Wandsprung",
"gameinput.togglelantern": "Laterne ein-/ausschalten", "gameinput.togglelantern": "Laterne ein-/ausschalten",
"gameinput.mount": "Aufsteigen", "gameinput.mount": "Aufsteigen",
"gameinput.enter": "Betreten", "gameinput.chat": "Chat",
"gameinput.command": "Befehl", "gameinput.command": "Befehl",
"gameinput.escape": "Escape", "gameinput.escape": "Escape",
"gameinput.map": "Karte", "gameinput.map": "Karte",
@ -412,6 +412,10 @@ magischen Gegenstände ergattern?"#,
"gameinput.declinegroupinvite": "Ablehnen", "gameinput.declinegroupinvite": "Ablehnen",
"gameinput.acceptgroupinvite": "Annehmen", "gameinput.acceptgroupinvite": "Annehmen",
"gameinput.select": "Auswählen", "gameinput.select": "Auswählen",
"gameinput.crafting": "Crafting",
"gameinput.sneak": "Schleichen",
"gameinput.swimdown": "Abwärts Tauchen",
"gameinput.swimup": "Aufwärts Schwimmen",
/// End GameInput section /// End GameInput section

View File

@ -397,7 +397,7 @@ magically infused items?"#,
"gameinput.wallleap": "Wall Leap", "gameinput.wallleap": "Wall Leap",
"gameinput.togglelantern": "Toggle Lantern", "gameinput.togglelantern": "Toggle Lantern",
"gameinput.mount": "Mount", "gameinput.mount": "Mount",
"gameinput.enter": "Enter", "gameinput.chat": "Chat",
"gameinput.command": "Command", "gameinput.command": "Command",
"gameinput.escape": "Escape", "gameinput.escape": "Escape",
"gameinput.map": "Map", "gameinput.map": "Map",
@ -416,6 +416,10 @@ magically infused items?"#,
"gameinput.select": "Select Entity", "gameinput.select": "Select Entity",
"gameinput.acceptgroupinvite": "Accept Group Invite", "gameinput.acceptgroupinvite": "Accept Group Invite",
"gameinput.declinegroupinvite": "Decline Group Invite", "gameinput.declinegroupinvite": "Decline Group Invite",
"gameinput.crafting": "Crafting",
"gameinput.sneak": "Sneak",
"gameinput.swimdown": "Dive downwards",
"gameinput.swimup": "Swim upwards",
/// End GameInput section /// End GameInput section

View File

@ -480,6 +480,10 @@
"voxel.weapon.hammer.2hhammer_mjolnir", "voxel.weapon.hammer.2hhammer_mjolnir",
(2.0, -1.0, 0.0), (-135.0, 90.0, 0.0), 1.1, (2.0, -1.0, 0.0), (-135.0, 90.0, 0.0), 1.1,
), ),
Tool(Hammer("CultPurp0")): VoxTrans(
"voxel.weapon.hammer.cult_purp-0",
(2.0, -1.0, 0.0), (-135.0, 90.0, 0.0), 1.1,
),
// Staffs // Staffs
Tool(Staff("BasicStaff")): VoxTrans( Tool(Staff("BasicStaff")): VoxTrans(
"voxel.weapon.staff.firestaff_starter", "voxel.weapon.staff.firestaff_starter",
@ -1110,6 +1114,26 @@
"voxel.object.bomb", "voxel.object.bomb",
(0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8, (0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8,
), ),
Throwable(Firework(Blue)): VoxTrans(
"voxel.weapon.projectile.fireworks_blue-0",
(0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8,
),
Throwable(Firework(Green)): VoxTrans(
"voxel.weapon.projectile.fireworks_green-0",
(0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8,
),
Throwable(Firework(Purple)): VoxTrans(
"voxel.weapon.projectile.fireworks_purple-0",
(0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8,
),
Throwable(Firework(Red)): VoxTrans(
"voxel.weapon.projectile.fireworks_red-0",
(0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8,
),
Throwable(Firework(Yellow)): VoxTrans(
"voxel.weapon.projectile.fireworks_yellow-0",
(0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8,
),
Throwable(TrainingDummy): VoxTrans( Throwable(TrainingDummy): VoxTrans(
"voxel.object.training_dummy", "voxel.object.training_dummy",
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8, (0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,

View File

@ -82,5 +82,5 @@ void main() {
vec3 color = surf_color; vec3 color = surf_color;
#endif #endif
tgt_color = vec4(color, 1.0 - clamp((distance(focus_pos.xy, f_pos.xy) - (1000.0 - FADE_DIST)) / FADE_DIST, 0, 1)); tgt_color = vec4(color, 0.3);
} }

View File

@ -38,6 +38,12 @@ const int FIRE = 1;
const int GUN_POWDER_SPARK = 2; const int GUN_POWDER_SPARK = 2;
const int SHRAPNEL = 3; const int SHRAPNEL = 3;
const int FIREWORK_BLUE = 4;
const int FIREWORK_GREEN = 5;
const int FIREWORK_PURPLE = 6;
const int FIREWORK_RED = 7;
const int FIREWORK_YELLOW = 8;
// meters per second squared (acceleration) // meters per second squared (acceleration)
const float earth_gravity = 9.807; const float earth_gravity = 9.807;
@ -61,6 +67,10 @@ float exp_scale(float factor) {
return 1 / (1 - lifetime * factor); return 1 / (1 - lifetime * factor);
} }
float linear_scale(float factor) {
return lifetime * factor;
}
void main() { void main() {
float rand0 = hash(vec4(inst_entropy + 0)); float rand0 = hash(vec4(inst_entropy + 0));
float rand1 = hash(vec4(inst_entropy + 1)); float rand1 = hash(vec4(inst_entropy + 1));
@ -76,10 +86,10 @@ void main() {
if (inst_mode == SMOKE) { if (inst_mode == SMOKE) {
attr = Attr( attr = Attr(
linear_motion( linear_motion(
vec3(rand0 * 0.25, rand1 * 0.25, 1.7 + rand5), vec3(0.0, 0.0, 0.0),
vec3(rand2 * 0.2, rand3 * 0.2, 1.0 + rand4 * 0.5)// + vec3(sin(lifetime), sin(lifetime + 1.5), sin(lifetime * 4) * 0.25) vec3(rand2 * 0.1, rand3 * 0.1, 1.0 + rand4 * 0.1)// + vec3(sin(lifetime), sin(lifetime + 1.5), sin(lifetime * 4) * 0.25)
), ),
exp_scale(-0.2), linear_scale(0.5),
vec3(1) vec3(1)
); );
} else if (inst_mode == FIRE) { } else if (inst_mode == FIRE) {
@ -109,6 +119,51 @@ void main() {
3.0 + rand0, 3.0 + rand0,
vec3(0.6 + rand7 * 0.4) vec3(0.6 + rand7 * 0.4)
); );
} else if (inst_mode == FIREWORK_BLUE) {
attr = Attr(
linear_motion(
vec3(0.0, 1.0, 1.0),
vec3(rand4, rand5, rand6) * 40.0 + grav_vel(earth_gravity)
),
3.0 + rand0,
vec3(0.6 + rand7 * 0.4)
);
} else if (inst_mode == FIREWORK_GREEN) {
attr = Attr(
linear_motion(
vec3(0.0, 1.0, 0.0),
vec3(rand4, rand5, rand6) * 40.0 + grav_vel(earth_gravity)
),
3.0 + rand0,
vec3(0.6 + rand7 * 0.4)
);
} else if (inst_mode == FIREWORK_PURPLE) {
attr = Attr(
linear_motion(
vec3(1.0, 0.0, 1.0),
vec3(rand4, rand5, rand6) * 40.0 + grav_vel(earth_gravity)
),
3.0 + rand0,
vec3(0.6 + rand7 * 0.4)
);
} else if (inst_mode == FIREWORK_RED) {
attr = Attr(
linear_motion(
vec3(1.0, 0.0, 0.0),
vec3(rand4, rand5, rand6) * 40.0 + grav_vel(earth_gravity)
),
3.0 + rand0,
vec3(0.6 + rand7 * 0.4)
);
} else if (inst_mode == FIREWORK_YELLOW) {
attr = Attr(
linear_motion(
vec3(1.0, 1.0, 0.0),
vec3(rand4, rand5, rand6) * 40.0 + grav_vel(earth_gravity)
),
3.0 + rand0,
vec3(0.6 + rand7 * 0.4)
);
} else { } else {
attr = Attr( attr = Attr(
linear_motion( linear_motion(

BIN
assets/voxygen/voxel/figure/accessory/orc/male_eyepatch.vox (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -108,6 +108,7 @@
Some(("figure.accessory.orc.teeth-1", (5, 11, 3))), Some(("figure.accessory.orc.teeth-1", (5, 11, 3))),
Some(("figure.accessory.orc.teeth-2", (5, 11, 3))), Some(("figure.accessory.orc.teeth-2", (5, 11, 3))),
Some(("figure.accessory.orc.warpaint-male-0", (0, 4, 3))), Some(("figure.accessory.orc.warpaint-male-0", (0, 4, 3))),
Some(("figure.accessory.orc.male_eyepatch", (0, 3, 0))),
], ],
), ),
(Orc, Female): ( (Orc, Female): (
@ -302,7 +303,8 @@
], ],
beard: [None], beard: [None],
accessory: [ accessory: [
None] None,
Some(("figure.accessory.undead.male_eyepatch", (0, 1, 0))),]
), ),
(Undead, Female): ( (Undead, Female): (
offset: (-5.0, -4.0, -6.75), offset: (-5.0, -4.0, -6.75),
@ -322,7 +324,8 @@
], ],
beard: [None], beard: [None],
accessory: [ accessory: [
None] None,
Some(("figure.accessory.undead.female_eyepatch", (0, 1, -1))),]
), ),
(Danari, Male): ( (Danari, Male): (
offset: (-9.0, -4.0, -7.5), offset: (-9.0, -4.0, -7.5),

View File

@ -425,6 +425,10 @@
vox_spec: ("weapon.hammer.2hhammer_mjolnir", (-2.5, -8.5, -4.0)), vox_spec: ("weapon.hammer.2hhammer_mjolnir", (-2.5, -8.5, -4.0)),
color: None color: None
), ),
Hammer("CultPurp0"): (
vox_spec: ("weapon.hammer.cult_purp-0", (-3.5, -4.5, -5.0)),
color: None
),
/*Dagger("Craftsman"): ( //TODO This should be a 1h hammer! /*Dagger("Craftsman"): ( //TODO This should be a 1h hammer!
vox_spec: ("weapon.hammer.craftsman", (-2.0, -5.0, -5.5)), vox_spec: ("weapon.hammer.craftsman", (-2.0, -5.0, -5.5)),
color: None color: None

BIN
assets/voxygen/voxel/weapon/hammer/cult_purp-0.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/projectile/fireworks-0.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/projectile/fireworks_blue-0.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/projectile/fireworks_green-0.vox (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/projectile/fireworks_red-0.vox (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/projectile/multi-arrow.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -441,9 +441,9 @@ impl Species {
(Species::Human, BodyType::Female) => 1, (Species::Human, BodyType::Female) => 1,
(Species::Human, BodyType::Male) => 1, (Species::Human, BodyType::Male) => 1,
(Species::Orc, BodyType::Female) => 4, (Species::Orc, BodyType::Female) => 4,
(Species::Orc, BodyType::Male) => 5, (Species::Orc, BodyType::Male) => 6,
(Species::Undead, BodyType::Female) => 1, (Species::Undead, BodyType::Female) => 2,
(Species::Undead, BodyType::Male) => 1, (Species::Undead, BodyType::Male) => 2,
} }
} }

View File

@ -58,6 +58,12 @@ pub enum Body {
CampfireLit = 51, CampfireLit = 51,
BoltFireBig = 52, BoltFireBig = 52,
TrainingDummy = 53, TrainingDummy = 53,
FireworkBlue = 54,
FireworkGreen = 55,
FireworkPurple = 56,
FireworkRed = 57,
FireworkYellow = 58,
MultiArrow = 59,
} }
impl Body { impl Body {
@ -67,7 +73,7 @@ impl Body {
} }
} }
pub const ALL_OBJECTS: [Body; 54] = [ pub const ALL_OBJECTS: [Body; 60] = [
Body::Arrow, Body::Arrow,
Body::Bomb, Body::Bomb,
Body::Scarecrow, Body::Scarecrow,
@ -122,6 +128,12 @@ pub const ALL_OBJECTS: [Body; 54] = [
Body::BoltFireBig, Body::BoltFireBig,
Body::ArrowSnake, Body::ArrowSnake,
Body::TrainingDummy, Body::TrainingDummy,
Body::FireworkBlue,
Body::FireworkGreen,
Body::FireworkPurple,
Body::FireworkRed,
Body::FireworkYellow,
Body::MultiArrow,
]; ];
impl From<Body> for super::Body { impl From<Body> for super::Body {
@ -185,6 +197,12 @@ impl Body {
Body::BoltFireBig => "bolt_fire_big", Body::BoltFireBig => "bolt_fire_big",
Body::ArrowSnake => "arrow_snake", Body::ArrowSnake => "arrow_snake",
Body::TrainingDummy => "training_dummy", Body::TrainingDummy => "training_dummy",
Body::FireworkBlue => "firework_blue",
Body::FireworkGreen => "firework_green",
Body::FireworkPurple => "firework_purple",
Body::FireworkRed => "firework_red",
Body::FireworkYellow => "firework_yellow",
Body::MultiArrow => "multi_arrow",
} }
} }
} }

View File

@ -20,6 +20,16 @@ use vek::Rgb;
pub enum Throwable { pub enum Throwable {
Bomb, Bomb,
TrainingDummy, TrainingDummy,
Firework(Reagent),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Reagent {
Blue,
Green,
Purple,
Red,
Yellow,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]

View File

@ -191,7 +191,7 @@ impl Tool {
prepare_duration: Duration::from_millis(100), prepare_duration: Duration::from_millis(100),
charge_duration: Duration::from_millis(1500), charge_duration: Duration::from_millis(1500),
recover_duration: Duration::from_millis(500), recover_duration: Duration::from_millis(500),
projectile_body: Body::Object(object::Body::Arrow), projectile_body: Body::Object(object::Body::MultiArrow),
projectile_light: None, projectile_light: None,
}, },
], ],

View File

@ -1,3 +1,4 @@
use super::item::Reagent;
use crate::sync::Uid; use crate::sync::Uid;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use specs::Component; use specs::Component;
@ -5,7 +6,13 @@ use specs_idvs::IdvStorage;
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Object { pub enum Object {
Bomb { owner: Option<Uid> }, Bomb {
owner: Option<Uid>,
},
Firework {
owner: Option<Uid>,
reagent: Reagent,
},
} }
impl Component for Object { impl Component for Object {

View File

@ -1,5 +1,5 @@
use crate::{comp, sync::Uid, util::Dir}; use crate::{comp, sync::Uid, util::Dir};
use comp::item::Item; use comp::item::{Item, Reagent};
use parking_lot::Mutex; use parking_lot::Mutex;
use specs::Entity as EcsEntity; use specs::Entity as EcsEntity;
use std::{collections::VecDeque, ops::DerefMut}; use std::{collections::VecDeque, ops::DerefMut};
@ -26,6 +26,7 @@ pub enum ServerEvent {
power: f32, power: f32,
owner: Option<Uid>, owner: Option<Uid>,
friendly_damage: bool, friendly_damage: bool,
reagent: Option<Reagent>,
}, },
Damage { Damage {
uid: Uid, uid: Uid,

View File

@ -1,4 +1,5 @@
use crate::comp; use crate::comp;
use comp::item::Reagent;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use vek::*; use vek::*;
@ -12,6 +13,7 @@ pub enum Outcome {
Explosion { Explosion {
pos: Vec3<f32>, pos: Vec3<f32>,
power: f32, power: f32,
reagent: Option<Reagent>, // How can we better define this?
}, },
ProjectileShot { ProjectileShot {
pos: Vec3<f32>, pos: Vec3<f32>,

View File

@ -71,6 +71,7 @@ impl<'a> System<'a> for Sys {
power, power,
owner: projectile.owner, owner: projectile.owner,
friendly_damage: false, friendly_damage: false,
reagent: None,
}) })
}, },
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy { projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
@ -133,6 +134,7 @@ impl<'a> System<'a> for Sys {
power, power,
owner: projectile.owner, owner: projectile.owner,
friendly_damage: false, friendly_damage: false,
reagent: None,
}) })
}, },
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy { projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {

View File

@ -1039,6 +1039,7 @@ fn handle_explosion(
power, power,
owner: ecs.read_storage::<Uid>().get(target).copied(), owner: ecs.read_storage::<Uid>().get(target).copied(),
friendly_damage: true, friendly_damage: true,
reagent: None,
}) })
}, },
None => server.notify_client( None => server.notify_client(

View File

@ -13,6 +13,7 @@ use common::{
terrain::{Block, TerrainGrid}, terrain::{Block, TerrainGrid},
vol::{ReadVol, Vox}, vol::{ReadVol, Vox},
}; };
use comp::item::Reagent;
use specs::{join::Join, saveload::MarkerAllocator, Entity as EcsEntity, WorldExt}; use specs::{join::Join, saveload::MarkerAllocator, Entity as EcsEntity, WorldExt};
use tracing::error; use tracing::error;
use vek::Vec3; use vek::Vec3;
@ -284,6 +285,7 @@ pub fn handle_explosion(
power: f32, power: f32,
owner: Option<Uid>, owner: Option<Uid>,
friendly_damage: bool, friendly_damage: bool,
reagent: Option<Reagent>,
) { ) {
// Go through all other entities // Go through all other entities
let hit_range = 3.0 * power; let hit_range = 3.0 * power;
@ -291,7 +293,11 @@ pub fn handle_explosion(
// Add an outcome // Add an outcome
ecs.write_resource::<Vec<Outcome>>() ecs.write_resource::<Vec<Outcome>>()
.push(Outcome::Explosion { pos, power }); .push(Outcome::Explosion {
pos,
power,
reagent,
});
let owner_entity = owner.and_then(|uid| { let owner_entity = owner.and_then(|uid| {
ecs.read_resource::<UidAllocator>() ecs.read_resource::<UidAllocator>()

View File

@ -11,10 +11,11 @@ use common::{
terrain::block::Block, terrain::block::Block,
vol::{ReadVol, Vox}, vol::{ReadVol, Vox},
}; };
use comp::LightEmitter;
use rand::Rng; use rand::Rng;
use specs::{join::Join, world::WorldExt, Builder, Entity as EcsEntity, WriteStorage}; use specs::{join::Join, world::WorldExt, Builder, Entity as EcsEntity, WriteStorage};
use tracing::{debug, error}; use tracing::{debug, error};
use vek::Vec3; use vek::{Rgb, Vec3};
pub fn swap_lantern( pub fn swap_lantern(
storage: &mut WriteStorage<comp::LightEmitter>, storage: &mut WriteStorage<comp::LightEmitter>,
@ -400,18 +401,36 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
.build(); .build();
} }
let mut rng = rand::thread_rng();
// Throw items // Throw items
for (pos, vel, ori, kind) in thrown_items { for (pos, vel, ori, kind) in thrown_items {
let vel = vel.0 let vel = match kind {
+ *ori.0 * 20.0 item::Throwable::Firework(_) => Vec3::new(
+ Vec3::unit_z() * 15.0 rng.gen_range(-15.0, 15.0),
+ Vec3::<f32>::zero().map(|_| rand::thread_rng().gen::<f32>() - 0.5) * 4.0; rng.gen_range(-15.0, 15.0),
rng.gen_range(80.0, 110.0),
),
_ => {
vel.0
+ *ori.0 * 20.0
+ Vec3::unit_z() * 15.0
+ Vec3::<f32>::zero().map(|_| rand::thread_rng().gen::<f32>() - 0.5) * 4.0
},
};
let uid = state.read_component_copied::<Uid>(entity); let uid = state.read_component_copied::<Uid>(entity);
let mut new_entity = state let mut new_entity = state
.create_object(Default::default(), match kind { .create_object(Default::default(), match kind {
item::Throwable::Bomb => comp::object::Body::Bomb, item::Throwable::Bomb => comp::object::Body::Bomb,
item::Throwable::Firework(reagent) => match reagent {
item::Reagent::Blue => comp::object::Body::FireworkBlue,
item::Reagent::Green => comp::object::Body::FireworkGreen,
item::Reagent::Purple => comp::object::Body::FireworkPurple,
item::Reagent::Red => comp::object::Body::FireworkRed,
item::Reagent::Yellow => comp::object::Body::FireworkYellow,
},
item::Throwable::TrainingDummy => comp::object::Body::TrainingDummy, item::Throwable::TrainingDummy => comp::object::Body::TrainingDummy,
}) })
.with(comp::Pos(pos.0 + Vec3::unit_z() * 0.25)) .with(comp::Pos(pos.0 + Vec3::unit_z() * 0.25))
@ -421,6 +440,19 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
item::Throwable::Bomb => { item::Throwable::Bomb => {
new_entity = new_entity.with(comp::Object::Bomb { owner: uid }); new_entity = new_entity.with(comp::Object::Bomb { owner: uid });
}, },
item::Throwable::Firework(reagent) => {
new_entity = new_entity
.with(comp::Object::Firework {
owner: uid,
reagent,
})
.with(LightEmitter {
animated: true,
flicker: 2.0,
strength: 2.0,
col: Rgb::new(1.0, 1.0, 0.0),
});
},
item::Throwable::TrainingDummy => { item::Throwable::TrainingDummy => {
new_entity = new_entity.with(comp::Stats::new( new_entity = new_entity.with(comp::Stats::new(
"Training Dummy".to_string(), "Training Dummy".to_string(),

View File

@ -55,7 +55,8 @@ impl Server {
power, power,
owner, owner,
friendly_damage, friendly_damage,
} => handle_explosion(&self, pos, power, owner, friendly_damage), reagent,
} => handle_explosion(&self, pos, power, owner, friendly_damage, reagent),
ServerEvent::Shoot { ServerEvent::Shoot {
entity, entity,
dir, dir,

View File

@ -1,5 +1,5 @@
use common::{ use common::{
comp::{HealthSource, Object, PhysicsState, Pos}, comp::{HealthSource, Object, PhysicsState, Pos, Vel},
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
state::DeltaTime, state::DeltaTime,
}; };
@ -14,19 +14,26 @@ impl<'a> System<'a> for Sys {
Read<'a, DeltaTime>, Read<'a, DeltaTime>,
Read<'a, EventBus<ServerEvent>>, Read<'a, EventBus<ServerEvent>>,
ReadStorage<'a, Pos>, ReadStorage<'a, Pos>,
ReadStorage<'a, Vel>,
ReadStorage<'a, PhysicsState>, ReadStorage<'a, PhysicsState>,
WriteStorage<'a, Object>, WriteStorage<'a, Object>,
); );
fn run( fn run(
&mut self, &mut self,
(entities, _dt, server_bus, positions, physics_states, mut objects): Self::SystemData, (entities, _dt, server_bus, positions, velocities, physics_states, mut objects): Self::SystemData,
) { ) {
let mut server_emitter = server_bus.emitter(); let mut server_emitter = server_bus.emitter();
// Objects // Objects
for (entity, pos, physics, object) in for (entity, pos, vel, physics, object) in (
(&entities, &positions, &physics_states, &mut objects).join() &entities,
&positions,
&velocities,
&physics_states,
&mut objects,
)
.join()
{ {
match object { match object {
Object::Bomb { owner } => { Object::Bomb { owner } => {
@ -40,6 +47,22 @@ impl<'a> System<'a> for Sys {
power: 4.0, power: 4.0,
owner: *owner, owner: *owner,
friendly_damage: true, friendly_damage: true,
reagent: None,
});
}
},
Object::Firework { owner, reagent } => {
if vel.0.z < 0.0 {
server_emitter.emit(ServerEvent::Destroy {
entity,
cause: HealthSource::Suicide,
});
server_emitter.emit(ServerEvent::Explosion {
pos: pos.0,
power: 4.0,
owner: *owner,
friendly_damage: true,
reagent: Some(*reagent),
}); });
} }
}, },

View File

@ -273,7 +273,7 @@ impl SfxMgr {
} }
match outcome { match outcome {
Outcome::Explosion { pos, power } => { Outcome::Explosion { pos, power, .. } => {
audio.play_sfx( audio.play_sfx(
// TODO: from sfx triggers config // TODO: from sfx triggers config
"voxygen.audio.sfx.explosion", "voxygen.audio.sfx.explosion",

View File

@ -72,7 +72,7 @@ impl From<&crate::settings::GamepadSettings> for ControllerSettings {
.push(GameInput::Escape); .push(GameInput::Escape);
map.entry(settings.game_buttons.enter) map.entry(settings.game_buttons.enter)
.or_default() .or_default()
.push(GameInput::Enter); .push(GameInput::Chat);
map.entry(settings.game_buttons.command) map.entry(settings.game_buttons.command)
.or_default() .or_default()
.push(GameInput::Command); .push(GameInput::Command);

View File

@ -374,7 +374,7 @@ impl<'a> Widget for Chat<'a> {
.w_h(20.0, 20.0) .w_h(20.0, 20.0)
.hover_image(self.imgs.chat_arrow_mo) .hover_image(self.imgs.chat_arrow_mo)
.press_image(self.imgs.chat_arrow_press) .press_image(self.imgs.chat_arrow_press)
.bottom_right_with_margins_on(state.ids.message_box_bg, 0.0, -22.0) .top_right_with_margins_on(state.ids.message_box_bg, 0.0, -22.0)
.parent(id) .parent(id)
.set(state.ids.chat_arrow, ui) .set(state.ids.chat_arrow, ui)
.was_clicked() .was_clicked()

View File

@ -2267,7 +2267,7 @@ impl Hud {
_ if !self.show.ui => false, _ if !self.show.ui => false,
WinEvent::Zoom(_) => !cursor_grabbed && !self.ui.no_widget_capturing_mouse(), WinEvent::Zoom(_) => !cursor_grabbed && !self.ui.no_widget_capturing_mouse(),
WinEvent::InputUpdate(GameInput::Enter, true) => { WinEvent::InputUpdate(GameInput::Chat, true) => {
self.ui.focus_widget(if self.typing() { self.ui.focus_widget(if self.typing() {
None None
} else { } else {

View File

@ -363,11 +363,10 @@ impl<'a> Widget for Overhead<'a> {
})) }))
.parent(id) .parent(id)
.set(state.ids.health_bar, ui); .set(state.ids.health_bar, ui);
// TODO Only show health values for entities below 100% health
let mut txt = format!( let mut txt = format!(
"{}/{}", "{}/{}",
self.stats.health.current().max(1) / 10 as u32, /* Don't show 0 health for (self.stats.health.current() / 10).max(1) as u32, /* Don't show 0 health for
* living entities */ * living entities */
self.stats.health.maximum() / 10 as u32, self.stats.health.maximum() / 10 as u32,
); );
if self.stats.is_dead { if self.stats.is_dead {

View File

@ -1,6 +1,6 @@
#![deny(unsafe_code)] #![deny(unsafe_code)]
#![allow(clippy::option_map_unit_fn)] #![allow(clippy::option_map_unit_fn)]
#![feature(drain_filter, bool_to_option)] #![feature(drain_filter, bool_to_option, or_patterns)]
#![recursion_limit = "2048"] #![recursion_limit = "2048"]
#[macro_use] #[macro_use]

View File

@ -263,6 +263,7 @@ impl<'a> MainMenuUi {
env!("CARGO_PKG_VERSION"), env!("CARGO_PKG_VERSION"),
common::util::GIT_VERSION.to_string() common::util::GIT_VERSION.to_string()
); );
let scale = 0.8;
const TEXT_COLOR: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0); const TEXT_COLOR: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0);
const TEXT_COLOR_2: Color = Color::Rgba(1.0, 1.0, 1.0, 0.2); const TEXT_COLOR_2: Color = Color::Rgba(1.0, 1.0, 1.0, 0.2);
const TEXT_BG: Color = Color::Rgba(0.0, 0.0, 0.0, 1.0); const TEXT_BG: Color = Color::Rgba(0.0, 0.0, 0.0, 1.0);
@ -330,9 +331,10 @@ impl<'a> MainMenuUi {
}; };
// Version displayed top right corner // Version displayed top right corner
let pos = if self.connect { 5.0 } else { 98.0 };
Text::new(&version) Text::new(&version)
.color(TEXT_COLOR) .color(TEXT_COLOR)
.top_right_with_margins_on(ui_widgets.window, 5.0, 5.0) .top_right_with_margins_on(ui_widgets.window, pos * scale, 10.0 * scale)
.font_id(self.fonts.cyri.conrod_id) .font_id(self.fonts.cyri.conrod_id)
.font_size(self.fonts.cyri.scale(14)) .font_size(self.fonts.cyri.scale(14))
.set(self.ids.version, ui_widgets); .set(self.ids.version, ui_widgets);
@ -463,20 +465,21 @@ impl<'a> MainMenuUi {
if !self.connect { if !self.connect {
Image::new(self.imgs.banner) Image::new(self.imgs.banner)
.w_h(65.0 * 6.0, 100.0 * 6.0) .w_h(65.0 * 6.0 * scale, 100.0 * 6.0 * scale)
.middle_of(self.ids.bg) .middle_of(self.ids.bg)
.color(Some(Color::Rgba(0.0, 0.0, 0.0, 0.9))) .color(Some(Color::Rgba(0.0, 0.0, 0.0, 0.0)))
.set(self.ids.banner, ui_widgets); .set(self.ids.banner, ui_widgets);
Image::new(self.imgs.banner_top) Image::new(self.imgs.banner_top)
.w_h(70.0 * 6.0, 34.0) .w_h(70.0 * 6.0 * scale, 34.0 * scale)
.mid_top_with_margin_on(self.ids.banner, -34.0) .mid_top_with_margin_on(self.ids.banner, -34.0)
.color(Some(Color::Rgba(0.0, 0.0, 0.0, 0.0)))
.set(self.ids.banner_top, ui_widgets); .set(self.ids.banner_top, ui_widgets);
// Logo // Logo
Image::new(self.imgs.v_logo) Image::new(self.imgs.v_logo)
.w_h(123.0 * 2.5, 35.0 * 2.5) .w_h(123.0 * 2.5 * scale, 35.0 * 2.5 * scale)
.mid_top_with_margin_on(self.ids.banner_top, 45.0) .top_right_with_margins_on(self.ids.bg, 10.0, 10.0)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.95))) .color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.95)))
.set(self.ids.v_logo, ui_widgets); .set(self.ids.v_logo, ui_widgets);
@ -537,18 +540,18 @@ impl<'a> MainMenuUi {
}; };
} }
// Info Window // Info Window
Rectangle::fill_with([550.0, 250.0], COL1) Rectangle::fill_with([550.0 * scale, 250.0 * scale], COL1)
.top_left_with_margins_on(ui_widgets.window, 40.0, 40.0) .top_left_with_margins_on(ui_widgets.window, 40.0 * scale, 40.0 * scale)
.color(Color::Rgba(0.0, 0.0, 0.0, 0.95)) .color(Color::Rgba(0.0, 0.0, 0.0, 0.80))
.set(self.ids.info_frame, ui_widgets); .set(self.ids.info_frame, ui_widgets);
Image::new(self.imgs.banner_bottom) Image::new(self.imgs.banner_bottom)
.mid_bottom_with_margin_on(self.ids.info_frame, -50.0) .mid_bottom_with_margin_on(self.ids.info_frame, -50.0 * scale)
.w_h(550.0, 50.0) .w_h(550.0 * scale, 50.0 * scale)
.color(Some(Color::Rgba(0.0, 0.0, 0.0, 0.95))) .color(Some(Color::Rgba(0.0, 0.0, 0.0, 0.80)))
.set(self.ids.info_bottom, ui_widgets); .set(self.ids.info_bottom, ui_widgets);
Text::new(intro_text) Text::new(intro_text)
.top_left_with_margins_on(self.ids.info_frame, 15.0, 15.0) .top_left_with_margins_on(self.ids.info_frame, 15.0 * scale, 15.0 * scale)
.font_size(self.fonts.cyri.scale(20)) .font_size(self.fonts.cyri.scale(16))
.font_id(self.fonts.cyri.conrod_id) .font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR) .color(TEXT_COLOR)
.set(self.ids.info_text, ui_widgets); .set(self.ids.info_text, ui_widgets);
@ -569,17 +572,20 @@ impl<'a> MainMenuUi {
} }
// Username // Username
Rectangle::fill_with([320.0, 50.0], color::rgba(0.0, 0.0, 0.0, 0.0)) Rectangle::fill_with(
.mid_top_with_margin_on(self.ids.banner_top, 150.0) [320.0 * scale, 50.0 * scale],
.set(self.ids.usrnm_bg, ui_widgets); color::rgba(0.0, 0.0, 0.0, 0.0),
)
.mid_top_with_margin_on(self.ids.banner_top, 150.0)
.set(self.ids.usrnm_bg, ui_widgets);
Image::new(self.imgs.input_bg) Image::new(self.imgs.input_bg)
.w_h(338.0, 50.0) .w_h(338.0 * scale, 50.0 * scale)
.middle_of(self.ids.usrnm_bg) .middle_of(self.ids.usrnm_bg)
.set(self.ids.username_bg, ui_widgets); .set(self.ids.username_bg, ui_widgets);
for event in TextBox::new(&self.username) for event in TextBox::new(&self.username)
.w_h(290.0, 30.0) .w_h(290.0* scale, 30.0* scale)
.mid_bottom_with_margin_on(self.ids.username_bg, 14.0) .mid_bottom_with_margin_on(self.ids.username_bg, 14.0* scale)
.font_size(self.fonts.cyri.scale(22)) .font_size(self.fonts.cyri.scale(18))
.font_id(self.fonts.cyri.conrod_id) .font_id(self.fonts.cyri.conrod_id)
.text_color(TEXT_COLOR) .text_color(TEXT_COLOR)
// transparent background // transparent background
@ -598,16 +604,19 @@ impl<'a> MainMenuUi {
} }
} }
// Password // Password
Rectangle::fill_with([320.0, 50.0], color::rgba(0.0, 0.0, 0.0, 0.0)) Rectangle::fill_with(
.down_from(self.ids.usrnm_bg, 10.0) [320.0 * scale, 50.0 * scale],
.set(self.ids.passwd_bg, ui_widgets); color::rgba(0.0, 0.0, 0.0, 0.0),
)
.down_from(self.ids.usrnm_bg, 10.0 * scale)
.set(self.ids.passwd_bg, ui_widgets);
Image::new(self.imgs.input_bg) Image::new(self.imgs.input_bg)
.w_h(338.0, 50.0) .w_h(338.0 * scale, 50.0 * scale)
.middle_of(self.ids.passwd_bg) .middle_of(self.ids.passwd_bg)
.set(self.ids.password_bg, ui_widgets); .set(self.ids.password_bg, ui_widgets);
for event in TextBox::new(&self.password) for event in TextBox::new(&self.password)
.w_h(290.0, 30.0) .w_h(290.0 * scale, 30.0* scale)
.mid_bottom_with_margin_on(self.ids.password_bg, 10.0) .mid_bottom_with_margin_on(self.ids.password_bg, 10.0* scale)
// the text is smaller to allow longer passwords, conrod limits text length // the text is smaller to allow longer passwords, conrod limits text length
// this allows 35 characters but can be increased, approximate formula: 420 / scale = length // this allows 35 characters but can be increased, approximate formula: 420 / scale = length
.font_size(self.fonts.cyri.scale(12)) .font_size(self.fonts.cyri.scale(12))
@ -695,17 +704,20 @@ impl<'a> MainMenuUi {
}; };
} }
// Server address // Server address
Rectangle::fill_with([320.0, 50.0], color::rgba(0.0, 0.0, 0.0, 0.0)) Rectangle::fill_with(
.down_from(self.ids.passwd_bg, 8.0) [320.0 * scale, 50.0 * scale],
.set(self.ids.srvr_bg, ui_widgets); color::rgba(0.0, 0.0, 0.0, 0.0),
)
.down_from(self.ids.passwd_bg, 8.0 * scale)
.set(self.ids.srvr_bg, ui_widgets);
Image::new(self.imgs.input_bg) Image::new(self.imgs.input_bg)
.w_h(338.0, 50.0) .w_h(338.0 * scale, 50.0 * scale)
.middle_of(self.ids.srvr_bg) .middle_of(self.ids.srvr_bg)
.set(self.ids.address_bg, ui_widgets); .set(self.ids.address_bg, ui_widgets);
for event in TextBox::new(&self.server_address) for event in TextBox::new(&self.server_address)
.w_h(290.0, 30.0) .w_h(290.0*scale, 30.0*scale)
.mid_top_with_margin_on(self.ids.address_bg, 8.0) .mid_top_with_margin_on(self.ids.address_bg, 8.0*scale)
.font_size(self.fonts.cyri.scale(22)) .font_size(self.fonts.cyri.scale(18))
.font_id(self.fonts.cyri.conrod_id) .font_id(self.fonts.cyri.conrod_id)
.text_color(TEXT_COLOR) .text_color(TEXT_COLOR)
// transparent background // transparent background
@ -727,14 +739,14 @@ impl<'a> MainMenuUi {
if Button::image(self.imgs.button) if Button::image(self.imgs.button)
.hover_image(self.imgs.button_hover) .hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press) .press_image(self.imgs.button_press)
.w_h(258.0, 55.0) .w_h(258.0*scale, 55.0*scale)
.down_from(self.ids.address_bg, 20.0) .down_from(self.ids.address_bg, 20.0*scale)
.align_middle_x_of(self.ids.address_bg) .align_middle_x_of(self.ids.address_bg)
.label(&self.voxygen_i18n.get("common.multiplayer")) .label(&self.voxygen_i18n.get("common.multiplayer"))
.label_font_id(self.fonts.cyri.conrod_id) .label_font_id(self.fonts.cyri.conrod_id)
.label_color(TEXT_COLOR) .label_color(TEXT_COLOR)
.label_font_size(self.fonts.cyri.scale(22)) .label_font_size(self.fonts.cyri.scale(18))
.label_y(Relative::Scalar(5.0)) .label_y(Relative::Scalar(4.0))
/*.with_tooltip( /*.with_tooltip(
tooltip_manager, tooltip_manager,
"Login", "Login",
@ -755,14 +767,14 @@ impl<'a> MainMenuUi {
if Button::image(self.imgs.button) if Button::image(self.imgs.button)
.hover_image(self.imgs.button_hover) .hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press) .press_image(self.imgs.button_press)
.w_h(258.0, 55.0) .w_h(258.0 * scale, 55.0 * scale)
.down_from(self.ids.login_button, 20.0) .down_from(self.ids.login_button, 20.0 * scale)
.align_middle_x_of(self.ids.address_bg) .align_middle_x_of(self.ids.address_bg)
.label(&self.voxygen_i18n.get("common.singleplayer")) .label(&self.voxygen_i18n.get("common.singleplayer"))
.label_font_id(self.fonts.cyri.conrod_id) .label_font_id(self.fonts.cyri.conrod_id)
.label_color(TEXT_COLOR) .label_color(TEXT_COLOR)
.label_font_size(self.fonts.cyri.scale(22)) .label_font_size(self.fonts.cyri.scale(18))
.label_y(Relative::Scalar(5.0)) .label_y(Relative::Scalar(4.0))
.label_x(Relative::Scalar(2.0)) .label_x(Relative::Scalar(2.0))
.set(self.ids.singleplayer_button, ui_widgets) .set(self.ids.singleplayer_button, ui_widgets)
.was_clicked() .was_clicked()
@ -773,14 +785,14 @@ impl<'a> MainMenuUi {
} }
// Quit // Quit
if Button::image(self.imgs.button) if Button::image(self.imgs.button)
.w_h(190.0, 40.0) .w_h(190.0 * scale, 40.0 * scale)
.bottom_left_with_margins_on(ui_widgets.window, 60.0, 30.0) .bottom_left_with_margins_on(ui_widgets.window, 60.0 * scale, 30.0 * scale)
.hover_image(self.imgs.button_hover) .hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press) .press_image(self.imgs.button_press)
.label(&self.voxygen_i18n.get("common.quit")) .label(&self.voxygen_i18n.get("common.quit"))
.label_font_id(self.fonts.cyri.conrod_id) .label_font_id(self.fonts.cyri.conrod_id)
.label_color(TEXT_COLOR) .label_color(TEXT_COLOR)
.label_font_size(self.fonts.cyri.scale(20)) .label_font_size(self.fonts.cyri.scale(16))
.label_y(Relative::Scalar(3.0)) .label_y(Relative::Scalar(3.0))
.set(self.ids.quit_button, ui_widgets) .set(self.ids.quit_button, ui_widgets)
.was_clicked() .was_clicked()
@ -790,14 +802,14 @@ impl<'a> MainMenuUi {
// Settings // Settings
if Button::image(self.imgs.button) if Button::image(self.imgs.button)
.w_h(190.0, 40.0) .w_h(190.0*scale, 40.0*scale)
.up_from(self.ids.quit_button, 8.0) .up_from(self.ids.quit_button, 8.0*scale)
//.hover_image(self.imgs.button_hover) //.hover_image(self.imgs.button_hover)
//.press_image(self.imgs.button_press) //.press_image(self.imgs.button_press)
.label(&self.voxygen_i18n.get("common.settings")) .label(&self.voxygen_i18n.get("common.settings"))
.label_font_id(self.fonts.cyri.conrod_id) .label_font_id(self.fonts.cyri.conrod_id)
.label_color(TEXT_COLOR_2) .label_color(TEXT_COLOR_2)
.label_font_size(self.fonts.cyri.scale(20)) .label_font_size(self.fonts.cyri.scale(16))
.label_y(Relative::Scalar(3.0)) .label_y(Relative::Scalar(3.0))
.set(self.ids.settings_button, ui_widgets) .set(self.ids.settings_button, ui_widgets)
.was_clicked() .was_clicked()
@ -807,14 +819,14 @@ impl<'a> MainMenuUi {
// Servers // Servers
if Button::image(self.imgs.button) if Button::image(self.imgs.button)
.w_h(190.0, 40.0) .w_h(190.0 * scale, 40.0 * scale)
.up_from(self.ids.settings_button, 8.0) .up_from(self.ids.settings_button, 8.0 * scale)
.hover_image(self.imgs.button_hover) .hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press) .press_image(self.imgs.button_press)
.label(&self.voxygen_i18n.get("common.servers")) .label(&self.voxygen_i18n.get("common.servers"))
.label_font_id(self.fonts.cyri.conrod_id) .label_font_id(self.fonts.cyri.conrod_id)
.label_color(TEXT_COLOR) .label_color(TEXT_COLOR)
.label_font_size(self.fonts.cyri.scale(20)) .label_font_size(self.fonts.cyri.scale(16))
.label_y(Relative::Scalar(3.0)) .label_y(Relative::Scalar(3.0))
.set(self.ids.servers_button, ui_widgets) .set(self.ids.servers_button, ui_widgets)
.was_clicked() .was_clicked()

View File

@ -93,6 +93,11 @@ pub enum ParticleMode {
CampfireFire = 1, CampfireFire = 1,
GunPowderSpark = 2, GunPowderSpark = 2,
Shrapnel = 3, Shrapnel = 3,
FireworkBlue = 4,
FireworkGreen = 5,
FireworkPurple = 6,
FireworkRed = 7,
FireworkYellow = 8,
} }
impl ParticleMode { impl ParticleMode {

View File

@ -3371,6 +3371,26 @@ pub fn mesh_object(
Vec3::new(-0.5, -6.0, -1.5), Vec3::new(-0.5, -6.0, -1.5),
), ),
Body::Bomb => ("object.bomb", Vec3::new(-5.5, -5.5, 0.0)), Body::Bomb => ("object.bomb", Vec3::new(-5.5, -5.5, 0.0)),
Body::FireworkBlue => (
"weapon.projectile.fireworks_blue-0",
Vec3::new(0.0, 0.0, 0.0),
),
Body::FireworkGreen => (
"weapon.projectile.fireworks_green-0",
Vec3::new(0.0, 0.0, 0.0),
),
Body::FireworkPurple => (
"weapon.projectile.fireworks_purple-0",
Vec3::new(0.0, 0.0, 0.0),
),
Body::FireworkRed => (
"weapon.projectile.fireworks_red-0",
Vec3::new(0.0, 0.0, 0.0),
),
Body::FireworkYellow => (
"weapon.projectile.fireworks_yellow-0",
Vec3::new(0.0, 0.0, 0.0),
),
Body::Scarecrow => ("object.scarecrow", Vec3::new(-9.5, -4.0, 0.0)), Body::Scarecrow => ("object.scarecrow", Vec3::new(-9.5, -4.0, 0.0)),
Body::Cauldron => ("object.cauldron", Vec3::new(-10.0, -10.0, 0.0)), Body::Cauldron => ("object.cauldron", Vec3::new(-10.0, -10.0, 0.0)),
Body::ChestVines => ("object.chest_vines", Vec3::new(-7.5, -6.0, 0.0)), Body::ChestVines => ("object.chest_vines", Vec3::new(-7.5, -6.0, 0.0)),
@ -3429,6 +3449,7 @@ pub fn mesh_object(
Body::BoltFire => ("weapon.projectile.fire-bolt-0", Vec3::new(-3.0, -5.5, -3.0)), Body::BoltFire => ("weapon.projectile.fire-bolt-0", Vec3::new(-3.0, -5.5, -3.0)),
Body::BoltFireBig => ("weapon.projectile.fire-bolt-1", Vec3::new(-6.0, -6.0, -6.0)), Body::BoltFireBig => ("weapon.projectile.fire-bolt-1", Vec3::new(-6.0, -6.0, -6.0)),
Body::TrainingDummy => ("object.training_dummy", Vec3::new(-7.0, -5.0, 0.0)), Body::TrainingDummy => ("object.training_dummy", Vec3::new(-7.0, -5.0, 0.0)),
Body::MultiArrow => ("weapon.projectile.multi-arrow", Vec3::new(-4.0, -9.5, -5.0)),
}; };
load_mesh(name, offset, generate_mesh) load_mesh(name, offset, generate_mesh)
} }

View File

@ -32,6 +32,7 @@ use common::{
terrain::{BlockKind, TerrainChunk}, terrain::{BlockKind, TerrainChunk},
vol::ReadVol, vol::ReadVol,
}; };
use comp::item::Reagent;
use num::traits::{Float, FloatConst}; use num::traits::{Float, FloatConst};
use specs::{Entity as EcsEntity, Join, WorldExt}; use specs::{Entity as EcsEntity, Join, WorldExt};
use vek::*; use vek::*;
@ -373,9 +374,31 @@ impl Scene {
self.sfx_mgr.handle_outcome(&outcome, audio); self.sfx_mgr.handle_outcome(&outcome, audio);
match outcome { match outcome {
Outcome::Explosion { pos, power, .. } => self.event_lights.push(EventLight { Outcome::Explosion {
light: Light::new(*pos, Rgb::new(1.0, 0.5, 0.0), *power * 2.5), pos,
timeout: 0.5, power,
reagent,
} => self.event_lights.push(EventLight {
light: Light::new(
*pos,
match reagent {
Some(Reagent::Blue) => Rgb::new(0.0, 0.0, 1.0),
Some(Reagent::Green) => Rgb::new(0.0, 1.0, 0.0),
Some(Reagent::Purple) => Rgb::new(1.0, 0.0, 1.0),
Some(Reagent::Red) => Rgb::new(1.0, 0.0, 0.0),
Some(Reagent::Yellow) => Rgb::new(1.0, 1.0, 0.0),
None => Rgb::new(1.0, 0.5, 0.0),
},
*power
* match reagent {
Some(_) => 5.0,
None => 2.5,
},
),
timeout: match reagent {
Some(_) => 1.0,
None => 0.5,
},
fadeout: |timeout| timeout * 2.0, fadeout: |timeout| timeout * 2.0,
}), }),
Outcome::ProjectileShot { .. } => {}, Outcome::ProjectileShot { .. } => {},

View File

@ -8,7 +8,7 @@ use crate::{
}; };
use common::{ use common::{
assets, assets,
comp::{object, Body, CharacterState, Pos}, comp::{item::Reagent, object, Body, CharacterState, Pos},
figure::Segment, figure::Segment,
outcome::Outcome, outcome::Outcome,
}; };
@ -48,15 +48,27 @@ impl ParticleMgr {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
match outcome { match outcome {
Outcome::Explosion { pos, power } => { Outcome::Explosion {
pos,
power,
reagent,
} => {
for _ in 0..150 { for _ in 0..150 {
self.particles.push(Particle::new( self.particles.push(Particle::new(
Duration::from_millis(250), Duration::from_millis(if reagent.is_some() { 1000 } else { 250 }),
time, time,
ParticleMode::Shrapnel, match reagent {
Some(Reagent::Blue) => ParticleMode::FireworkBlue,
Some(Reagent::Green) => ParticleMode::FireworkGreen,
Some(Reagent::Purple) => ParticleMode::FireworkPurple,
Some(Reagent::Red) => ParticleMode::FireworkRed,
Some(Reagent::Yellow) => ParticleMode::FireworkYellow,
None => ParticleMode::Shrapnel,
},
*pos, *pos,
)); ));
} }
for _ in 0..200 { for _ in 0..200 {
self.particles.push(Particle::new( self.particles.push(Particle::new(
Duration::from_secs(4), Duration::from_secs(4),
@ -113,7 +125,14 @@ impl ParticleMgr {
Body::Object(object::Body::BoltFireBig) => { Body::Object(object::Body::BoltFireBig) => {
self.maintain_boltfirebig_particles(scene_data, pos) self.maintain_boltfirebig_particles(scene_data, pos)
}, },
Body::Object(object::Body::Bomb) => self.maintain_bomb_particles(scene_data, pos), Body::Object(
object::Body::Bomb
| object::Body::FireworkBlue
| object::Body::FireworkGreen
| object::Body::FireworkPurple
| object::Body::FireworkRed
| object::Body::FireworkYellow,
) => self.maintain_bomb_particles(scene_data, pos),
_ => {}, _ => {},
} }
} }

View File

@ -122,7 +122,7 @@ impl ControlSettings {
GameInput::Secondary => KeyMouse::Mouse(MouseButton::Right), GameInput::Secondary => KeyMouse::Mouse(MouseButton::Right),
GameInput::ToggleCursor => KeyMouse::Key(VirtualKeyCode::Tab), GameInput::ToggleCursor => KeyMouse::Key(VirtualKeyCode::Tab),
GameInput::Escape => KeyMouse::Key(VirtualKeyCode::Escape), GameInput::Escape => KeyMouse::Key(VirtualKeyCode::Escape),
GameInput::Enter => KeyMouse::Key(VirtualKeyCode::Return), GameInput::Chat => KeyMouse::Key(VirtualKeyCode::Return),
GameInput::Command => KeyMouse::Key(VirtualKeyCode::Slash), GameInput::Command => KeyMouse::Key(VirtualKeyCode::Slash),
GameInput::MoveForward => KeyMouse::Key(VirtualKeyCode::W), GameInput::MoveForward => KeyMouse::Key(VirtualKeyCode::W),
GameInput::MoveLeft => KeyMouse::Key(VirtualKeyCode::A), GameInput::MoveLeft => KeyMouse::Key(VirtualKeyCode::A),
@ -207,7 +207,7 @@ impl Default for ControlSettings {
//GameInput::WallLeap, //GameInput::WallLeap,
GameInput::ToggleLantern, GameInput::ToggleLantern,
GameInput::Mount, GameInput::Mount,
GameInput::Enter, GameInput::Chat,
GameInput::Command, GameInput::Command,
GameInput::Escape, GameInput::Escape,
GameInput::Map, GameInput::Map,

View File

@ -47,7 +47,7 @@ pub enum GameInput {
//WallLeap, //WallLeap,
ToggleLantern, ToggleLantern,
Mount, Mount,
Enter, Chat,
Command, Command,
Escape, Escape,
Map, Map,
@ -98,7 +98,7 @@ impl GameInput {
//GameInput::WallLeap => "gameinput.wallleap", //GameInput::WallLeap => "gameinput.wallleap",
GameInput::ToggleLantern => "gameinput.togglelantern", GameInput::ToggleLantern => "gameinput.togglelantern",
GameInput::Mount => "gameinput.mount", GameInput::Mount => "gameinput.mount",
GameInput::Enter => "gameinput.enter", GameInput::Chat => "gameinput.chat",
GameInput::Command => "gameinput.command", GameInput::Command => "gameinput.command",
GameInput::CycleCamera => "gameinput.cyclecamera", GameInput::CycleCamera => "gameinput.cyclecamera",
GameInput::Escape => "gameinput.escape", GameInput::Escape => "gameinput.escape",
@ -158,12 +158,13 @@ impl GameInput {
GameInput::Sneak, GameInput::Sneak,
GameInput::ToggleLantern, GameInput::ToggleLantern,
GameInput::Mount, GameInput::Mount,
GameInput::Enter, GameInput::Chat,
GameInput::Command, GameInput::Command,
GameInput::Escape, GameInput::Escape,
GameInput::Map, GameInput::Map,
GameInput::Bag, GameInput::Bag,
GameInput::Social, GameInput::Social,
GameInput::Crafting,
GameInput::Spellbook, GameInput::Spellbook,
GameInput::Settings, GameInput::Settings,
GameInput::ToggleInterface, GameInput::ToggleInterface,