Networked unit control / Mimic AI prototype

This commit is contained in:
Anuken 2020-04-11 10:03:47 -04:00
parent 7dca6b2a30
commit 3bb2b646db
32 changed files with 87 additions and 36 deletions

View File

@ -1 +0,0 @@
{fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:1,fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:range,type:float,size:4},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:damage,type:float,size:4},{name:lifetime,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:time,type:float,size:4},{name:type,type:mindustry.entities.bullet.BulletType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:1,fields:[{name:damage,type:float,size:4},{name:data,type:java.lang.Object,size:-1},{name:lifetime,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:time,type:float,size:4},{name:type,type:mindustry.entities.bullet.BulletType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:color,type:arc.graphics.Color,size:-1},{name:lifetime,type:float,size:4},{name:rotation,type:float,size:4},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:baseFlammability,type:float,size:4},{name:block,type:mindustry.world.Block,size:-1},{name:lifetime,type:float,size:4},{name:puddleFlammability,type:float,size:4},{name:tile,type:mindustry.world.Tile,size:-1},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:color,type:arc.graphics.Color,size:-1},{name:lifetime,type:float,size:4},{name:offsetX,type:float,size:4},{name:offsetY,type:float,size:4},{name:rotation,type:float,size:4},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:1,fields:[{name:color,type:arc.graphics.Color,size:-1},{name:data,type:java.lang.Object,size:-1},{name:lifetime,type:float,size:4},{name:offsetX,type:float,size:4},{name:offsetY,type:float,size:4},{name:rotation,type:float,size:4},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:baseRotation,type:float,size:4},{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:1,fields:[{name:baseRotation,type:float,size:4},{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:range,type:float,size:4},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:1,fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:range,type:float,size:4},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:admin,type:boolean,size:1},{name:color,type:arc.graphics.Color,size:-1},{name:lastText,type:java.lang.String,size:-1},{name:mouseX,type:float,size:4},{name:mouseY,type:float,size:4},{name:name,type:java.lang.String,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:textFadeTime,type:float,size:4},{name:typing,type:boolean,size:1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:accepting,type:float,size:4},{name:amount,type:float,size:4},{name:generation,type:int,size:4},{name:lastRipple,type:float,size:4},{name:liquid,type:mindustry.type.Liquid,size:-1},{name:tile,type:mindustry.world.Tile,size:-1},{name:updateTime,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:color,type:arc.graphics.Color,size:-1},{name:lifetime,type:float,size:4},{name:offsetX,type:float,size:4},{name:offsetY,type:float,size:4},{name:rotation,type:float,size:4},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:1,fields:[{name:color,type:arc.graphics.Color,size:-1},{name:data,type:java.lang.Object,size:-1},{name:lifetime,type:float,size:4},{name:offsetX,type:float,size:4},{name:offsetY,type:float,size:4},{name:rotation,type:float,size:4},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:health,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:1,fields:[{name:health,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:updateFlow,type:boolean,size:1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:2,fields:[{name:health,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:1,fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:range,type:float,size:4},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:1,fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:range,type:float,size:4},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:1,fields:[{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -0,0 +1,31 @@
package mindustry.ai.types;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
public class MimicAI extends AIController{
public @Nullable Unitc control;
public MimicAI(@Nullable Unitc control){
this.control = control;
}
public MimicAI(){
}
@Override
public void update(){
if(control != null){
unit.controlWeapons(control.isRotate(), control.isShooting());
//TODO this isn't accurate
unit.moveAt(Tmp.v1.set(control.vel()).limit(unit.type().speed));
if(control.isShooting()){
unit.aimLook(control.aimX(), control.aimY());
}else{
unit.lookAt(unit.vel().angle());
}
}
}
}

View File

@ -12,6 +12,8 @@ import static mindustry.Vars.net;
@Component
abstract class FlyingComp implements Posc, Velc, Healthc, Hitboxc{
private static final Vec2 tmp1 = new Vec2(), tmp2 = new Vec2();
@Import float x, y, drag;
@Import Vec2 vel;
@ -37,9 +39,9 @@ abstract class FlyingComp implements Posc, Velc, Healthc, Hitboxc{
}
void moveAt(Vec2 vector, float acceleration){
Vec2 t = Tmp.v3.set(vector).scl(floorSpeedMultiplier()); //target vector
Tmp.v1.set(t).sub(vel).limit(acceleration * vector.len()); //delta vector
vel.add(Tmp.v1);
Vec2 t = tmp1.set(vector).scl(floorSpeedMultiplier()); //target vector
tmp2.set(t).sub(vel).limit(acceleration * vector.len()); //delta vector
vel.add(tmp2);
}
float floorSpeedMultiplier(){

View File

@ -956,6 +956,7 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
Events.fire(new BlockDestroyEvent(tile));
block.breakSound.at(tile);
onDestroyed();
tile.remove();
remove();
}

View File

@ -34,6 +34,11 @@ abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitbox
lookAt(pos);
}
public void aimLook(float x, float y){
aim(x, y);
lookAt(x, y);
}
@Override
public float clipSize(){
return type.region.getWidth() * 2f;
@ -109,6 +114,14 @@ abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitbox
lookAt(angleTo(pos));
}
public void lookAt(float x, float y){
lookAt(angleTo(x, y));
}
public boolean isAI(){
return controller instanceof AIController;
}
@Override
public void afterRead(){
//set up type info after reading

View File

@ -21,7 +21,8 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
/** weapon mount array, never null */
@ReadOnly WeaponMount[] mounts = {};
@ReadOnly float range;
@ReadOnly transient float range, aimX, aimY;
@ReadOnly transient boolean isRotate, isShooting;
boolean inRange(Position other){
return within(other, range);
@ -41,6 +42,8 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
mount.rotate = rotate;
mount.shoot = shoot;
}
isRotate = rotate;
isShooting = shoot;
}
void aim(Position pos){
@ -59,6 +62,9 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
mount.aimX = x;
mount.aimY = y;
}
aimX = x;
aimY = y;
}
/** Update shooting and rotation for this unit. */

View File

@ -4,6 +4,7 @@ import arc.*;
import arc.Graphics.*;
import arc.Graphics.Cursor.*;
import arc.graphics.g2d.*;
import arc.input.*;
import arc.math.*;
import arc.math.geom.*;
import arc.scene.*;
@ -13,6 +14,8 @@ import arc.scene.ui.layout.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import mindustry.*;
import mindustry.ai.types.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
@ -170,17 +173,27 @@ public class DesktopInput extends InputHandler{
Core.camera.position.lerpDelta(player, 0.08f);
}
//TODO remove: debug unit possession
if(!scene.hasMouse()){
if(Core.input.keyTap(Binding.select)){
Unitc unit = Units.closest(state.rules.defaultTeam, Core.input.mouseWorld().x, Core.input.mouseWorld().y, 40f, u -> true);
Unitc unit = Units.closest(player.team(), Core.input.mouseWorld().x, Core.input.mouseWorld().y, 40f, u -> true);
if(unit != null){
unit.hitbox(Tmp.r1);
if(Tmp.r1.contains(Core.input.mouseWorld())){
player.unit(unit);
Call.onUnitControl(player, unit);
}
}
}
if(Core.input.keyTap(KeyCode.Q) && !player.dead()){
Fx.commandSend.at(player);
Units.nearby(player.team(), player.x(), player.y(), 200f, u -> {
if(u.isAI()){
u.controller(new MimicAI(player.unit()));
}
});
}
}
if(!player.dead() && !state.isPaused() && !(Core.scene.getKeyboardFocus() instanceof TextField)){
updateMovement(player.unit());
}

View File

@ -168,6 +168,16 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
Core.app.post(() -> Events.fire(new TapConfigEvent(tile, player, value)));
}
@Remote(targets = Loc.both, called = Loc.server, forward = true)
public static void onUnitControl(Playerc player, @Nullable Unitc unit){
if(unit == null){
player.clearUnit();
//make sure it's AI controlled, so players can't overwrite each other
}else if(unit.isAI() && unit.team() == player.team()){
player.unit(unit);
}
}
public Eachable<BuildRequest> allRequests(){
return cons -> {
for(BuildRequest request : player.builder().requests()) cons.get(request);