3D spaceshooter with online scoreboard, online demos, ship building. Now entirely defunct, but might be resurrected
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
sector/src/net/sector/level/drivers/Navigator.java

190 lines
4.2 KiB

package net.sector.level.drivers;
import java.util.HashMap;
import java.util.Map.Entry;
import net.sector.util.Log;
/**
* AI drone controller with tasks
*
* @author Ondřej Hruška (MightyPork)
*/
public class Navigator {
private INavigated drone;
private TaskList tasks = new TaskList();
private HashMap<String, Boolean> taskFlags = new HashMap<String, Boolean>();
/**
* Implicit navigator constructor
*/
public Navigator() {}
/**
* Implicit navigator constructor
*
* @param tasks AI tasks to be used in this AI
*/
public Navigator(TaskList tasks) {
this.tasks = tasks.copy();
}
/**
* Navigator constructor for ship
*
* @param ship controlled ship
*/
public Navigator(INavigated ship) {
this.drone = ship;
}
/**
* Set ship to be controlled by this AI
*
* @param drone the ship
*/
public void setShip(INavigated drone) {
this.drone = drone;
}
/**
* Set ship desired speed
*
* @param desiredSpeed desired speed
*/
public void setShipDesiredSpeed(double desiredSpeed) {
this.drone.setDesiredSpeed(desiredSpeed);
}
/**
* Set ship level
*
* @param level level to set
*/
public void setShipLevel(int level) {
this.drone.setShipLevel(level);
}
/**
* Add AI task
*
* @param task AI task to add
*/
public void addTask(AiTask task) {
tasks.add(task);
}
/**
* Clear AI tasks
*/
public void clearTasks() {
tasks.clear();
}
/**
* Reset AI tasks (erase memories)
*/
public void resetTasks() {
for (AiTask task : tasks) {
task.reset();
}
}
/**
* On entity update hook
*/
public void onUpdate() {
taskFlags.clear();
for (AiTask task : tasks) {
if (task.fn == null || task.fn.equals("") || task.fn.equals("none")) continue;
boolean fnNeg = task.fn.startsWith("!");
FunctorBase functor = FunctorRegistry.get(task.fn.replace("!", ""));
if (functor == null) {
Log.e("AI error: requested functor '" + task.fn + "' does not exist. Task id=" + task.id + ", drone=" + drone);
continue;
}
if (task.type == EAiTaskType.TASK) {
// check if "if" condition is met.
String condition = task.typeArg;
String cond1 = condition;
if (condition != null && condition.length() != 0) {
condition = cond1 = condition.toLowerCase();
for (Entry<String, Boolean> flag : taskFlags.entrySet()) {
condition = condition.replace(flag.getKey().toLowerCase(), flag.getValue() ? "1" : "0");
}
if (!condition.matches("[\\(\\)\\|\\&01\\!\\+\\*]+")) {
Log.w("AI error: invalid condition pattern in task \"" + cond1 + "\" - possibly flag that hasn't been set yet.\nRemains = "
+ condition);
continue;
}
int iter = 0;
condition = condition.replaceAll("\\|\\|", "|");
condition = condition.replaceAll("\\&\\&", "&");
condition = condition.replaceAll("\\+", "|");
condition = condition.replaceAll("\\*", "&");
while (condition.length() > 1) {
// remove useless brackets
condition = condition.replaceAll("\\(([01])\\)", "$1");
// not
condition = condition.replaceAll("!0", "1");
condition = condition.replaceAll("!1", "0");
// and
condition = condition.replaceAll("0\\&0", "0");
condition = condition.replaceAll("0\\&1", "0");
condition = condition.replaceAll("1\\&0", "0");
condition = condition.replaceAll("1\\&1", "1");
// or
condition = condition.replaceAll("0\\|0", "0");
condition = condition.replaceAll("0\\|1", "1");
condition = condition.replaceAll("1\\|0", "1");
condition = condition.replaceAll("1\\|1", "1");
iter++;
if (iter >= 15) break;
}
}
if (condition == null || condition.equals("1")) functor.execute(drone, task.memory, task.args);
} else if (task.type == EAiTaskType.CHECK) {
if (task.typeArg == null) continue;
// perform check.
taskFlags.put(task.typeArg.toLowerCase(), (fnNeg ? true : false) ^ functor.execute(drone, task.memory, task.args));
}
}
}
/**
* Set driver to this navigator.
*
* @param driver the task list.
*/
public void setDriver(TaskList driver) {
if (driver == null) {
Log.e(new RuntimeException("Null driver assigned to entity " + this + "."));
return;
}
this.tasks = driver.copy();
//resetTasks();
}
}