Added field for running logic code upon objective completion
This commit is contained in:
@@ -47,6 +47,10 @@ public class MapObjectivesDialog extends BaseDialog{
|
|||||||
|
|
||||||
if(field != null && field.isAnnotationPresent(Multiline.class)){
|
if(field != null && field.isAnnotationPresent(Multiline.class)){
|
||||||
cont.area(get.get(), set).height(100f).growX();
|
cont.area(get.get(), set).height(100f).growX();
|
||||||
|
}else if(field != null && field.isAnnotationPresent(LogicCode.class)){
|
||||||
|
cont.button(b -> b.image(Icon.pencil).size(iconSmall), () -> {
|
||||||
|
ui.logic.show(get.get(), null, true, set::get);
|
||||||
|
}).pad(4f);
|
||||||
}else{
|
}else{
|
||||||
cont.field(get.get(), set).growX();
|
cont.field(get.get(), set).growX();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
public static abstract class MapObjective{
|
public static abstract class MapObjective{
|
||||||
public boolean hidden;
|
public boolean hidden;
|
||||||
public @Nullable @Multiline String details;
|
public @Nullable @Multiline String details;
|
||||||
|
public @Nullable @LogicCode String completionLogicCode;
|
||||||
public @Unordered String[] flagsAdded = {};
|
public @Unordered String[] flagsAdded = {};
|
||||||
public @Unordered String[] flagsRemoved = {};
|
public @Unordered String[] flagsRemoved = {};
|
||||||
public ObjectiveMarker[] markers = {};
|
public ObjectiveMarker[] markers = {};
|
||||||
@@ -207,9 +208,13 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
state.rules.objectiveFlags.removeAll(flagsRemoved);
|
state.rules.objectiveFlags.removeAll(flagsRemoved);
|
||||||
state.rules.objectiveFlags.addAll(flagsAdded);
|
state.rules.objectiveFlags.addAll(flagsAdded);
|
||||||
completed = true;
|
completed = true;
|
||||||
|
|
||||||
|
if(completionLogicCode != null && !completionLogicCode.isEmpty()){
|
||||||
|
LExecutor.runLogicScript(completionLogicCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return True if all {@link #parents} are completed, rendering this objective able to execute. */
|
/** @return true if all {@link #parents} are completed, rendering this objective able to execute. */
|
||||||
public final boolean dependencyFinished(){
|
public final boolean dependencyFinished(){
|
||||||
if(depFinished) return true;
|
if(depFinished) return true;
|
||||||
|
|
||||||
@@ -220,7 +225,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
return depFinished = true;
|
return depFinished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return True if this objective is done (practically, has been removed from the executor). */
|
/** @return true if this objective is done (practically, has been removed from the executor). */
|
||||||
public final boolean isCompleted(){
|
public final boolean isCompleted(){
|
||||||
return completed;
|
return completed;
|
||||||
}
|
}
|
||||||
@@ -1493,6 +1498,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
@Retention(RUNTIME)
|
@Retention(RUNTIME)
|
||||||
public @interface Multiline{}
|
public @interface Multiline{}
|
||||||
|
|
||||||
|
/** For {@link String}; indicates that text corresponds to logic code. */
|
||||||
|
@Target(FIELD)
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
public @interface LogicCode{}
|
||||||
|
|
||||||
/** For {@code float}; multiplies the UI input by 60. */
|
/** For {@code float}; multiplies the UI input by 60. */
|
||||||
@Target(FIELD)
|
@Target(FIELD)
|
||||||
@Retention(RUNTIME)
|
@Retention(RUNTIME)
|
||||||
|
|||||||
@@ -67,6 +67,28 @@ public class LExecutor{
|
|||||||
Events.on(ResetEvent.class, e -> unitTimeouts.clear());
|
Events.on(ResetEvent.class, e -> unitTimeouts.clear());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void runLogicScript(String code){
|
||||||
|
runLogicScript(code, 100_000, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runLogicScript(String code, int maxInstructions, boolean loop){
|
||||||
|
LExecutor executor = new LExecutor();
|
||||||
|
executor.privileged = true;
|
||||||
|
|
||||||
|
try{
|
||||||
|
//assembler has no variables, all the standard ones are null
|
||||||
|
executor.load(LAssembler.assemble(code, true));
|
||||||
|
}catch(Throwable ignored){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//executions are limited to prevent a game freeze
|
||||||
|
for(int i = 1; i < maxInstructions; i++){
|
||||||
|
if((!loop && executor.counter.numval >= executor.instructions.length || executor.counter.numval < 0) || executor.yield) break;
|
||||||
|
executor.runOnce();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean timeoutDone(Unit unit, float delay){
|
boolean timeoutDone(Unit unit, float delay){
|
||||||
return Time.time >= unitTimeouts.get(unit.id) + delay;
|
return Time.time >= unitTimeouts.get(unit.id) + delay;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package mindustry.maps.filters;
|
package mindustry.maps.filters;
|
||||||
|
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import mindustry.*;
|
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.logic.*;
|
import mindustry.logic.*;
|
||||||
import mindustry.maps.filters.FilterOption.*;
|
import mindustry.maps.filters.FilterOption.*;
|
||||||
@@ -38,26 +37,10 @@ public class LogicFilter extends GenerateFilter{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(Tiles tiles, GenerateInput in){
|
public void apply(Tiles tiles, GenerateInput in){
|
||||||
LExecutor executor = new LExecutor();
|
|
||||||
executor.privileged = true;
|
|
||||||
|
|
||||||
try{
|
|
||||||
//assembler has no variables, all the standard ones are null
|
|
||||||
executor.load(LAssembler.assemble(code, true));
|
|
||||||
}catch(Throwable ignored){
|
|
||||||
//if loading code
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//this updates map width/height global variables
|
//this updates map width/height global variables
|
||||||
logicVars.update();
|
logicVars.update();
|
||||||
|
|
||||||
//NOTE: all tile operations will call setNet for tiles, but that should have no overhead during world loading
|
LExecutor.runLogicScript(code, maxInstructionsExecution, loop);
|
||||||
//executions are limited to prevent infinite generation
|
|
||||||
for(int i = 1; i < maxInstructionsExecution; i++){
|
|
||||||
if(!loop && (executor.counter.numval >= executor.instructions.length || executor.counter.numval < 0)) break;
|
|
||||||
executor.runOnce();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user