mirror of
https://github.com/Anuken/Mindustry.git
synced 2026-04-28 00:10:48 -07:00
Automatic assignment of entities
This commit is contained in:
parent
2f3c098b50
commit
a4d49f5d17
11 changed files with 102 additions and 29 deletions
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}]}
|
||||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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 -> {
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -91,6 +91,10 @@ public class EventType{
|
|||
}
|
||||
}
|
||||
|
||||
public static class SaveLoadEvent{
|
||||
|
||||
}
|
||||
|
||||
public static class ClientCreateEvent{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(){
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue