commit
301dfdc200
|
@ -6,7 +6,7 @@ jobs:
|
||||||
displayName: "Install build dependencies"
|
displayName: "Install build dependencies"
|
||||||
condition: eq(variables['Agent.OS'], 'Linux')
|
condition: eq(variables['Agent.OS'], 'Linux')
|
||||||
minrust: 1.44.1
|
minrust: 1.44.1
|
||||||
clippy: -A clippy::not_unsafe_ptr_arg_deref -A clippy::float_cmp
|
clippy: -D clippy::all
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
repositories:
|
repositories:
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#![recursion_limit = "600"]
|
#![recursion_limit = "600"]
|
||||||
|
#![allow(clippy::identity_op)]
|
||||||
|
#![allow(clippy::collapsible_if)]
|
||||||
|
|
||||||
extern crate steven_shared as shared;
|
extern crate steven_shared as shared;
|
||||||
|
|
||||||
|
@ -261,7 +263,7 @@ macro_rules! define_blocks {
|
||||||
return $update_state;
|
return $update_state;
|
||||||
)?
|
)?
|
||||||
Block::$name {
|
Block::$name {
|
||||||
$($fname: $fname,)?
|
$($fname,)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
|
@ -376,7 +378,7 @@ macro_rules! define_blocks {
|
||||||
$($fname: $fname.next().unwrap(),)?
|
$($fname: $fname.next().unwrap(),)?
|
||||||
},
|
},
|
||||||
state: CombinationIterState {
|
state: CombinationIterState {
|
||||||
$($fname: $fname,)?
|
$($fname,)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -570,9 +572,9 @@ define_blocks! {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
update_state (world, pos) => if variant == DirtVariant::Podzol {
|
update_state (world, pos) => if variant == DirtVariant::Podzol {
|
||||||
Block::Dirt{snowy: is_snowy(world, pos), variant: variant}
|
Block::Dirt{snowy: is_snowy(world, pos), variant}
|
||||||
} else {
|
} else {
|
||||||
Block::Dirt{snowy: snowy, variant: variant}
|
Block::Dirt{snowy, variant}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
Cobblestone {
|
Cobblestone {
|
||||||
|
@ -774,7 +776,7 @@ define_blocks! {
|
||||||
offset if check_decay {
|
offset if check_decay {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(variant.offset() * (7 * 2) + ((distance as usize - 1) << 1) | (if decayable { 0 } else { 1 }))
|
Some(variant.offset() * (7 * 2) + ((distance as usize - 1) << 1) + (if decayable { 0 } else { 1 }))
|
||||||
},
|
},
|
||||||
material material::LEAVES,
|
material material::LEAVES,
|
||||||
model { ("minecraft", format!("{}_leaves", variant.as_string()) ) },
|
model { ("minecraft", format!("{}_leaves", variant.as_string()) ) },
|
||||||
|
@ -1337,7 +1339,7 @@ define_blocks! {
|
||||||
collision vec![],
|
collision vec![],
|
||||||
update_state (world, pos) => {
|
update_state (world, pos) => {
|
||||||
Fire{
|
Fire{
|
||||||
age: age,
|
age,
|
||||||
up: can_burn(world, pos.shift(Direction::Up)),
|
up: can_burn(world, pos.shift(Direction::Up)),
|
||||||
north: can_burn(world, pos.shift(Direction::North)),
|
north: can_burn(world, pos.shift(Direction::North)),
|
||||||
south: can_burn(world, pos.shift(Direction::South)),
|
south: can_burn(world, pos.shift(Direction::South)),
|
||||||
|
@ -1438,7 +1440,7 @@ define_blocks! {
|
||||||
south: can_connect_redstone(world, pos, Direction::South),
|
south: can_connect_redstone(world, pos, Direction::South),
|
||||||
west: can_connect_redstone(world, pos, Direction::West),
|
west: can_connect_redstone(world, pos, Direction::West),
|
||||||
east: can_connect_redstone(world, pos, Direction::East),
|
east: can_connect_redstone(world, pos, Direction::East),
|
||||||
power: power
|
power
|
||||||
},
|
},
|
||||||
multipart (key, val) => match key {
|
multipart (key, val) => match key {
|
||||||
"north" => val.contains(north.as_string()),
|
"north" => val.contains(north.as_string()),
|
||||||
|
@ -1565,7 +1567,7 @@ define_blocks! {
|
||||||
collision door_collision(facing, hinge, open),
|
collision door_collision(facing, hinge, open),
|
||||||
update_state (world, pos) => {
|
update_state (world, pos) => {
|
||||||
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
||||||
Block::WoodenDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
|
Block::WoodenDoor{facing, half, hinge, open, powered}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
Ladder {
|
Ladder {
|
||||||
|
@ -1702,7 +1704,7 @@ define_blocks! {
|
||||||
collision door_collision(facing, hinge, open),
|
collision door_collision(facing, hinge, open),
|
||||||
update_state (world, pos) => {
|
update_state (world, pos) => {
|
||||||
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
||||||
Block::IronDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
|
Block::IronDoor{facing, half, hinge, open, powered}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
WoodenPressurePlate {
|
WoodenPressurePlate {
|
||||||
|
@ -2088,7 +2090,7 @@ define_blocks! {
|
||||||
Point3::new(0.0, 0.0, 0.0),
|
Point3::new(0.0, 0.0, 0.0),
|
||||||
Point3::new(1.0, 1.0/8.0, 1.0)
|
Point3::new(1.0, 1.0/8.0, 1.0)
|
||||||
)],
|
)],
|
||||||
update_state (world, pos) => RepeaterPowered{delay: delay, facing: facing, locked: update_repeater_state(world, pos, facing)},
|
update_state (world, pos) => RepeaterPowered{delay, facing, locked: update_repeater_state(world, pos, facing)},
|
||||||
}
|
}
|
||||||
StainedGlass {
|
StainedGlass {
|
||||||
props {
|
props {
|
||||||
|
@ -2222,7 +2224,7 @@ define_blocks! {
|
||||||
data None::<usize>,
|
data None::<usize>,
|
||||||
offset mushroom_block_offset(false, west, up, south, north, east, down),
|
offset mushroom_block_offset(false, west, up, south, north, east, down),
|
||||||
model { ("minecraft", "mushroom_stem") },
|
model { ("minecraft", "mushroom_stem") },
|
||||||
variant format!("variant=all_stem"),
|
variant "variant=all_stem".to_string(),
|
||||||
}
|
}
|
||||||
IronBars {
|
IronBars {
|
||||||
props {
|
props {
|
||||||
|
@ -2380,7 +2382,7 @@ define_blocks! {
|
||||||
_ => Direction::Up,
|
_ => Direction::Up,
|
||||||
};
|
};
|
||||||
|
|
||||||
Block::PumpkinStem{age: age, facing: facing}
|
Block::PumpkinStem{age, facing}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
MelonStem {
|
MelonStem {
|
||||||
|
@ -2416,7 +2418,7 @@ define_blocks! {
|
||||||
_ => Direction::Up,
|
_ => Direction::Up,
|
||||||
};
|
};
|
||||||
|
|
||||||
Block::MelonStem{age: age, facing: facing}
|
Block::MelonStem{age, facing}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
Vine {
|
Vine {
|
||||||
|
@ -2448,7 +2450,7 @@ define_blocks! {
|
||||||
update_state (world, pos) => {
|
update_state (world, pos) => {
|
||||||
let mat = world.get_block(pos.shift(Direction::Up)).get_material();
|
let mat = world.get_block(pos.shift(Direction::Up)).get_material();
|
||||||
let up = mat.renderable && (mat.should_cull_against || mat.never_cull /* Because leaves */);
|
let up = mat.renderable && (mat.should_cull_against || mat.never_cull /* Because leaves */);
|
||||||
Vine{up: up, south: south, west: west, north: north, east: east}
|
Vine{up, south, west, north, east}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
FenceGate {
|
FenceGate {
|
||||||
|
@ -2470,10 +2472,10 @@ define_blocks! {
|
||||||
variant format!("facing={},in_wall={},open={}", facing.as_string(), in_wall, open),
|
variant format!("facing={},in_wall={},open={}", facing.as_string(), in_wall, open),
|
||||||
collision fence_gate_collision(facing, in_wall, open),
|
collision fence_gate_collision(facing, in_wall, open),
|
||||||
update_state (world, pos) => Block::FenceGate{
|
update_state (world, pos) => Block::FenceGate{
|
||||||
facing: facing,
|
facing,
|
||||||
in_wall: fence_gate_update_state(world, pos, facing),
|
in_wall: fence_gate_update_state(world, pos, facing),
|
||||||
open: open,
|
open,
|
||||||
powered: powered
|
powered
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
BrickStairs {
|
BrickStairs {
|
||||||
|
@ -2930,14 +2932,14 @@ define_blocks! {
|
||||||
};
|
};
|
||||||
|
|
||||||
Tripwire{
|
Tripwire{
|
||||||
powered: powered,
|
powered,
|
||||||
attached: attached,
|
attached,
|
||||||
disarmed: disarmed,
|
disarmed,
|
||||||
north: f(Direction::North),
|
north: f(Direction::North),
|
||||||
south: f(Direction::South),
|
south: f(Direction::South),
|
||||||
west: f(Direction::West),
|
west: f(Direction::West),
|
||||||
east: f(Direction::East),
|
east: f(Direction::East),
|
||||||
mojang_cant_even: mojang_cant_even
|
mojang_cant_even
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -4206,10 +4208,10 @@ define_blocks! {
|
||||||
variant format!("facing={},in_wall={},open={}", facing.as_string(), in_wall, open),
|
variant format!("facing={},in_wall={},open={}", facing.as_string(), in_wall, open),
|
||||||
collision fence_gate_collision(facing, in_wall, open),
|
collision fence_gate_collision(facing, in_wall, open),
|
||||||
update_state (world, pos) => Block::SpruceFenceGate{
|
update_state (world, pos) => Block::SpruceFenceGate{
|
||||||
facing: facing,
|
facing,
|
||||||
in_wall: fence_gate_update_state(world, pos, facing),
|
in_wall: fence_gate_update_state(world, pos, facing),
|
||||||
open: open,
|
open,
|
||||||
powered: powered
|
powered
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
BirchFenceGate {
|
BirchFenceGate {
|
||||||
|
@ -4231,10 +4233,10 @@ define_blocks! {
|
||||||
variant format!("facing={},in_wall={},open={}", facing.as_string(), in_wall, open),
|
variant format!("facing={},in_wall={},open={}", facing.as_string(), in_wall, open),
|
||||||
collision fence_gate_collision(facing, in_wall, open),
|
collision fence_gate_collision(facing, in_wall, open),
|
||||||
update_state (world, pos) => Block::BirchFenceGate{
|
update_state (world, pos) => Block::BirchFenceGate{
|
||||||
facing: facing,
|
facing,
|
||||||
in_wall: fence_gate_update_state(world, pos, facing),
|
in_wall: fence_gate_update_state(world, pos, facing),
|
||||||
open: open,
|
open,
|
||||||
powered: powered
|
powered
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
JungleFenceGate {
|
JungleFenceGate {
|
||||||
|
@ -4256,10 +4258,10 @@ define_blocks! {
|
||||||
variant format!("facing={},in_wall={},open={}", facing.as_string(), in_wall, open),
|
variant format!("facing={},in_wall={},open={}", facing.as_string(), in_wall, open),
|
||||||
collision fence_gate_collision(facing, in_wall, open),
|
collision fence_gate_collision(facing, in_wall, open),
|
||||||
update_state (world, pos) => Block::JungleFenceGate{
|
update_state (world, pos) => Block::JungleFenceGate{
|
||||||
facing: facing,
|
facing,
|
||||||
in_wall: fence_gate_update_state(world, pos, facing),
|
in_wall: fence_gate_update_state(world, pos, facing),
|
||||||
open: open,
|
open,
|
||||||
powered: powered
|
powered
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
DarkOakFenceGate {
|
DarkOakFenceGate {
|
||||||
|
@ -4281,10 +4283,10 @@ define_blocks! {
|
||||||
variant format!("facing={},in_wall={},open={}", facing.as_string(), in_wall, open),
|
variant format!("facing={},in_wall={},open={}", facing.as_string(), in_wall, open),
|
||||||
collision fence_gate_collision(facing, in_wall, open),
|
collision fence_gate_collision(facing, in_wall, open),
|
||||||
update_state (world, pos) => Block::DarkOakFenceGate{
|
update_state (world, pos) => Block::DarkOakFenceGate{
|
||||||
facing: facing,
|
facing,
|
||||||
in_wall: fence_gate_update_state(world, pos, facing),
|
in_wall: fence_gate_update_state(world, pos, facing),
|
||||||
open: open,
|
open,
|
||||||
powered: powered
|
powered
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
AcaciaFenceGate {
|
AcaciaFenceGate {
|
||||||
|
@ -4306,10 +4308,10 @@ define_blocks! {
|
||||||
variant format!("facing={},in_wall={},open={}", facing.as_string(), in_wall, open),
|
variant format!("facing={},in_wall={},open={}", facing.as_string(), in_wall, open),
|
||||||
collision fence_gate_collision(facing, in_wall, open),
|
collision fence_gate_collision(facing, in_wall, open),
|
||||||
update_state (world, pos) => Block::AcaciaFenceGate{
|
update_state (world, pos) => Block::AcaciaFenceGate{
|
||||||
facing: facing,
|
facing,
|
||||||
in_wall: fence_gate_update_state(world, pos, facing),
|
in_wall: fence_gate_update_state(world, pos, facing),
|
||||||
open: open,
|
open,
|
||||||
powered: powered
|
powered
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
SpruceFence {
|
SpruceFence {
|
||||||
|
@ -4478,7 +4480,7 @@ define_blocks! {
|
||||||
collision door_collision(facing, hinge, open),
|
collision door_collision(facing, hinge, open),
|
||||||
update_state (world, pos) => {
|
update_state (world, pos) => {
|
||||||
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
||||||
Block::SpruceDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
|
Block::SpruceDoor{facing, half, hinge, open, powered}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
BirchDoor {
|
BirchDoor {
|
||||||
|
@ -4502,7 +4504,7 @@ define_blocks! {
|
||||||
collision door_collision(facing, hinge, open),
|
collision door_collision(facing, hinge, open),
|
||||||
update_state (world, pos) => {
|
update_state (world, pos) => {
|
||||||
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
||||||
Block::BirchDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
|
Block::BirchDoor{facing, half, hinge, open, powered}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
JungleDoor {
|
JungleDoor {
|
||||||
|
@ -4526,7 +4528,7 @@ define_blocks! {
|
||||||
collision door_collision(facing, hinge, open),
|
collision door_collision(facing, hinge, open),
|
||||||
update_state (world, pos) => {
|
update_state (world, pos) => {
|
||||||
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
||||||
Block::JungleDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
|
Block::JungleDoor{facing, half, hinge, open, powered}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
AcaciaDoor {
|
AcaciaDoor {
|
||||||
|
@ -4550,7 +4552,7 @@ define_blocks! {
|
||||||
collision door_collision(facing, hinge, open),
|
collision door_collision(facing, hinge, open),
|
||||||
update_state (world, pos) => {
|
update_state (world, pos) => {
|
||||||
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
||||||
Block::AcaciaDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
|
Block::AcaciaDoor{facing, half, hinge, open, powered}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
DarkOakDoor {
|
DarkOakDoor {
|
||||||
|
@ -4574,7 +4576,7 @@ define_blocks! {
|
||||||
collision door_collision(facing, hinge, open),
|
collision door_collision(facing, hinge, open),
|
||||||
update_state (world, pos) => {
|
update_state (world, pos) => {
|
||||||
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
|
||||||
Block::DarkOakDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
|
Block::DarkOakDoor{facing, half, hinge, open, powered}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
EndRod {
|
EndRod {
|
||||||
|
@ -7264,7 +7266,7 @@ impl TreeVariant {
|
||||||
TreeVariant::Spruce | TreeVariant::DarkOak => 1,
|
TreeVariant::Spruce | TreeVariant::DarkOak => 1,
|
||||||
TreeVariant::Birch => 2,
|
TreeVariant::Birch => 2,
|
||||||
TreeVariant::Jungle => 3,
|
TreeVariant::Jungle => 3,
|
||||||
_ => panic!("TreeVariant {:?} has no data (1.13+ only)"),
|
_ => panic!("TreeVariant {:?} has no data (1.13+ only)", self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7293,7 +7295,7 @@ impl TreeVariant {
|
||||||
TreeVariant::Jungle => 3,
|
TreeVariant::Jungle => 3,
|
||||||
TreeVariant::Acacia => 4,
|
TreeVariant::Acacia => 4,
|
||||||
TreeVariant::DarkOak => 5,
|
TreeVariant::DarkOak => 5,
|
||||||
_ => panic!("TreeVariant {:?} has no plank data (1.13+ only)"),
|
_ => panic!("TreeVariant {:?} has no plank data (1.13+ only)", self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
|
#![allow(clippy::unused_unit)]
|
||||||
|
#![allow(clippy::missing_safety_doc)]
|
||||||
|
#![allow(clippy::too_many_arguments)]
|
||||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use serde_json;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
@ -96,14 +95,14 @@ pub struct Modifier {
|
||||||
impl Modifier {
|
impl Modifier {
|
||||||
pub fn from_value(v: &serde_json::Value) -> Self {
|
pub fn from_value(v: &serde_json::Value) -> Self {
|
||||||
let mut m = Modifier {
|
let mut m = Modifier {
|
||||||
bold: v.get("bold").map_or(Option::None, |v| v.as_bool()),
|
bold: v.get("bold").and_then(|v| v.as_bool()),
|
||||||
italic: v.get("italic").map_or(Option::None, |v| v.as_bool()),
|
italic: v.get("italic").and_then(|v| v.as_bool()),
|
||||||
underlined: v.get("underlined").map_or(Option::None, |v| v.as_bool()),
|
underlined: v.get("underlined").and_then(|v| v.as_bool()),
|
||||||
strikethrough: v.get("strikethrough").map_or(Option::None, |v| v.as_bool()),
|
strikethrough: v.get("strikethrough").and_then(|v| v.as_bool()),
|
||||||
obfuscated: v.get("obfuscated").map_or(Option::None, |v| v.as_bool()),
|
obfuscated: v.get("obfuscated").and_then(|v| v.as_bool()),
|
||||||
color: v
|
color: v
|
||||||
.get("color")
|
.get("color")
|
||||||
.map_or(Option::None, |v| v.as_str())
|
.and_then(|v| v.as_str())
|
||||||
.map(|v| Color::from_string(&v.to_owned())),
|
.map(|v| Color::from_string(&v.to_owned())),
|
||||||
extra: Option::None,
|
extra: Option::None,
|
||||||
};
|
};
|
||||||
|
@ -246,7 +245,8 @@ impl Color {
|
||||||
};
|
};
|
||||||
Color::RGB(r, g, b)
|
Color::RGB(r, g, b)
|
||||||
}
|
}
|
||||||
"white" | _ => Color::White,
|
"white" => Color::White,
|
||||||
|
_ => Color::White,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,8 +84,8 @@ impl Serializable for ModIdMapping {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static BLOCK_NAMESPACE: &'static str = "\u{1}";
|
pub static BLOCK_NAMESPACE: &str = "\u{1}";
|
||||||
pub static ITEM_NAMESPACE: &'static str = "\u{2}";
|
pub static ITEM_NAMESPACE: &str = "\u{2}";
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum FmlHs {
|
pub enum FmlHs {
|
||||||
|
|
|
@ -18,10 +18,7 @@
|
||||||
use aes::Aes128;
|
use aes::Aes128;
|
||||||
use cfb8::stream_cipher::{NewStreamCipher, StreamCipher};
|
use cfb8::stream_cipher::{NewStreamCipher, StreamCipher};
|
||||||
use cfb8::Cfb8;
|
use cfb8::Cfb8;
|
||||||
use hex;
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use reqwest;
|
|
||||||
use serde_json;
|
|
||||||
use std_or_web::fs;
|
use std_or_web::fs;
|
||||||
|
|
||||||
pub mod forge;
|
pub mod forge;
|
||||||
|
@ -422,11 +419,21 @@ impl Serializable for f64 {
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||||
pub struct UUID(u64, u64);
|
pub struct UUID(u64, u64);
|
||||||
|
|
||||||
impl UUID {
|
#[derive(Debug)]
|
||||||
pub fn from_str(s: &str) -> UUID {
|
pub struct UUIDParseError;
|
||||||
// TODO: Panics aren't the best idea here
|
impl std::error::Error for UUIDParseError {}
|
||||||
|
|
||||||
|
impl fmt::Display for UUIDParseError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "Invalid UUID format")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for UUID {
|
||||||
|
type Err = UUIDParseError;
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
if s.len() != 36 {
|
if s.len() != 36 {
|
||||||
panic!("Invalid UUID format");
|
return Err(UUIDParseError {});
|
||||||
}
|
}
|
||||||
let mut parts = hex::decode(&s[..8]).unwrap();
|
let mut parts = hex::decode(&s[..8]).unwrap();
|
||||||
parts.extend_from_slice(&hex::decode(&s[9..13]).unwrap());
|
parts.extend_from_slice(&hex::decode(&s[9..13]).unwrap());
|
||||||
|
@ -439,7 +446,7 @@ impl UUID {
|
||||||
high |= (parts[i] as u64) << (56 - i * 8);
|
high |= (parts[i] as u64) << (56 - i * 8);
|
||||||
low |= (parts[i + 8] as u64) << (56 - i * 8);
|
low |= (parts[i + 8] as u64) << (56 - i * 8);
|
||||||
}
|
}
|
||||||
UUID(high, low)
|
Ok(UUID(high, low))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,12 +492,12 @@ impl Default for Biomes3D {
|
||||||
|
|
||||||
impl Serializable for Biomes3D {
|
impl Serializable for Biomes3D {
|
||||||
fn read_from<R: io::Read>(buf: &mut R) -> Result<Biomes3D, Error> {
|
fn read_from<R: io::Read>(buf: &mut R) -> Result<Biomes3D, Error> {
|
||||||
let mut data: [i32; 1024] = [0; 1024];
|
let data: [i32; 1024] = [0; 1024];
|
||||||
|
|
||||||
// Non-length-prefixed three-dimensional biome data
|
// Non-length-prefixed three-dimensional biome data
|
||||||
for i in 0..1024 {
|
for item in &mut data.to_vec() {
|
||||||
let b: i32 = Serializable::read_from(buf)?;
|
let b: i32 = Serializable::read_from(buf)?;
|
||||||
data[i] = b;
|
*item = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result::Ok(Biomes3D { data })
|
Result::Ok(Biomes3D { data })
|
||||||
|
@ -1211,8 +1218,8 @@ impl Conn {
|
||||||
|
|
||||||
let invalid_status = || Error::Err("Invalid status".to_owned());
|
let invalid_status = || Error::Err("Invalid status".to_owned());
|
||||||
|
|
||||||
let version = val.get("version").ok_or(invalid_status())?;
|
let version = val.get("version").ok_or_else(invalid_status)?;
|
||||||
let players = val.get("players").ok_or(invalid_status())?;
|
let players = val.get("players").ok_or_else(invalid_status)?;
|
||||||
|
|
||||||
// For modded servers, get the list of Forge mods installed
|
// For modded servers, get the list of Forge mods installed
|
||||||
let mut forge_mods: std::vec::Vec<crate::protocol::forge::ForgeMod> = vec![];
|
let mut forge_mods: std::vec::Vec<crate::protocol::forge::ForgeMod> = vec![];
|
||||||
|
@ -1267,26 +1274,26 @@ impl Conn {
|
||||||
name: version
|
name: version
|
||||||
.get("name")
|
.get("name")
|
||||||
.and_then(Value::as_str)
|
.and_then(Value::as_str)
|
||||||
.ok_or(invalid_status())?
|
.ok_or_else(invalid_status)?
|
||||||
.to_owned(),
|
.to_owned(),
|
||||||
protocol: version
|
protocol: version
|
||||||
.get("protocol")
|
.get("protocol")
|
||||||
.and_then(Value::as_i64)
|
.and_then(Value::as_i64)
|
||||||
.ok_or(invalid_status())? as i32,
|
.ok_or_else(invalid_status)? as i32,
|
||||||
},
|
},
|
||||||
players: StatusPlayers {
|
players: StatusPlayers {
|
||||||
max: players
|
max: players
|
||||||
.get("max")
|
.get("max")
|
||||||
.and_then(Value::as_i64)
|
.and_then(Value::as_i64)
|
||||||
.ok_or(invalid_status())? as i32,
|
.ok_or_else(invalid_status)? as i32,
|
||||||
online: players
|
online: players
|
||||||
.get("online")
|
.get("online")
|
||||||
.and_then(Value::as_i64)
|
.and_then(Value::as_i64)
|
||||||
.ok_or(invalid_status())? as i32,
|
.ok_or_else(invalid_status)? as i32,
|
||||||
sample: Vec::new(), /* TODO */
|
sample: Vec::new(), /* TODO */
|
||||||
},
|
},
|
||||||
description: format::Component::from_value(
|
description: format::Component::from_value(
|
||||||
val.get("description").ok_or(invalid_status())?,
|
val.get("description").ok_or_else(invalid_status)?,
|
||||||
),
|
),
|
||||||
favicon: val
|
favicon: val
|
||||||
.get("favicon")
|
.get("favicon")
|
||||||
|
@ -1346,11 +1353,8 @@ impl Write for Conn {
|
||||||
match self.cipher.as_mut() {
|
match self.cipher.as_mut() {
|
||||||
Option::None => self.stream.write(buf),
|
Option::None => self.stream.write(buf),
|
||||||
Option::Some(cipher) => {
|
Option::Some(cipher) => {
|
||||||
// TODO: avoid copying, but trait requires non-mutable buf
|
|
||||||
let mut data = vec![0; buf.len()];
|
let mut data = vec![0; buf.len()];
|
||||||
for i in 0..buf.len() {
|
data[..buf.len()].clone_from_slice(&buf[..]);
|
||||||
data[i] = buf[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
cipher.encrypt(&mut data);
|
cipher.encrypt(&mut data);
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use reqwest;
|
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use sha1::{self, Digest};
|
use sha1::{self, Digest};
|
||||||
|
|
||||||
|
@ -78,7 +77,7 @@ impl Profile {
|
||||||
|
|
||||||
pub fn refresh(self, token: &str) -> Result<Profile, super::Error> {
|
pub fn refresh(self, token: &str) -> Result<Profile, super::Error> {
|
||||||
let req_msg = json!({
|
let req_msg = json!({
|
||||||
"accessToken": self.access_token.clone(),
|
"accessToken": self.access_token,
|
||||||
"clientToken": token
|
"clientToken": token
|
||||||
});
|
});
|
||||||
let req = serde_json::to_string(&req_msg)?;
|
let req = serde_json::to_string(&req_msg)?;
|
||||||
|
|
|
@ -2569,7 +2569,7 @@ impl Serializable for PlayerInfoData {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
4 => m.players.push(PlayerDetail::Remove { uuid: uuid }),
|
4 => m.players.push(PlayerDetail::Remove { uuid }),
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,8 @@ impl Gamemode {
|
||||||
3 => Gamemode::Spectator,
|
3 => Gamemode::Spectator,
|
||||||
2 => Gamemode::Adventure,
|
2 => Gamemode::Adventure,
|
||||||
1 => Gamemode::Creative,
|
1 => Gamemode::Creative,
|
||||||
0 | _ => Gamemode::Survival,
|
0 => Gamemode::Survival,
|
||||||
|
_ => Gamemode::Survival,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,12 @@ fn main() {
|
||||||
build_map(&mut out, &base);
|
build_map(&mut out, &base);
|
||||||
|
|
||||||
let mut file = BufWriter::new(fs::File::create(&dest.join("resources.rs")).unwrap());
|
let mut file = BufWriter::new(fs::File::create(&dest.join("resources.rs")).unwrap());
|
||||||
write!(
|
writeln!(
|
||||||
file,
|
file,
|
||||||
"pub fn get_file(name: &str) -> Option<&'static [u8]> {{\n"
|
"pub fn get_file(name: &str) -> Option<&'static [u8]> {{"
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
write!(file, " match name {{\n").unwrap();
|
writeln!(file, " match name {{").unwrap();
|
||||||
for path in &out {
|
for path in &out {
|
||||||
let mut absolute_path = std::env::current_dir().unwrap();
|
let mut absolute_path = std::env::current_dir().unwrap();
|
||||||
absolute_path.push(path);
|
absolute_path.push(path);
|
||||||
|
@ -26,9 +26,9 @@ fn main() {
|
||||||
let absolute = absolute_path.to_str().unwrap().replace("\\", "/");
|
let absolute = absolute_path.to_str().unwrap().replace("\\", "/");
|
||||||
let relative = path.to_str().unwrap().replace("\\", "/");
|
let relative = path.to_str().unwrap().replace("\\", "/");
|
||||||
|
|
||||||
write!(
|
writeln!(
|
||||||
file,
|
file,
|
||||||
" {:?} => Some(include_bytes!(\"{}\")),\n",
|
" {:?} => Some(include_bytes!(\"{}\")),",
|
||||||
relative, absolute
|
relative, absolute
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -6,7 +6,6 @@ use crate::types::bit::Set;
|
||||||
use crate::world;
|
use crate::world;
|
||||||
use crate::world::block;
|
use crate::world::block;
|
||||||
use rand::{self, Rng, SeedableRng};
|
use rand::{self, Rng, SeedableRng};
|
||||||
use rand_pcg;
|
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
@ -27,10 +26,7 @@ impl ChunkBuilder {
|
||||||
resources: Arc<RwLock<resources::Manager>>,
|
resources: Arc<RwLock<resources::Manager>>,
|
||||||
textures: Arc<RwLock<render::TextureManager>>,
|
textures: Arc<RwLock<render::TextureManager>>,
|
||||||
) -> ChunkBuilder {
|
) -> ChunkBuilder {
|
||||||
let models = Arc::new(RwLock::new(model::Factory::new(
|
let models = Arc::new(RwLock::new(model::Factory::new(resources, textures)));
|
||||||
resources.clone(),
|
|
||||||
textures,
|
|
||||||
)));
|
|
||||||
|
|
||||||
let mut threads = vec![];
|
let mut threads = vec![];
|
||||||
let mut free = vec![];
|
let mut free = vec![];
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use log;
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::cell::{Ref, RefCell};
|
use std::cell::{Ref, RefCell};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -191,7 +190,7 @@ impl Vars {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for line in var.description().lines() {
|
for line in var.description().lines() {
|
||||||
write!(file, "# {}\n", line).unwrap();
|
writeln!(file, "# {}", line).unwrap();
|
||||||
}
|
}
|
||||||
write!(
|
write!(
|
||||||
file,
|
file,
|
||||||
|
@ -204,6 +203,7 @@ impl Vars {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Console {
|
pub struct Console {
|
||||||
history: Vec<Component>,
|
history: Vec<Component>,
|
||||||
dirty: bool,
|
dirty: bool,
|
||||||
|
|
|
@ -53,6 +53,12 @@ pub struct Filter {
|
||||||
bits: BSet,
|
bits: BSet,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Filter {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Filter {
|
impl Filter {
|
||||||
/// Creates an empty filter which matches everything
|
/// Creates an empty filter which matches everything
|
||||||
pub fn new() -> Filter {
|
pub fn new() -> Filter {
|
||||||
|
@ -106,6 +112,7 @@ struct EntityState {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stores and manages a collection of entities.
|
/// Stores and manages a collection of entities.
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Manager {
|
pub struct Manager {
|
||||||
num_components: usize,
|
num_components: usize,
|
||||||
entities: Vec<(Option<EntityState>, u32)>,
|
entities: Vec<(Option<EntityState>, u32)>,
|
||||||
|
@ -619,7 +626,7 @@ impl ComponentMem {
|
||||||
data.2 += 1;
|
data.2 += 1;
|
||||||
data.1.set(rem, true);
|
data.1.set(rem, true);
|
||||||
unsafe {
|
unsafe {
|
||||||
ptr::write(data.0.as_mut_ptr().offset(start as isize) as *mut T, val);
|
ptr::write(data.0.as_mut_ptr().add(start) as *mut T, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -635,7 +642,7 @@ impl ComponentMem {
|
||||||
// we use the drop_func which stores the type in its closure
|
// we use the drop_func which stores the type in its closure
|
||||||
// to handle the dropping for us.
|
// to handle the dropping for us.
|
||||||
unsafe {
|
unsafe {
|
||||||
(self.drop_func)(data.0.as_mut_ptr().offset(start as isize));
|
(self.drop_func)(data.0.as_mut_ptr().add(start));
|
||||||
}
|
}
|
||||||
data.2 -= 1;
|
data.2 -= 1;
|
||||||
data.2
|
data.2
|
||||||
|
@ -650,7 +657,7 @@ impl ComponentMem {
|
||||||
let rem = index % COMPONENTS_PER_BLOCK;
|
let rem = index % COMPONENTS_PER_BLOCK;
|
||||||
let data = self.data[idx].as_ref().unwrap();
|
let data = self.data[idx].as_ref().unwrap();
|
||||||
let start = rem * self.component_size;
|
let start = rem * self.component_size;
|
||||||
unsafe { &*(data.0.as_ptr().offset(start as isize) as *const T) }
|
unsafe { &*(data.0.as_ptr().add(start) as *const T) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_mut<T>(&mut self, index: usize) -> &mut T {
|
fn get_mut<T>(&mut self, index: usize) -> &mut T {
|
||||||
|
@ -658,7 +665,7 @@ impl ComponentMem {
|
||||||
let rem = index % COMPONENTS_PER_BLOCK;
|
let rem = index % COMPONENTS_PER_BLOCK;
|
||||||
let data = self.data[idx].as_mut().unwrap();
|
let data = self.data[idx].as_mut().unwrap();
|
||||||
let start = rem * self.component_size;
|
let start = rem * self.component_size;
|
||||||
unsafe { &mut *(data.0.as_mut_ptr().offset(start as isize) as *mut T) }
|
unsafe { &mut *(data.0.as_mut_ptr().add(start) as *mut T) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,7 +677,7 @@ impl Drop for ComponentMem {
|
||||||
if data.1.get(i) {
|
if data.1.get(i) {
|
||||||
let start = i * self.component_size;
|
let start = i * self.component_size;
|
||||||
unsafe {
|
unsafe {
|
||||||
(self.drop_func)(data.0.as_mut_ptr().offset(start as isize));
|
(self.drop_func)(data.0.as_mut_ptr().add(start));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -640,7 +640,7 @@ impl ecs::System for MovementHandler {
|
||||||
if movement.is_key_pressed(Stevenkey::Jump) {
|
if movement.is_key_pressed(Stevenkey::Jump) {
|
||||||
if movement.when_last_jump_pressed.is_none() {
|
if movement.when_last_jump_pressed.is_none() {
|
||||||
movement.when_last_jump_pressed = Some(Instant::now());
|
movement.when_last_jump_pressed = Some(Instant::now());
|
||||||
if !movement.when_last_jump_released.is_none() {
|
if movement.when_last_jump_released.is_some() {
|
||||||
let dt = movement.when_last_jump_pressed.unwrap()
|
let dt = movement.when_last_jump_pressed.unwrap()
|
||||||
- movement.when_last_jump_released.unwrap();
|
- movement.when_last_jump_released.unwrap();
|
||||||
if dt.as_secs() == 0
|
if dt.as_secs() == 0
|
||||||
|
@ -655,7 +655,7 @@ impl ecs::System for MovementHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if !movement.when_last_jump_pressed.is_none() {
|
} else if movement.when_last_jump_pressed.is_some() {
|
||||||
movement.when_last_jump_released = Some(Instant::now());
|
movement.when_last_jump_released = Some(Instant::now());
|
||||||
movement.when_last_jump_pressed = None;
|
movement.when_last_jump_pressed = None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ impl ecs::System for ApplyVelocity {
|
||||||
}
|
}
|
||||||
let pos = m.get_component_mut(e, self.position).unwrap();
|
let pos = m.get_component_mut(e, self.position).unwrap();
|
||||||
let vel = m.get_component(e, self.velocity).unwrap();
|
let vel = m.get_component(e, self.velocity).unwrap();
|
||||||
pos.position = pos.position + vel.velocity;
|
pos.position += vel.velocity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,6 +264,7 @@ pub const NEAREST_MIPMAP_LINEAR: TextureValue = gl::NEAREST_MIPMAP_LINEAR as Tex
|
||||||
pub const CLAMP_TO_EDGE: TextureValue = gl::CLAMP_TO_EDGE as TextureValue;
|
pub const CLAMP_TO_EDGE: TextureValue = gl::CLAMP_TO_EDGE as TextureValue;
|
||||||
|
|
||||||
/// `Texture` is a buffer of data used by fragment shaders.
|
/// `Texture` is a buffer of data used by fragment shaders.
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Texture(u32);
|
pub struct Texture(u32);
|
||||||
|
|
||||||
impl Texture {
|
impl Texture {
|
||||||
|
@ -510,6 +511,7 @@ pub type ShaderParameter = u32;
|
||||||
pub const COMPILE_STATUS: ShaderParameter = gl::COMPILE_STATUS;
|
pub const COMPILE_STATUS: ShaderParameter = gl::COMPILE_STATUS;
|
||||||
pub const INFO_LOG_LENGTH: ShaderParameter = gl::INFO_LOG_LENGTH;
|
pub const INFO_LOG_LENGTH: ShaderParameter = gl::INFO_LOG_LENGTH;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Program(u32);
|
pub struct Program(u32);
|
||||||
|
|
||||||
impl Program {
|
impl Program {
|
||||||
|
@ -646,10 +648,9 @@ impl Uniform {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_float_mutli_raw(&self, data: *const f32, len: usize) {
|
#[allow(clippy::missing_safety_doc)]
|
||||||
unsafe {
|
pub unsafe fn set_float_multi_raw(&self, data: *const f32, len: usize) {
|
||||||
gl::Uniform4fv(self.0, len as i32, data);
|
gl::Uniform4fv(self.0, len as i32, data);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_matrix4(&self, m: &::cgmath::Matrix4<f32>) {
|
pub fn set_matrix4(&self, m: &::cgmath::Matrix4<f32>) {
|
||||||
|
@ -712,6 +713,7 @@ impl Attribute {
|
||||||
// VertexArray is used to store state needed to render vertices.
|
// VertexArray is used to store state needed to render vertices.
|
||||||
// This includes buffers, the format of the buffers and enabled
|
// This includes buffers, the format of the buffers and enabled
|
||||||
// attributes.
|
// attributes.
|
||||||
|
#[derive(Default)]
|
||||||
pub struct VertexArray(u32);
|
pub struct VertexArray(u32);
|
||||||
|
|
||||||
impl VertexArray {
|
impl VertexArray {
|
||||||
|
@ -772,6 +774,7 @@ pub const READ_ONLY: Access = gl::READ_ONLY;
|
||||||
pub const WRITE_ONLY: Access = gl::WRITE_ONLY;
|
pub const WRITE_ONLY: Access = gl::WRITE_ONLY;
|
||||||
|
|
||||||
/// `Buffer` is a storage for vertex data.
|
/// `Buffer` is a storage for vertex data.
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Buffer(u32);
|
pub struct Buffer(u32);
|
||||||
|
|
||||||
impl Buffer {
|
impl Buffer {
|
||||||
|
@ -871,6 +874,7 @@ pub const COLOR_ATTACHMENT_1: Attachment = gl::COLOR_ATTACHMENT1;
|
||||||
pub const COLOR_ATTACHMENT_2: Attachment = gl::COLOR_ATTACHMENT2;
|
pub const COLOR_ATTACHMENT_2: Attachment = gl::COLOR_ATTACHMENT2;
|
||||||
pub const DEPTH_ATTACHMENT: Attachment = gl::DEPTH_ATTACHMENT;
|
pub const DEPTH_ATTACHMENT: Attachment = gl::DEPTH_ATTACHMENT;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Framebuffer(u32);
|
pub struct Framebuffer(u32);
|
||||||
|
|
||||||
pub fn check_framebuffer_status() {
|
pub fn check_framebuffer_status() {
|
||||||
|
|
32
src/main.rs
32
src/main.rs
|
@ -13,6 +13,9 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#![recursion_limit = "300"]
|
#![recursion_limit = "300"]
|
||||||
|
#![allow(clippy::too_many_arguments)] // match standard gl functions with many arguments
|
||||||
|
#![allow(clippy::many_single_char_names)] // short variable names provide concise clarity
|
||||||
|
#![allow(clippy::float_cmp)] // float comparison used to check if changed
|
||||||
|
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
@ -43,7 +46,6 @@ pub mod world;
|
||||||
|
|
||||||
use crate::protocol::mojang;
|
use crate::protocol::mojang;
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use glutin;
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
@ -296,7 +298,8 @@ fn main2() {
|
||||||
let textures = renderer.get_textures();
|
let textures = renderer.get_textures();
|
||||||
let dpi_factor = window.window().scale_factor();
|
let dpi_factor = window.window().scale_factor();
|
||||||
let default_protocol_version = protocol::versions::protocol_name_to_protocol_version(
|
let default_protocol_version = protocol::versions::protocol_name_to_protocol_version(
|
||||||
opt.default_protocol_version.unwrap_or("".to_string()),
|
opt.default_protocol_version
|
||||||
|
.unwrap_or_else(|| "".to_string()),
|
||||||
);
|
);
|
||||||
let mut game = Game {
|
let mut game = Game {
|
||||||
server: server::Server::dummy_server(resource_manager.clone()),
|
server: server::Server::dummy_server(resource_manager.clone()),
|
||||||
|
@ -347,8 +350,7 @@ fn main2() {
|
||||||
|
|
||||||
let version = {
|
let version = {
|
||||||
let try_res = game.resource_manager.try_write();
|
let try_res = game.resource_manager.try_write();
|
||||||
if try_res.is_ok() {
|
if let Ok(mut res) = try_res {
|
||||||
let mut res = try_res.unwrap();
|
|
||||||
res.tick(&mut resui, &mut ui_container, delta);
|
res.tick(&mut resui, &mut ui_container, delta);
|
||||||
res.version()
|
res.version()
|
||||||
} else {
|
} else {
|
||||||
|
@ -508,18 +510,16 @@ fn handle_window_event<T>(
|
||||||
game.focused = true;
|
game.focused = true;
|
||||||
window.window().set_cursor_grab(true).unwrap();
|
window.window().set_cursor_grab(true).unwrap();
|
||||||
window.window().set_cursor_visible(false);
|
window.window().set_cursor_visible(false);
|
||||||
} else {
|
} else if !game.focused {
|
||||||
if !game.focused {
|
window.window().set_cursor_grab(false).unwrap();
|
||||||
window.window().set_cursor_grab(false).unwrap();
|
window.window().set_cursor_visible(true);
|
||||||
window.window().set_cursor_visible(true);
|
ui_container.click_at(
|
||||||
ui_container.click_at(
|
game,
|
||||||
game,
|
game.last_mouse_x,
|
||||||
game.last_mouse_x,
|
game.last_mouse_y,
|
||||||
game.last_mouse_y,
|
width,
|
||||||
width,
|
height,
|
||||||
height,
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(ElementState::Pressed, MouseButton::Right) => {
|
(ElementState::Pressed, MouseButton::Right) => {
|
||||||
|
|
|
@ -6,7 +6,6 @@ use crate::shared::Direction;
|
||||||
use crate::world;
|
use crate::world;
|
||||||
use crate::world::block::{Block, TintType};
|
use crate::world::block::{Block, TintType};
|
||||||
use byteorder::{NativeEndian, WriteBytesExt};
|
use byteorder::{NativeEndian, WriteBytesExt};
|
||||||
use serde_json;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
@ -892,7 +891,7 @@ impl RawModel {
|
||||||
.texture_vars
|
.texture_vars
|
||||||
.get(&name[1..])
|
.get(&name[1..])
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or("".to_owned());
|
.unwrap_or_else(|| "".to_owned());
|
||||||
return self.lookup_texture(&tex);
|
return self.lookup_texture(&tex);
|
||||||
}
|
}
|
||||||
name.to_owned()
|
name.to_owned()
|
||||||
|
|
|
@ -57,9 +57,7 @@ impl Atlas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if target.is_none() {
|
target?;
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let mut t = target.unwrap();
|
let mut t = target.unwrap();
|
||||||
let ret = Rect {
|
let ret = Rect {
|
||||||
x: t.x,
|
x: t.x,
|
||||||
|
|
|
@ -25,11 +25,8 @@ use crate::resources;
|
||||||
use crate::world;
|
use crate::world;
|
||||||
use byteorder::{NativeEndian, WriteBytesExt};
|
use byteorder::{NativeEndian, WriteBytesExt};
|
||||||
use cgmath::prelude::*;
|
use cgmath::prelude::*;
|
||||||
use collision;
|
|
||||||
use image;
|
|
||||||
use image::{GenericImage, GenericImageView};
|
use image::{GenericImage, GenericImageView};
|
||||||
use log::{error, trace};
|
use log::{error, trace};
|
||||||
use serde_json;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
@ -41,7 +38,6 @@ use std::sync::mpsc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use reqwest;
|
|
||||||
|
|
||||||
const ATLAS_SIZE: usize = 1024;
|
const ATLAS_SIZE: usize = 1024;
|
||||||
|
|
||||||
|
@ -959,6 +955,8 @@ pub struct TextureManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextureManager {
|
impl TextureManager {
|
||||||
|
#[allow(clippy::let_and_return)]
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
fn new(
|
fn new(
|
||||||
res: Arc<RwLock<resources::Manager>>,
|
res: Arc<RwLock<resources::Manager>>,
|
||||||
) -> (
|
) -> (
|
||||||
|
@ -972,6 +970,7 @@ impl TextureManager {
|
||||||
let mut tm = TextureManager {
|
let mut tm = TextureManager {
|
||||||
textures: HashMap::with_hasher(BuildHasherDefault::default()),
|
textures: HashMap::with_hasher(BuildHasherDefault::default()),
|
||||||
version: {
|
version: {
|
||||||
|
// TODO: fix borrow and remove clippy::let_and_return above
|
||||||
let ver = res.read().unwrap().version();
|
let ver = res.read().unwrap().version();
|
||||||
ver
|
ver
|
||||||
},
|
},
|
||||||
|
@ -1222,7 +1221,7 @@ impl TextureManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_texture(&self, name: &str) -> Option<Texture> {
|
fn get_texture(&self, name: &str) -> Option<Texture> {
|
||||||
if let Some(_) = name.find(':') {
|
if name.find(':').is_some() {
|
||||||
self.textures.get(name).cloned()
|
self.textures.get(name).cloned()
|
||||||
} else {
|
} else {
|
||||||
self.textures.get(&format!("minecraft:{}", name)).cloned()
|
self.textures.get(&format!("minecraft:{}", name)).cloned()
|
||||||
|
@ -1390,7 +1389,7 @@ impl TextureManager {
|
||||||
rel_height: 1.0,
|
rel_height: 1.0,
|
||||||
is_rel: false,
|
is_rel: false,
|
||||||
};
|
};
|
||||||
self.textures.insert(full_name.to_owned(), t.clone());
|
self.textures.insert(full_name, t.clone());
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1425,8 +1424,7 @@ impl TextureManager {
|
||||||
(height as f32) / (tex.height as f32),
|
(height as f32) / (tex.height as f32),
|
||||||
);
|
);
|
||||||
let old_name = mem::replace(&mut tex.name, format!("steven-dynamic:{}", name));
|
let old_name = mem::replace(&mut tex.name, format!("steven-dynamic:{}", name));
|
||||||
self.dynamic_textures
|
self.dynamic_textures.insert(name.to_owned(), (tex, img));
|
||||||
.insert(name.to_owned(), (tex.clone(), img));
|
|
||||||
// We need to rename the texture itself so that get_texture calls
|
// We need to rename the texture itself so that get_texture calls
|
||||||
// work with the new name
|
// work with the new name
|
||||||
let mut old = self.textures.remove(&old_name).unwrap();
|
let mut old = self.textures.remove(&old_name).unwrap();
|
||||||
|
|
|
@ -86,31 +86,36 @@ impl Manager {
|
||||||
let mut model = {
|
let mut model = {
|
||||||
let collection = &mut self.collections[ckey.0];
|
let collection = &mut self.collections[ckey.0];
|
||||||
collection.shader.program.use_program();
|
collection.shader.program.use_program();
|
||||||
collection.shader.position.map(|v| v.enable());
|
if let Some(v) = collection.shader.position {
|
||||||
collection.shader.texture_info.map(|v| v.enable());
|
v.enable()
|
||||||
collection.shader.texture_offset.map(|v| v.enable());
|
}
|
||||||
collection.shader.color.map(|v| v.enable());
|
if let Some(v) = collection.shader.texture_info {
|
||||||
collection.shader.id.map(|v| v.enable());
|
v.enable()
|
||||||
collection
|
}
|
||||||
.shader
|
if let Some(v) = collection.shader.texture_offset {
|
||||||
.position
|
v.enable()
|
||||||
.map(|v| v.vertex_pointer(3, gl::FLOAT, false, 36, 0));
|
}
|
||||||
collection
|
if let Some(v) = collection.shader.color {
|
||||||
.shader
|
v.enable()
|
||||||
.texture_info
|
}
|
||||||
.map(|v| v.vertex_pointer(4, gl::UNSIGNED_SHORT, false, 36, 12));
|
if let Some(v) = collection.shader.id {
|
||||||
collection
|
v.enable()
|
||||||
.shader
|
}
|
||||||
.texture_offset
|
if let Some(v) = collection.shader.position {
|
||||||
.map(|v| v.vertex_pointer_int(3, gl::SHORT, 36, 20));
|
v.vertex_pointer(3, gl::FLOAT, false, 36, 0)
|
||||||
collection
|
}
|
||||||
.shader
|
if let Some(v) = collection.shader.texture_info {
|
||||||
.color
|
v.vertex_pointer(4, gl::UNSIGNED_SHORT, false, 36, 12)
|
||||||
.map(|v| v.vertex_pointer(4, gl::UNSIGNED_BYTE, true, 36, 28));
|
}
|
||||||
collection
|
if let Some(v) = collection.shader.texture_offset {
|
||||||
.shader
|
v.vertex_pointer_int(3, gl::SHORT, 36, 20)
|
||||||
.id
|
}
|
||||||
.map(|v| v.vertex_pointer_int(1, gl::UNSIGNED_BYTE, 36, 32));
|
if let Some(v) = collection.shader.color {
|
||||||
|
v.vertex_pointer(4, gl::UNSIGNED_BYTE, true, 36, 28)
|
||||||
|
}
|
||||||
|
if let Some(v) = collection.shader.id {
|
||||||
|
v.vertex_pointer_int(1, gl::UNSIGNED_BYTE, 36, 32)
|
||||||
|
}
|
||||||
|
|
||||||
let mut model = Model {
|
let mut model = Model {
|
||||||
// For culling only
|
// For culling only
|
||||||
|
@ -214,7 +219,7 @@ impl Manager {
|
||||||
textures: &Arc<RwLock<super::TextureManager>>,
|
textures: &Arc<RwLock<super::TextureManager>>,
|
||||||
) {
|
) {
|
||||||
for collection in &mut self.collections {
|
for collection in &mut self.collections {
|
||||||
for (_, model) in &mut collection.models {
|
for model in collection.models.values_mut() {
|
||||||
for vert in &mut model.verts {
|
for vert in &mut model.verts {
|
||||||
vert.texture = if vert.texture.version == version {
|
vert.texture = if vert.texture.version == version {
|
||||||
vert.texture.clone()
|
vert.texture.clone()
|
||||||
|
@ -244,23 +249,21 @@ impl Manager {
|
||||||
gl::enable(gl::BLEND);
|
gl::enable(gl::BLEND);
|
||||||
for collection in &self.collections {
|
for collection in &self.collections {
|
||||||
collection.shader.program.use_program();
|
collection.shader.program.use_program();
|
||||||
collection
|
if let Some(v) = collection.shader.perspective_matrix {
|
||||||
.shader
|
v.set_matrix4(perspective_matrix)
|
||||||
.perspective_matrix
|
}
|
||||||
.map(|v| v.set_matrix4(perspective_matrix));
|
if let Some(v) = collection.shader.camera_matrix {
|
||||||
collection
|
v.set_matrix4(camera_matrix)
|
||||||
.shader
|
}
|
||||||
.camera_matrix
|
if let Some(v) = collection.shader.texture {
|
||||||
.map(|v| v.set_matrix4(camera_matrix));
|
v.set_int(0)
|
||||||
collection.shader.texture.map(|v| v.set_int(0));
|
}
|
||||||
collection
|
if let Some(v) = collection.shader.sky_offset {
|
||||||
.shader
|
v.set_float(sky_offset)
|
||||||
.sky_offset
|
}
|
||||||
.map(|v| v.set_float(sky_offset));
|
if let Some(v) = collection.shader.light_level {
|
||||||
collection
|
v.set_float(light_level)
|
||||||
.shader
|
}
|
||||||
.light_level
|
|
||||||
.map(|v| v.set_float(light_level));
|
|
||||||
gl::blend_func(collection.blend_s, collection.blend_d);
|
gl::blend_func(collection.blend_s, collection.blend_d);
|
||||||
|
|
||||||
for model in collection.models.values() {
|
for model in collection.models.values() {
|
||||||
|
@ -273,17 +276,17 @@ impl Manager {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
model.array.bind();
|
model.array.bind();
|
||||||
collection
|
if let Some(v) = collection.shader.lighting {
|
||||||
.shader
|
v.set_float2(model.block_light, model.sky_light)
|
||||||
.lighting
|
}
|
||||||
.map(|v| v.set_float2(model.block_light, model.sky_light));
|
if let Some(v) = collection.shader.model_matrix {
|
||||||
collection
|
v.set_matrix4_multi(&model.matrix)
|
||||||
.shader
|
}
|
||||||
.model_matrix
|
if let Some(v) = collection.shader.color_mul {
|
||||||
.map(|v| v.set_matrix4_multi(&model.matrix));
|
unsafe {
|
||||||
collection.shader.color_mul.map(|v| {
|
v.set_float_multi_raw(model.colors.as_ptr() as *const _, model.colors.len())
|
||||||
v.set_float_mutli_raw(model.colors.as_ptr() as *const _, model.colors.len())
|
}
|
||||||
});
|
}
|
||||||
gl::draw_elements(gl::TRIANGLES, model.count, self.index_type, 0);
|
gl::draw_elements(gl::TRIANGLES, model.count, self.index_type, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ use crate::render::glsl;
|
||||||
use crate::render::shaders;
|
use crate::render::shaders;
|
||||||
use crate::resources;
|
use crate::resources;
|
||||||
use byteorder::{NativeEndian, WriteBytesExt};
|
use byteorder::{NativeEndian, WriteBytesExt};
|
||||||
use image;
|
|
||||||
use image::GenericImageView;
|
use image::GenericImageView;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
extern crate steven_resources as internal;
|
extern crate steven_resources as internal;
|
||||||
|
|
||||||
use serde_json;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::hash::BuildHasherDefault;
|
use std::hash::BuildHasherDefault;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
@ -24,10 +23,6 @@ use std::sync::{Arc, Mutex};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std_or_web::fs;
|
use std_or_web::fs;
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
use reqwest;
|
|
||||||
use zip;
|
|
||||||
|
|
||||||
use crate::types::hash::FNVHash;
|
use crate::types::hash::FNVHash;
|
||||||
use crate::ui;
|
use crate::ui;
|
||||||
|
|
||||||
|
@ -136,7 +131,7 @@ impl Manager {
|
||||||
// (if it was started)
|
// (if it was started)
|
||||||
let mut done = false;
|
let mut done = false;
|
||||||
if let Some(ref recv) = self.vanilla_chan {
|
if let Some(ref recv) = self.vanilla_chan {
|
||||||
if let Ok(_) = recv.try_recv() {
|
if recv.try_recv().is_ok() {
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,7 +141,7 @@ impl Manager {
|
||||||
}
|
}
|
||||||
let mut done = false;
|
let mut done = false;
|
||||||
if let Some(ref recv) = self.vanilla_assets_chan {
|
if let Some(ref recv) = self.vanilla_assets_chan {
|
||||||
if let Ok(_) = recv.try_recv() {
|
if recv.try_recv().is_ok() {
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,11 +230,11 @@ impl Manager {
|
||||||
prog = task.progress as f64 / task.total as f64;
|
prog = task.progress as f64 / task.total as f64;
|
||||||
}
|
}
|
||||||
let background = ui.background.borrow();
|
let background = ui.background.borrow();
|
||||||
let bar = ui.progress_bar.borrow();
|
let progress_bar = ui.progress_bar.borrow();
|
||||||
// Let the progress bar finish
|
// Let the progress bar finish
|
||||||
if !found
|
if !found
|
||||||
&& (background.y - ui.position).abs() < 0.7 * delta
|
&& (background.y - ui.position).abs() < 0.7 * delta
|
||||||
&& (bar.width - 350.0).abs() < 1.0 * delta
|
&& (progress_bar.width - 350.0).abs() < 1.0 * delta
|
||||||
{
|
{
|
||||||
ui.closing = true;
|
ui.closing = true;
|
||||||
ui.position = -UI_HEIGHT;
|
ui.position = -UI_HEIGHT;
|
||||||
|
@ -262,12 +257,13 @@ impl Manager {
|
||||||
} else {
|
} else {
|
||||||
background.y += (ui.position - background.y).signum() * 0.7 * delta;
|
background.y += (ui.position - background.y).signum() * 0.7 * delta;
|
||||||
}
|
}
|
||||||
let mut bar = ui.progress_bar.borrow_mut();
|
let mut progress_bar = ui.progress_bar.borrow_mut();
|
||||||
let target_size = (350.0 * ui.progress).min(350.0);
|
let target_size = (350.0 * ui.progress).min(350.0);
|
||||||
if (bar.width - target_size).abs() < 1.0 * delta {
|
if (progress_bar.width - target_size).abs() < 1.0 * delta {
|
||||||
bar.width = target_size;
|
progress_bar.width = target_size;
|
||||||
} else {
|
} else {
|
||||||
bar.width += ((target_size - bar.width).signum() * delta).max(0.0);
|
progress_bar.width +=
|
||||||
|
((target_size - progress_bar.width).signum() * delta).max(0.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl Login {
|
||||||
pub fn new(vars: Rc<console::Vars>) -> Login {
|
pub fn new(vars: Rc<console::Vars>) -> Login {
|
||||||
Login {
|
Login {
|
||||||
elements: None,
|
elements: None,
|
||||||
vars: vars,
|
vars,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,11 +24,7 @@ use crate::protocol;
|
||||||
use crate::render;
|
use crate::render;
|
||||||
use crate::ui;
|
use crate::ui;
|
||||||
|
|
||||||
use base64;
|
|
||||||
use image;
|
|
||||||
use rand;
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use serde_json;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
pub struct ServerList {
|
pub struct ServerList {
|
||||||
|
@ -506,7 +502,7 @@ impl super::Screen for ServerList {
|
||||||
}
|
}
|
||||||
let sm =
|
let sm =
|
||||||
format!("{} mods + {}", res.forge_mods.len(), res.protocol_name);
|
format!("{} mods + {}", res.forge_mods.len(), res.protocol_name);
|
||||||
let st = if res.forge_mods.len() > 0 {
|
let st = if !res.forge_mods.is_empty() {
|
||||||
&sm
|
&sm
|
||||||
} else {
|
} else {
|
||||||
&res.protocol_name
|
&res.protocol_name
|
||||||
|
|
|
@ -21,7 +21,7 @@ impl SettingsMenu {
|
||||||
SettingsMenu {
|
SettingsMenu {
|
||||||
_vars: vars,
|
_vars: vars,
|
||||||
elements: None,
|
elements: None,
|
||||||
show_disconnect_button: show_disconnect_button,
|
show_disconnect_button,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,12 @@ use crate::types::hash::FNVHash;
|
||||||
use crate::types::Gamemode;
|
use crate::types::Gamemode;
|
||||||
use crate::world;
|
use crate::world;
|
||||||
use crate::world::block;
|
use crate::world::block;
|
||||||
use base64;
|
|
||||||
use cgmath::prelude::*;
|
use cgmath::prelude::*;
|
||||||
use log::{debug, error, warn};
|
use log::{debug, error, warn};
|
||||||
use rand::{self, Rng};
|
use rand::{self, Rng};
|
||||||
use rsa_public_encrypt_pkcs1;
|
|
||||||
use serde_json;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::hash::BuildHasherDefault;
|
use std::hash::BuildHasherDefault;
|
||||||
|
use std::str::FromStr;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
@ -114,7 +112,11 @@ impl Server {
|
||||||
) -> Result<Server, protocol::Error> {
|
) -> Result<Server, protocol::Error> {
|
||||||
let mut conn = protocol::Conn::new(address, protocol_version)?;
|
let mut conn = protocol::Conn::new(address, protocol_version)?;
|
||||||
|
|
||||||
let tag = if forge_mods.len() != 0 { "\0FML\0" } else { "" };
|
let tag = if !forge_mods.is_empty() {
|
||||||
|
"\0FML\0"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
};
|
||||||
let host = conn.host.clone() + tag;
|
let host = conn.host.clone() + tag;
|
||||||
let port = conn.port;
|
let port = conn.port;
|
||||||
conn.write_packet(protocol::packet::handshake::serverbound::Handshake {
|
conn.write_packet(protocol::packet::handshake::serverbound::Handshake {
|
||||||
|
@ -151,14 +153,14 @@ impl Server {
|
||||||
warn!("Server is running in offline mode");
|
warn!("Server is running in offline mode");
|
||||||
debug!("Login: {} {}", val.username, val.uuid);
|
debug!("Login: {} {}", val.username, val.uuid);
|
||||||
let mut read = conn.clone();
|
let mut read = conn.clone();
|
||||||
let mut write = conn.clone();
|
let mut write = conn;
|
||||||
read.state = protocol::State::Play;
|
read.state = protocol::State::Play;
|
||||||
write.state = protocol::State::Play;
|
write.state = protocol::State::Play;
|
||||||
let rx = Self::spawn_reader(read);
|
let rx = Self::spawn_reader(read);
|
||||||
return Ok(Server::new(
|
return Ok(Server::new(
|
||||||
protocol_version,
|
protocol_version,
|
||||||
forge_mods,
|
forge_mods,
|
||||||
protocol::UUID::from_str(&val.uuid),
|
protocol::UUID::from_str(&val.uuid).unwrap(),
|
||||||
resources,
|
resources,
|
||||||
Some(write),
|
Some(write),
|
||||||
Some(rx),
|
Some(rx),
|
||||||
|
@ -169,7 +171,7 @@ impl Server {
|
||||||
warn!("Server is running in offline mode");
|
warn!("Server is running in offline mode");
|
||||||
debug!("Login: {} {:?}", val.username, val.uuid);
|
debug!("Login: {} {:?}", val.username, val.uuid);
|
||||||
let mut read = conn.clone();
|
let mut read = conn.clone();
|
||||||
let mut write = conn.clone();
|
let mut write = conn;
|
||||||
read.state = protocol::State::Play;
|
read.state = protocol::State::Play;
|
||||||
write.state = protocol::State::Play;
|
write.state = protocol::State::Play;
|
||||||
let rx = Self::spawn_reader(read);
|
let rx = Self::spawn_reader(read);
|
||||||
|
@ -216,7 +218,7 @@ impl Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut read = conn.clone();
|
let mut read = conn.clone();
|
||||||
let mut write = conn.clone();
|
let mut write = conn;
|
||||||
|
|
||||||
read.enable_encyption(&shared, true);
|
read.enable_encyption(&shared, true);
|
||||||
write.enable_encyption(&shared, false);
|
write.enable_encyption(&shared, false);
|
||||||
|
@ -230,7 +232,7 @@ impl Server {
|
||||||
}
|
}
|
||||||
protocol::packet::Packet::LoginSuccess_String(val) => {
|
protocol::packet::Packet::LoginSuccess_String(val) => {
|
||||||
debug!("Login: {} {}", val.username, val.uuid);
|
debug!("Login: {} {}", val.username, val.uuid);
|
||||||
uuid = protocol::UUID::from_str(&val.uuid);
|
uuid = protocol::UUID::from_str(&val.uuid).unwrap();
|
||||||
read.state = protocol::State::Play;
|
read.state = protocol::State::Play;
|
||||||
write.state = protocol::State::Play;
|
write.state = protocol::State::Play;
|
||||||
break;
|
break;
|
||||||
|
@ -268,7 +270,7 @@ impl Server {
|
||||||
thread::spawn(move || loop {
|
thread::spawn(move || loop {
|
||||||
let pck = read.read_packet();
|
let pck = read.read_packet();
|
||||||
let was_error = pck.is_err();
|
let was_error = pck.is_err();
|
||||||
if let Err(_) = tx.send(pck) {
|
if tx.send(pck).is_err() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if was_error {
|
if was_error {
|
||||||
|
@ -846,8 +848,8 @@ impl Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
match channel {
|
match channel {
|
||||||
// TODO: "REGISTER" =>
|
"REGISTER" => {} // TODO
|
||||||
// TODO: "UNREGISTER" =>
|
"UNREGISTER" => {} // TODO
|
||||||
"FML|HS" => {
|
"FML|HS" => {
|
||||||
let msg = crate::protocol::Serializable::read_from(&mut std::io::Cursor::new(data))
|
let msg = crate::protocol::Serializable::read_from(&mut std::io::Cursor::new(data))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -865,10 +867,7 @@ impl Server {
|
||||||
fml_protocol_version, override_dimension
|
fml_protocol_version, override_dimension
|
||||||
);
|
);
|
||||||
|
|
||||||
self.write_plugin_message(
|
self.write_plugin_message("REGISTER", b"FML|HS\0FML\0FML|MP\0FML\0FORGE");
|
||||||
"REGISTER",
|
|
||||||
"FML|HS\0FML\0FML|MP\0FML\0FORGE".as_bytes(),
|
|
||||||
);
|
|
||||||
self.write_fmlhs_plugin_message(&ClientHello {
|
self.write_fmlhs_plugin_message(&ClientHello {
|
||||||
fml_protocol_version,
|
fml_protocol_version,
|
||||||
});
|
});
|
||||||
|
@ -1029,9 +1028,9 @@ impl Server {
|
||||||
};
|
};
|
||||||
// TODO: refactor with write_plugin_message
|
// TODO: refactor with write_plugin_message
|
||||||
if self.protocol_version >= 47 {
|
if self.protocol_version >= 47 {
|
||||||
self.write_packet(brand.as_message());
|
self.write_packet(brand.into_message());
|
||||||
} else {
|
} else {
|
||||||
self.write_packet(brand.as_message17());
|
self.write_packet(brand.into_message17());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1368,7 +1367,7 @@ impl Server {
|
||||||
) {
|
) {
|
||||||
self.on_player_spawn(
|
self.on_player_spawn(
|
||||||
spawn.entity_id.0,
|
spawn.entity_id.0,
|
||||||
protocol::UUID::from_str(&spawn.uuid),
|
protocol::UUID::from_str(&spawn.uuid).unwrap(),
|
||||||
f64::from(spawn.x),
|
f64::from(spawn.x),
|
||||||
f64::from(spawn.y),
|
f64::from(spawn.y),
|
||||||
f64::from(spawn.z),
|
f64::from(spawn.z),
|
||||||
|
@ -1577,13 +1576,13 @@ impl Server {
|
||||||
nbt.1.get("Text4").unwrap().as_str().unwrap(),
|
nbt.1.get("Text4").unwrap().as_str().unwrap(),
|
||||||
);
|
);
|
||||||
self.world.add_block_entity_action(
|
self.world.add_block_entity_action(
|
||||||
world::BlockEntityAction::UpdateSignText(
|
world::BlockEntityAction::UpdateSignText(Box::new((
|
||||||
block_update.location,
|
block_update.location,
|
||||||
line1,
|
line1,
|
||||||
line2,
|
line2,
|
||||||
line3,
|
line3,
|
||||||
line4,
|
line4,
|
||||||
),
|
))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
//10 => // Unused
|
//10 => // Unused
|
||||||
|
@ -1611,13 +1610,13 @@ impl Server {
|
||||||
format::convert_legacy(&mut update_sign.line3);
|
format::convert_legacy(&mut update_sign.line3);
|
||||||
format::convert_legacy(&mut update_sign.line4);
|
format::convert_legacy(&mut update_sign.line4);
|
||||||
self.world
|
self.world
|
||||||
.add_block_entity_action(world::BlockEntityAction::UpdateSignText(
|
.add_block_entity_action(world::BlockEntityAction::UpdateSignText(Box::new((
|
||||||
update_sign.location,
|
update_sign.location,
|
||||||
update_sign.line1,
|
update_sign.line1,
|
||||||
update_sign.line2,
|
update_sign.line2,
|
||||||
update_sign.line3,
|
update_sign.line3,
|
||||||
update_sign.line4,
|
update_sign.line4,
|
||||||
));
|
))));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_sign_update_u16(&mut self, mut update_sign: packet::play::clientbound::UpdateSign_u16) {
|
fn on_sign_update_u16(&mut self, mut update_sign: packet::play::clientbound::UpdateSign_u16) {
|
||||||
|
@ -1626,13 +1625,13 @@ impl Server {
|
||||||
format::convert_legacy(&mut update_sign.line3);
|
format::convert_legacy(&mut update_sign.line3);
|
||||||
format::convert_legacy(&mut update_sign.line4);
|
format::convert_legacy(&mut update_sign.line4);
|
||||||
self.world
|
self.world
|
||||||
.add_block_entity_action(world::BlockEntityAction::UpdateSignText(
|
.add_block_entity_action(world::BlockEntityAction::UpdateSignText(Box::new((
|
||||||
Position::new(update_sign.x, update_sign.y as i32, update_sign.z),
|
Position::new(update_sign.x, update_sign.y as i32, update_sign.z),
|
||||||
update_sign.line1,
|
update_sign.line1,
|
||||||
update_sign.line2,
|
update_sign.line2,
|
||||||
update_sign.line3,
|
update_sign.line3,
|
||||||
update_sign.line4,
|
update_sign.line4,
|
||||||
));
|
))));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_player_info_string(
|
fn on_player_info_string(
|
||||||
|
@ -1972,6 +1971,7 @@ impl Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::enum_variant_names)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum TeleportFlag {
|
enum TeleportFlag {
|
||||||
RelX = 0b00001,
|
RelX = 0b00001,
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub struct Brand {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Brand {
|
impl Brand {
|
||||||
pub fn as_message(self) -> PluginMessageServerbound {
|
pub fn into_message(self) -> PluginMessageServerbound {
|
||||||
let protocol_version = crate::protocol::current_protocol_version();
|
let protocol_version = crate::protocol::current_protocol_version();
|
||||||
|
|
||||||
let channel_name = if protocol_version >= 404 {
|
let channel_name = if protocol_version >= 404 {
|
||||||
|
@ -25,7 +25,7 @@ impl Brand {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: cleanup this duplication for 1.7, return either message dynamically
|
// TODO: cleanup this duplication for 1.7, return either message dynamically
|
||||||
pub fn as_message17(self) -> PluginMessageServerbound_i16 {
|
pub fn into_message17(self) -> PluginMessageServerbound_i16 {
|
||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
Serializable::write_to(&self.brand, &mut data).unwrap();
|
Serializable::write_to(&self.brand, &mut data).unwrap();
|
||||||
PluginMessageServerbound_i16 {
|
PluginMessageServerbound_i16 {
|
||||||
|
|
|
@ -114,7 +114,7 @@ impl SunModel {
|
||||||
z: SIZE,
|
z: SIZE,
|
||||||
texture_x: 1.0,
|
texture_x: 1.0,
|
||||||
texture_y: 0.0,
|
texture_y: 0.0,
|
||||||
texture: tex.clone(),
|
texture: tex,
|
||||||
r: 255,
|
r: 255,
|
||||||
g: 255,
|
g: 255,
|
||||||
b: 255,
|
b: 255,
|
||||||
|
@ -178,7 +178,7 @@ impl SunModel {
|
||||||
z: SIZE,
|
z: SIZE,
|
||||||
texture_x: mpx + (1.0 / 4.0),
|
texture_x: mpx + (1.0 / 4.0),
|
||||||
texture_y: mpy,
|
texture_y: mpy,
|
||||||
texture: tex.clone(),
|
texture: tex,
|
||||||
r: 255,
|
r: 255,
|
||||||
g: 255,
|
g: 255,
|
||||||
b: 255,
|
b: 255,
|
||||||
|
|
|
@ -3,7 +3,6 @@ use crate::render::model;
|
||||||
use crate::shared::{Direction, Position};
|
use crate::shared::{Direction, Position};
|
||||||
use crate::world;
|
use crate::world;
|
||||||
use crate::world::block;
|
use crate::world::block;
|
||||||
use cgmath;
|
|
||||||
use collision::{self, Aabb};
|
use collision::{self, Aabb};
|
||||||
|
|
||||||
pub struct Info {
|
pub struct Info {
|
||||||
|
@ -12,6 +11,12 @@ pub struct Info {
|
||||||
last_pos: Position,
|
last_pos: Position,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Info {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Info {
|
impl Info {
|
||||||
pub fn new() -> Info {
|
pub fn new() -> Info {
|
||||||
Info {
|
Info {
|
||||||
|
@ -130,6 +135,7 @@ impl Info {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn test_block(
|
pub fn test_block(
|
||||||
world: &world::World,
|
world: &world::World,
|
||||||
pos: Position,
|
pos: Position,
|
||||||
|
|
|
@ -2,7 +2,6 @@ use crate::render;
|
||||||
use crate::resources;
|
use crate::resources;
|
||||||
use crate::ui;
|
use crate::ui;
|
||||||
use rand::{self, seq::SliceRandom};
|
use rand::{self, seq::SliceRandom};
|
||||||
use rand_pcg;
|
|
||||||
use std::f64::consts;
|
use std::f64::consts;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
|
@ -282,6 +282,12 @@ pub struct Container {
|
||||||
last_height: f64,
|
last_height: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Container {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Container {
|
impl Container {
|
||||||
pub fn new() -> Container {
|
pub fn new() -> Container {
|
||||||
Container {
|
Container {
|
||||||
|
@ -677,6 +683,7 @@ macro_rules! element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct $builder {
|
pub struct $builder {
|
||||||
$(
|
$(
|
||||||
$sname: Option<$sty>,
|
$sname: Option<$sty>,
|
||||||
|
@ -769,7 +776,7 @@ macro_rules! element {
|
||||||
$oname: self.$oname.unwrap_or($oval),
|
$oname: self.$oname.unwrap_or($oval),
|
||||||
)*
|
)*
|
||||||
$(
|
$(
|
||||||
$nname: $nname,
|
$nname,
|
||||||
)*
|
)*
|
||||||
// Base fields
|
// Base fields
|
||||||
draw_index: self.draw_index,
|
draw_index: self.draw_index,
|
||||||
|
@ -1532,9 +1539,8 @@ impl UIElement for TextBox {
|
||||||
(VirtualKeyCode::V, true) => {
|
(VirtualKeyCode::V, true) => {
|
||||||
if ctrl_pressed {
|
if ctrl_pressed {
|
||||||
let mut clipboard: ClipboardContext = ClipboardProvider::new().unwrap();
|
let mut clipboard: ClipboardContext = ClipboardProvider::new().unwrap();
|
||||||
match clipboard.get_contents() {
|
if let Ok(text) = clipboard.get_contents() {
|
||||||
Ok(text) => self.input.push_str(&text),
|
self.input.push_str(&text)
|
||||||
Err(_) => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,8 @@ use crate::shared::{Direction, Position};
|
||||||
use crate::types::hash::FNVHash;
|
use crate::types::hash::FNVHash;
|
||||||
use crate::types::{bit, nibble};
|
use crate::types::{bit, nibble};
|
||||||
use cgmath::prelude::*;
|
use cgmath::prelude::*;
|
||||||
use collision;
|
|
||||||
use flate2::read::ZlibDecoder;
|
use flate2::read::ZlibDecoder;
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::hash::BuildHasherDefault;
|
use std::hash::BuildHasherDefault;
|
||||||
|
@ -53,11 +53,13 @@ pub enum BlockEntityAction {
|
||||||
Create(Position),
|
Create(Position),
|
||||||
Remove(Position),
|
Remove(Position),
|
||||||
UpdateSignText(
|
UpdateSignText(
|
||||||
Position,
|
Box<(
|
||||||
format::Component,
|
Position,
|
||||||
format::Component,
|
format::Component,
|
||||||
format::Component,
|
format::Component,
|
||||||
format::Component,
|
format::Component,
|
||||||
|
format::Component,
|
||||||
|
)>,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +204,7 @@ impl World {
|
||||||
self.block_entity_actions.push_back(action);
|
self.block_entity_actions.push_back(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::verbose_bit_mask)] // "llvm generates better code" for updates_performed & 0xFFF "on x86"
|
||||||
pub fn tick(&mut self, m: &mut ecs::Manager) {
|
pub fn tick(&mut self, m: &mut ecs::Manager) {
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
@ -209,11 +212,9 @@ impl World {
|
||||||
while !self.light_updates.is_empty() {
|
while !self.light_updates.is_empty() {
|
||||||
updates_performed += 1;
|
updates_performed += 1;
|
||||||
self.do_light_update();
|
self.do_light_update();
|
||||||
if updates_performed & 0xFFF == 0 {
|
if (updates_performed & 0xFFF == 0) && start.elapsed().subsec_nanos() >= 5000000 {
|
||||||
if start.elapsed().subsec_nanos() >= 5000000 {
|
// 5 ms for light updates
|
||||||
// 5 ms for light updates
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +244,8 @@ impl World {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BlockEntityAction::UpdateSignText(pos, line1, line2, line3, line4) => {
|
BlockEntityAction::UpdateSignText(bx) => {
|
||||||
|
let (pos, line1, line2, line3, line4) = *bx;
|
||||||
if let Some(chunk) = self.chunks.get(&CPos(pos.x >> 4, pos.z >> 4)) {
|
if let Some(chunk) = self.chunks.get(&CPos(pos.x >> 4, pos.z >> 4)) {
|
||||||
if let Some(entity) = chunk.block_entities.get(&pos) {
|
if let Some(entity) = chunk.block_entities.get(&pos) {
|
||||||
if let Some(sign) = m.get_component_mut(*entity, sign_info) {
|
if let Some(sign) = m.get_component_mut(*entity, sign_info) {
|
||||||
|
@ -316,7 +318,7 @@ impl World {
|
||||||
|
|
||||||
pub fn copy_cloud_heightmap(&mut self, data: &mut [u8]) -> bool {
|
pub fn copy_cloud_heightmap(&mut self, data: &mut [u8]) -> bool {
|
||||||
let mut dirty = false;
|
let mut dirty = false;
|
||||||
for (_, c) in &mut self.chunks {
|
for c in self.chunks.values_mut() {
|
||||||
if c.heightmap_dirty {
|
if c.heightmap_dirty {
|
||||||
dirty = true;
|
dirty = true;
|
||||||
c.heightmap_dirty = false;
|
c.heightmap_dirty = false;
|
||||||
|
@ -443,7 +445,7 @@ impl World {
|
||||||
|
|
||||||
pub fn get_dirty_chunk_sections(&mut self) -> Vec<(i32, i32, i32)> {
|
pub fn get_dirty_chunk_sections(&mut self) -> Vec<(i32, i32, i32)> {
|
||||||
let mut out = vec![];
|
let mut out = vec![];
|
||||||
for (_, chunk) in &mut self.chunks {
|
for chunk in self.chunks.values_mut() {
|
||||||
for sec in &mut chunk.sections {
|
for sec in &mut chunk.sections {
|
||||||
if let Some(sec) = sec.as_mut() {
|
if let Some(sec) = sec.as_mut() {
|
||||||
if !sec.building && sec.dirty {
|
if !sec.building && sec.dirty {
|
||||||
|
@ -490,7 +492,7 @@ impl World {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn flag_dirty_all(&mut self) {
|
pub fn flag_dirty_all(&mut self) {
|
||||||
for (_, chunk) in &mut self.chunks {
|
for chunk in self.chunks.values_mut() {
|
||||||
for sec in &mut chunk.sections {
|
for sec in &mut chunk.sections {
|
||||||
if let Some(sec) = sec.as_mut() {
|
if let Some(sec) = sec.as_mut() {
|
||||||
sec.dirty = true;
|
sec.dirty = true;
|
||||||
|
@ -801,6 +803,7 @@ impl World {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::needless_range_loop)]
|
||||||
fn load_uncompressed_chunk17(
|
fn load_uncompressed_chunk17(
|
||||||
&mut self,
|
&mut self,
|
||||||
x: i32,
|
x: i32,
|
||||||
|
@ -997,6 +1000,7 @@ impl World {
|
||||||
self.load_chunk19_or_115(false, x, z, new, mask, data)
|
self.load_chunk19_or_115(false, x, z, new, mask, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::or_fun_call)]
|
||||||
fn load_chunk19_or_115(
|
fn load_chunk19_or_115(
|
||||||
&mut self,
|
&mut self,
|
||||||
read_biomes: bool,
|
read_biomes: bool,
|
||||||
|
@ -1071,6 +1075,7 @@ impl World {
|
||||||
mappings
|
mappings
|
||||||
.get(&id)
|
.get(&id)
|
||||||
.cloned()
|
.cloned()
|
||||||
|
// TODO: fix or_fun_call, but do not re-borrow self
|
||||||
.unwrap_or(block::Block::by_vanilla_id(
|
.unwrap_or(block::Block::by_vanilla_id(
|
||||||
id,
|
id,
|
||||||
self.protocol_version,
|
self.protocol_version,
|
||||||
|
@ -1267,20 +1272,24 @@ impl Chunk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let idx = ((z << 4) | x) as usize;
|
let idx = ((z << 4) | x) as usize;
|
||||||
if self.heightmap[idx] < y as u8 {
|
match self.heightmap[idx].cmp(&(y as u8)) {
|
||||||
self.heightmap[idx] = y as u8;
|
Ordering::Less => {
|
||||||
self.heightmap_dirty = true;
|
self.heightmap[idx] = y as u8;
|
||||||
} else if self.heightmap[idx] == y as u8 {
|
self.heightmap_dirty = true;
|
||||||
// Find a new lowest
|
|
||||||
for yy in 0..y {
|
|
||||||
let sy = y - yy - 1;
|
|
||||||
if let block::Air { .. } = self.get_block(x, sy, z) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
self.heightmap[idx] = sy as u8;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
self.heightmap_dirty = true;
|
Ordering::Equal => {
|
||||||
|
// Find a new lowest
|
||||||
|
for yy in 0..y {
|
||||||
|
let sy = y - yy - 1;
|
||||||
|
if let block::Air { .. } = self.get_block(x, sy, z) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
self.heightmap[idx] = sy as u8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
self.heightmap_dirty = true;
|
||||||
|
}
|
||||||
|
Ordering::Greater => (),
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue