Automatic assignment of entities

This commit is contained in:
Anuken 2020-04-27 01:31:41 -04:00
parent 2f3c098b50
commit a4d49f5d17
11 changed files with 102 additions and 29 deletions

View file

@ -173,7 +173,8 @@ public class EntityProcess extends BaseProcessor{
GroupDef an = group.annotation(GroupDef.class);
Array<Stype> types = types(an, GroupDef::value).map(this::interfaceToComp);
Array<Stype> collides = types(an, GroupDef::collide);
groupDefs.add(new GroupDefinition(group.name(), ClassName.bestGuess(packageName + "." + interfaceName(types.first())), types, an.spatial(), an.mapping(), collides));
groupDefs.add(new GroupDefinition(group.name().startsWith("g") ? group.name().substring(1) : group.name(),
ClassName.bestGuess(packageName + "." + interfaceName(types.first())), types, an.spatial(), an.mapping(), collides));
}
ObjectMap<String, Selement> usedNames = new ObjectMap<>();
@ -436,7 +437,7 @@ public class EntityProcess extends BaseProcessor{
for(GroupDefinition group : groupDefs){
for(Stype collide : group.collides){
groupUpdate.addStatement("$L.collide($L)", group.name, collide.name());
groupUpdate.addStatement("$L.collide($L)", group.name, collide.name().startsWith("g") ? collide.name().substring(1) : collide.name());
}
}

View file

@ -0,0 +1 @@
{version:1,fields:[{name:admin,type:boolean,size:1},{name:color,type:arc.graphics.Color,size:-1},{name:deathTimer,type:float,size:4},{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

@ -54,7 +54,7 @@ public class Fx{
reset();
}),
unitSpirit = new Effect(20f, e -> {
unitSpirit = new Effect(17f, e -> {
if(!(e.data instanceof Position)) return;
Position to = e.data();

View file

@ -5,6 +5,7 @@ import arc.assets.*;
import arc.audio.*;
import arc.graphics.g2d.*;
import arc.input.*;
import arc.math.*;
import arc.scene.ui.*;
import arc.struct.*;
import arc.util.*;
@ -68,14 +69,19 @@ public class Control implements ApplicationListener, Loadable{
});
Events.on(WorldLoadEvent.class, event -> {
//TODO test this
app.post(() -> app.post(() -> {
//TODO 0,0 seems like a bad choice?
if(Mathf.zero(player.x()) && Mathf.zero(player.y())){
Tilec core = state.teams.closestCore(0, 0, player.team());
if(core != null){
player.set(core);
camera.position.set(core);
}
}));
}else{
camera.position.set(player);
}
});
Events.on(SaveLoadEvent.class, event -> {
input.checkUnit();
});
Events.on(ResetEvent.class, event -> {

View file

@ -6,37 +6,37 @@ import mindustry.gen.*;
class AllDefs{
@GroupDef(value = Entityc.class, mapping = true)
class all{
class gall{
}
@GroupDef(value = Playerc.class, mapping = true)
class player{
class gplayer{
}
@GroupDef(value = Bulletc.class, spatial = true, collide = {unit.class})
class bullet{
@GroupDef(value = Bulletc.class, spatial = true, collide = {gunit.class})
class gbullet{
}
@GroupDef(value = Unitc.class, spatial = true, collide = {unit.class}, mapping = true)
class unit{
@GroupDef(value = Unitc.class, spatial = true, collide = {gunit.class}, mapping = true)
class gunit{
}
@GroupDef(Tilec.class)
class tile{
class gtile{
}
@GroupDef(value = Syncc.class, mapping = true)
class sync{
class gsync{
}
@GroupDef(Drawc.class)
class draw{
class gdraw{
}
}

View file

@ -126,6 +126,24 @@ public class Units{
return result;
}
/** Returns the closest ally of this team. Filter by predicate. No range. */
public static Unitc closest(Team team, float x, float y, Boolf<Unitc> predicate){
result = null;
cdist = 0f;
for(Unitc e : Groups.unit){
if(!predicate.get(e) || e.team() != team) continue;
float dist = e.dst2(x, y);
if(result == null || dist < cdist){
result = e;
cdist = dist;
}
}
return result;
}
/** Returns the closest ally of this team. Filter by predicate. */
public static Unitc closest(Team team, float x, float y, float range, Boolf<Unitc> predicate){
result = null;

View file

@ -25,6 +25,8 @@ import static mindustry.Vars.*;
@EntityDef(value = {Playerc.class}, serialize = false)
@Component
abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Drawc{
static final float deathDelay = 30f;
@NonNull @ReadOnly Unitc unit = Nulls.unit;
@ReadOnly Team team = Team.sharded;
@ -33,6 +35,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
boolean admin, typing;
Color color = new Color();
float mouseX, mouseY;
float deathTimer;
String lastText = "";
float textFadeTime;
@ -76,8 +79,12 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
x(unit.x());
y(unit.y());
unit.team(team);
deathTimer = 0;
}else if(core != null){
core.requestSpawn((Playerc)this);
deathTimer += Time.delta();
if(deathTimer >= deathDelay){
core.requestSpawn((Playerc)this);
}
}
textFadeTime -= Time.delta() / (60 * 5);

View file

@ -91,6 +91,10 @@ public class EventType{
}
}
public static class SaveLoadEvent{
}
public static class ClientCreateEvent{
}

View file

@ -55,6 +55,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public boolean droppingItem;
public Group uiGroup;
public boolean isShooting, isBuilding = true, buildWasAutoPaused = false;
public UnitType controlledType;
protected @Nullable Schematic lastSchematic;
protected GestureDetector detector;
@ -174,9 +175,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
player.clearUnit();
//make sure it's AI controlled, so players can't overwrite each other
}else if(unit.isAI() && unit.team() == player.team()){
Time.runTask(Fx.unitSpirit.lifetime * 0.87f, () -> {
player.unit(unit);
});
player.unit(unit);
Time.run(Fx.unitSpirit.lifetime, () -> Fx.unitControl.at(unit.x(), unit.y(), 0f, unit));
if(!player.dead()){
Fx.unitSpirit.at(player.x(), player.y(), 0f, unit);
@ -198,6 +197,30 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public void update(){
player.typing(ui.chatfrag.shown());
if(!player.dead()){
controlledType = player.unit().type();
}
if(controlledType != null && player.dead()){
Unitc unit = Units.closest(player.team(), player.x(), player.y(), u -> !u.isPlayer() && u.type() == controlledType);
if(unit != null){
Call.onUnitControl(player, unit);
}
}
}
public void checkUnit(){
if(controlledType != null){
Unitc unit = Units.closest(player.team(), player.x(), player.y(), u -> !u.isPlayer() && u.type() == controlledType);
if(unit != null){
if(net.client()){
Call.onUnitControl(player, unit);
}else{
unit.controller(player);
}
}
}
}
public float getMouseX(){

View file

@ -1,17 +1,18 @@
package mindustry.io;
import arc.*;
import arc.files.*;
import arc.struct.*;
import arc.files.Fi;
import arc.util.io.CounterInputStream;
import arc.util.io.FastDeflaterOutputStream;
import mindustry.Vars;
import arc.util.io.*;
import mindustry.*;
import mindustry.game.EventType.*;
import mindustry.io.legacy.*;
import mindustry.io.versions.*;
import mindustry.world.WorldContext;
import mindustry.world.*;
import java.io.*;
import java.util.Arrays;
import java.util.zip.InflaterInputStream;
import java.util.*;
import java.util.zip.*;
import static mindustry.Vars.*;
@ -151,6 +152,7 @@ public class SaveIO{
SaveVersion ver = versions.get(version);
ver.read(stream, counter, context);
Events.fire(new SaveLoadEvent());
}catch(Exception e){
throw new SaveException(e);
}finally{

View file

@ -1,5 +1,7 @@
package mindustry.io;
import arc.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import arc.util.io.*;
@ -69,7 +71,9 @@ public abstract class SaveVersion extends SaveFileReader{
"rules", JsonIO.write(state.rules),
"mods", JsonIO.write(mods.getModStrings().toArray(String.class)),
"width", world.width(),
"height", world.height()
"height", world.height(),
"viewpos", Tmp.v1.set(player == null ? Vec2.ZERO : player).toString(),
"controlledType", headless || control.input.controlledType == null ? "null" : control.input.controlledType.name
).merge(tags));
}
@ -83,6 +87,14 @@ public abstract class SaveVersion extends SaveFileReader{
if(state.rules.spawns.isEmpty()) state.rules.spawns = defaultWaves.get();
lastReadBuild = map.getInt("build", -1);
if(!headless){
Tmp.v1.tryFromString(map.get("viewpos"));
Core.camera.position.set(Tmp.v1);
player.set(Tmp.v1);
control.input.controlledType = content.getByName(ContentType.unit, map.get("controlledType"));
}
Map worldmap = maps.byName(map.get("mapname", "\\\\\\"));
state.map = worldmap == null ? new Map(StringMap.of(
"name", map.get("mapname", "Unknown"),
@ -184,7 +196,6 @@ public abstract class SaveVersion extends SaveFileReader{
//read blocks
for(int i = 0; i < width * height; i++){
int x = i % width, y = i / width;
Block block = content.block(stream.readShort());
Tile tile = context.tile(i);
if(block == null) block = Blocks.air;