Skip to content

Commit 2234e0b

Browse files
committed
Implement getblock
1 parent a067223 commit 2234e0b

File tree

5 files changed

+183
-48
lines changed

5 files changed

+183
-48
lines changed

src/logic/ast.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ pub enum Instruction {
9595
y: Value,
9696
},
9797
// privileged
98+
GetBlock {
99+
layer: TileLayer,
100+
result: Value,
101+
x: Value,
102+
y: Value,
103+
},
98104
SetRate {
99105
value: Value,
100106
},
@@ -182,6 +188,14 @@ pub enum LogicOp {
182188
Atan,
183189
}
184190

191+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
192+
pub enum TileLayer {
193+
Floor,
194+
Ore,
195+
Block,
196+
Building,
197+
}
198+
185199
#[derive(Debug, Clone, PartialEq)]
186200
pub enum Value {
187201
Variable(String),

src/logic/grammar.lalrpop

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ match {
3232
"stop",
3333
"end",
3434
"jump",
35+
"getblock",
3536
"setrate",
3637

3738
"clear",
@@ -122,6 +123,9 @@ match {
122123
"unitCommand",
123124
"unitStance",
124125

126+
"ore",
127+
"building",
128+
125129
// https://github.com/Anuken/Arc/blob/071fdffaf220cd57cf971a0ee58db2f321f92ee1/arc-core/src/arc/util/Strings.java#L495
126130
// for example, -+1.--0. is a valid number literal
127131
r"(?x)
@@ -256,6 +260,9 @@ Instruction: Instruction = {
256260

257261
// privileged
258262

263+
"getblock" <layer:TileLayer> <result:Value> <x:Value> <y:Value> =>
264+
Instruction::GetBlock { <> },
265+
259266
"setrate" <value:Value> =>
260267
Instruction::SetRate { <> },
261268

@@ -386,7 +393,14 @@ ContentType: ContentType = {
386393
"team" => ContentType::Team,
387394
"unitCommand" => ContentType::UnitCommand,
388395
"unitStance" => ContentType::UnitStance,
389-
}
396+
};
397+
398+
TileLayer: TileLayer = {
399+
"floor" => TileLayer::Floor,
400+
"ore" => TileLayer::Ore,
401+
"block" => TileLayer::Block,
402+
"building" => TileLayer::Building,
403+
};
390404

391405
Value: Value = {
392406
<s:STRING> =>
@@ -465,6 +479,7 @@ Symbol = {
465479
"stop",
466480
"end",
467481
"jump",
482+
"getblock",
468483
"setrate",
469484

470485
"clear",
@@ -554,4 +569,7 @@ Symbol = {
554569
"team",
555570
"unitCommand",
556571
"unitStance",
572+
573+
"ore",
574+
"building",
557575
};

src/logic/vm/instructions.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ use super::{
1111
};
1212
use crate::{
1313
logic::{
14-
ast::{self, ConditionOp, LogicOp},
14+
ast::{self, ConditionOp, LogicOp, TileLayer},
1515
vm::variables::{F64_DEG_RAD, F64_RAD_DEG},
1616
},
1717
types::{
18-
ContentType, Team,
18+
ContentType, Point2, Team,
1919
colors::{f32_to_double_bits, f64_from_double_bits},
2020
content,
2121
},
@@ -207,6 +207,17 @@ impl Instruction for InstructionBuilder {
207207
_ if !privileged => Box::new(Noop),
208208

209209
// privileged
210+
ast::Instruction::GetBlock {
211+
layer,
212+
result,
213+
x,
214+
y,
215+
} => Box::new(GetBlock {
216+
layer,
217+
result: lvar(result),
218+
x: lvar(x),
219+
y: lvar(y),
220+
}),
210221
ast::Instruction::SetRate { value } => Box::new(SetRate { value: lvar(value) }),
211222
})
212223
}
@@ -635,6 +646,31 @@ impl SimpleInstruction for Jump {
635646

636647
// privileged
637648

649+
struct GetBlock {
650+
layer: TileLayer,
651+
result: LVar,
652+
x: LVar,
653+
y: LVar,
654+
}
655+
656+
impl SimpleInstruction for GetBlock {
657+
fn execute(&self, state: &mut ProcessorState, vm: &LogicVM) {
658+
let result = match vm.building(Point2 {
659+
x: self.x.get(state).numf().round() as i32,
660+
y: self.y.get(state).numf().round() as i32,
661+
}) {
662+
Some(building) => match self.layer {
663+
TileLayer::Floor => Content::Block(&content::blocks::STONE).into(),
664+
TileLayer::Ore => Content::Block(&content::blocks::AIR).into(),
665+
TileLayer::Block => Content::Block(building.block).into(),
666+
TileLayer::Building => building.position.into(),
667+
},
668+
None => LValue::Null,
669+
};
670+
self.result.set(state, result);
671+
}
672+
}
673+
638674
struct SetRate {
639675
value: LVar,
640676
}

src/logic/vm/mod.rs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,10 @@ mod tests {
251251
},
252252
variables::{Content, LValue, LVar},
253253
},
254-
types::{Object, PackedPoint2, ProcessorConfig, ProcessorLinkConfig, Team, colors::COLORS},
254+
types::{
255+
Object, PackedPoint2, ProcessorConfig, ProcessorLinkConfig, Team, colors::COLORS,
256+
content,
257+
},
255258
};
256259

257260
use super::{
@@ -848,6 +851,66 @@ mod tests {
848851
);
849852
}
850853

854+
#[test]
855+
fn test_getblock() {
856+
let mut builder = LogicVMBuilder::new();
857+
builder.add_buildings(
858+
[
859+
Building::from_processor_config(
860+
WORLD_PROCESSOR,
861+
Point2 { x: 1, y: 2 },
862+
&ProcessorConfig::from_code(
863+
"
864+
getblock floor floor1 @thisx @thisy
865+
getblock ore ore1 @thisx @thisy
866+
getblock block block1 @thisx @thisy
867+
getblock building building1 @thisx @thisy
868+
869+
getblock floor floor2 1 3
870+
getblock ore ore2 1 3
871+
getblock block block2 1 3
872+
getblock building building2 1 3
873+
874+
getblock floor floor3 1 1
875+
getblock ore ore3 1 1
876+
getblock block block3 1 1
877+
getblock building building3 1 1
878+
879+
stop
880+
",
881+
),
882+
&builder,
883+
),
884+
Building::from_config(SWITCH, Point2 { x: 1, y: 3 }, &Object::Null, &builder),
885+
]
886+
.map(|v| v.unwrap()),
887+
);
888+
let mut vm = builder.build().unwrap();
889+
890+
run(&mut vm, 2, true);
891+
892+
let state = take_processor(&mut vm, (1, 2)).state;
893+
assert_variables(
894+
&state,
895+
map_iter! {
896+
"floor1": LValue::Content(Content::Block(&content::blocks::STONE)),
897+
"ore1": LValue::Content(Content::Block(&content::blocks::AIR)),
898+
"block1": LValue::Content(Content::Block(content::blocks::FROM_NAME["world-processor"])),
899+
"building1": LValue::Building(Point2 { x: 1, y: 2 }),
900+
901+
"floor2": LValue::Content(Content::Block(&content::blocks::STONE)),
902+
"ore2": LValue::Content(Content::Block(&content::blocks::AIR)),
903+
"block2": LValue::Content(Content::Block(content::blocks::FROM_NAME["switch"])),
904+
"building2": LValue::Building(Point2 { x: 1, y: 3 }),
905+
906+
"floor3": LValue::Null,
907+
"ore3": LValue::Null,
908+
"block3": LValue::Null,
909+
"building3": LValue::Null,
910+
},
911+
);
912+
}
913+
851914
#[test]
852915
fn test_max_ticks() {
853916
let mut vm = single_processor_vm(

src/types/content.rs

Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -92,51 +92,55 @@ impl PartialEq for Unit {
9292
impl Eq for Unit {}
9393

9494
macro_rules! include_content {
95-
($name:ident, $typ:ident, $file:expr) => {
96-
pub mod $name {
97-
use std::collections::HashMap;
98-
99-
use lazy_static::lazy_static;
100-
101-
use super::$typ;
102-
103-
lazy_static! {
104-
pub static ref VALUES: Vec<$typ> = csv::ReaderBuilder::new()
105-
.delimiter(b';')
106-
.comment(Some(b'/'))
107-
.from_reader(&include_bytes!($file)[..])
108-
.deserialize()
109-
.map(|v| v.unwrap())
110-
.collect();
111-
pub static ref FROM_LOGIC_ID: HashMap<i32, &'static $typ> = VALUES
112-
.iter()
113-
.filter(|v| v.logic_id >= 0)
114-
.map(|v| (v.logic_id, v))
115-
.collect();
116-
pub static ref FROM_NAME: HashMap<&'static str, &'static $typ> =
117-
VALUES.iter().map(|v| (v.name.as_str(), v)).collect();
118-
}
95+
($typ:ident, $file:expr) => {
96+
use std::collections::HashMap;
97+
98+
use lazy_static::lazy_static;
99+
100+
use super::$typ;
101+
102+
lazy_static! {
103+
pub static ref VALUES: Vec<$typ> = csv::ReaderBuilder::new()
104+
.delimiter(b';')
105+
.comment(Some(b'/'))
106+
.from_reader(&include_bytes!($file)[..])
107+
.deserialize()
108+
.map(|v| v.unwrap())
109+
.collect();
110+
pub static ref FROM_LOGIC_ID: HashMap<i32, &'static $typ> = VALUES
111+
.iter()
112+
.filter(|v| v.logic_id >= 0)
113+
.map(|v| (v.logic_id, v))
114+
.collect();
115+
pub static ref FROM_NAME: HashMap<&'static str, &'static $typ> =
116+
VALUES.iter().map(|v| (v.name.as_str(), v)).collect();
119117
}
120118
};
121119
}
122120

123-
include_content!(
124-
blocks,
125-
Block,
126-
"../../submodules/mimex-data/data/be/mimex-blocks.txt"
127-
);
128-
include_content!(
129-
items,
130-
Item,
131-
"../../submodules/mimex-data/data/be/mimex-items.txt"
132-
);
133-
include_content!(
134-
liquids,
135-
Liquid,
136-
"../../submodules/mimex-data/data/be/mimex-liquids.txt"
137-
);
138-
include_content!(
139-
units,
140-
Unit,
141-
"../../submodules/mimex-data/data/be/mimex-units.txt"
142-
);
121+
pub mod blocks {
122+
include_content!(
123+
Block,
124+
"../../submodules/mimex-data/data/be/mimex-blocks.txt"
125+
);
126+
127+
lazy_static! {
128+
pub static ref AIR: &'static Block = FROM_NAME["air"];
129+
pub static ref STONE: &'static Block = FROM_NAME["stone"];
130+
}
131+
}
132+
133+
pub mod items {
134+
include_content!(Item, "../../submodules/mimex-data/data/be/mimex-items.txt");
135+
}
136+
137+
pub mod liquids {
138+
include_content!(
139+
Liquid,
140+
"../../submodules/mimex-data/data/be/mimex-liquids.txt"
141+
);
142+
}
143+
144+
pub mod units {
145+
include_content!(Unit, "../../submodules/mimex-data/data/be/mimex-units.txt");
146+
}

0 commit comments

Comments
 (0)