🐛 append End instruction after jump labels at end, CONTROL function

main
Shad Amethyst 1 year ago
parent 00f992d459
commit 652b64d4ca

@ -0,0 +1,42 @@
READ(difficulty, cell1, 3)
IF difficulty == 0 THEN
difficulty = 2
WRITE(difficulty, cell1, 3)
END IF
PRINT "Difficulty: "
IF difficulty == 1 THEN
PRINT "<[green]Easy[white]>[gray] Medium Hard "
ELSE
IF difficulty == 2 THEN
PRINT " [gray]Easy [white]<[yellow]Medium[white]>[gray] Hard "
ELSE
PRINT "[gray]Easy Medium [white]<[red]Hard[white]>"
END IF
END IF
PRINT_FLUSH(message1)
difficulty = 0
easy = switch1.@enabled
IF easy THEN
difficulty = 1
CONTROL(enabled, switch1, false)
END IF
medium = switch2.@enabled
IF medium THEN
difficulty = 2
CONTROL(enabled, switch2, false)
END IF
hard = switch3.@enabled
IF hard THEN
difficulty = 3
CONTROL(enabled, switch3, false)
END IF
IF difficulty != 0 THEN
WRITE(difficulty, cell1, 3)
END IF

@ -16,14 +16,19 @@ LOOP WHILE remaining > 0
WHILE true
wave = wave + 1
REM TODO: difficult control wave multiplier
LET progression = POW(wave / 4, 0.75)
READ(difficulty, cell1, 3)
difficulty = difficulty - 1
LET progression_mult = 5 - difficulty / 2
LET units_mult = 0.5 + difficulty / 2
LET max_progression = 8 + difficulty * 2
LET progression = POW(wave / progression_mult, 0.75)
REM TODO: optimize duplicate operations
progression = MIN(progression / 2 + rand(progression / 2), 10)
progression = MIN(progression / 2 + rand(progression / 2), max_progression)
LET units = 2 + SQRT(progression) * 4 + RAND(progression * 2)
REM TODO: difficulty control unit amount
units = CEIL(units * 1)
units = MIN(CEIL(units * units_mult), 20)
LET tank_units = FLOOR(RAND(units))
LET mech_units = FLOOR(RAND(units - tank_units))
LET air_units = units - tank_units - mech_units

@ -65,6 +65,37 @@ impl Default for Config {
}),
);
special_functions.insert(
String::from("control"),
Box::new(|arguments| {
let BasicAstExpression::Variable(buffer) = &arguments[0] else {
return Err(ParseError::InvalidArgument(arguments[0].clone()));
};
let expected_length = match buffer.as_str() {
"enabled" => 3,
"shoot" => 5,
"shootp" => 4,
"config" => 3,
"color" => 3,
_ => return Err(ParseError::InvalidArgument(arguments[0].clone())),
};
if arguments.len() != expected_length {
return Err(ParseError::InvalidArgumentCount(
String::from("control"),
expected_length,
arguments.len(),
));
}
Ok(BasicAstInstruction::CallBuiltin(
String::from("control"),
arguments,
))
}),
);
Self {
builtin_functions: HashMap::from([
builtin_function!("print_flush", None, false, 1),

@ -61,6 +61,8 @@ pub enum MindustryOperation {
PrintFlush(Operand),
/// Available to world processors only - flushes the print buffer to a global buffer
WorldPrintFlush(WorldPrintFlush),
/// Sets a property of a given block
Control(String, Vec<Operand>),
/// Reads `key` from `object` and puts its result into `out_name`.
/// `object` may be a connection, an entity, a block, a unit type, etc.
@ -146,10 +148,12 @@ impl_operands!(
mut: {
Self::Generic(_name, operands) => operands.iter_mut().collect::<Vec<_>>(),
Self::GenericMut(_name, _out_name, operands) => operands.iter_mut().collect::<Vec<_>>(),
Self::Control(_name, operands) => operands.iter_mut().collect::<Vec<_>>(),
},
ref: {
Self::Generic(_name, operands) => operands.iter().collect::<Vec<_>>(),
Self::GenericMut(_name, _out_name, operands) => operands.iter().collect::<Vec<_>>(),
Self::Control(_name, operands) => operands.iter().collect::<Vec<_>>(),
}
);
@ -165,7 +169,8 @@ impl MindustryOperation {
value: _,
cell: _,
index: _,
} => false,
}
| Self::Control(_, _) => false,
Self::Operator(out_name, _, _, _)
| Self::UnaryOperator(out_name, _, _)
@ -214,7 +219,8 @@ impl MindustryOperation {
| Self::PrintFlush(_)
| Self::WorldPrintFlush(_)
| Self::Generic(_, _)
| Self::GenericMut(_, _, _) => false,
| Self::GenericMut(_, _, _)
| Self::Control(_, _) => false,
Self::Set(var_name, _)
| Self::Operator(var_name, _, _, _)

@ -120,12 +120,27 @@ impl std::fmt::Display for MindustryProgram {
WorldPrintFlush::Toast(time) => writeln!(f, "message toast {}", time)?,
};
}
MindustryOperation::Sensor { out_name, object, key } => {
MindustryOperation::Sensor {
out_name,
object,
key,
} => {
writeln!(f, "sensor {out_name} {object} {key}")?;
}
MindustryOperation::Control(key, arguments) => {
write!(f, "control {}", key)?;
for arg in arguments {
write!(f, " {}", arg)?;
}
writeln!(f)?;
}
}
}
if matches!(self.0.last(), Some(MindustryOperation::JumpLabel(_))) {
writeln!(f, "end")?;
}
Ok(())
}
}

@ -382,6 +382,20 @@ pub fn translate_ast(
res.push(instruction);
}
Instr::CallBuiltin(name, arguments) if name == "control" => translate_call!(
"control",
arguments,
res,
[BasicAstExpression::Variable(key), ..],
MindustryOperation::Control(
key.clone(),
arguments
.iter()
.skip(1)
.map(|arg| translate_operand!(arg, res, namer))
.collect()
)
),
Instr::CallBuiltin(name, arguments) => {
let Some((Some(target_name), mutating, _)) = config.builtin_functions.get(name)
else {

@ -27,3 +27,4 @@ set main__tmp_11 1
message announce main__tmp_11
main__label_5_endif:
main__label_1_endif:
end

@ -14,3 +14,4 @@ main__label_4_else:
message announce 1
main__label_5_endif:
main__label_1_endif:
end

Loading…
Cancel
Save