it never ends

This commit is contained in:
Anuken
2020-02-05 13:03:22 -05:00
parent a7b39e56bd
commit da97aee8e4
111 changed files with 1327 additions and 1644 deletions

View File

@@ -122,7 +122,7 @@ public class BlockIndexer{
for(int x = 0; x < world.width(); x++){
for(int y = 0; y < world.height(); y++){
Tile tile = world.tile(x, y);
if(tile.getTeam() == team){
if(tile.team() == team){
int quadrantX = tile.x / quadrantSize;
int quadrantY = tile.y / quadrantSize;
structQuadrant(team).set(quadrantX, quadrantY);
@@ -185,7 +185,7 @@ public class BlockIndexer{
if(other == null) continue;
if(other.getTeam() == team && !intSet.contains(other.pos()) && other.entity != null && pred.get(other)){
if(other.team() == team && !intSet.contains(other.pos()) && other.entity != null && pred.get(other)){
cons.get(other);
any = true;
intSet.add(other.pos());
@@ -254,7 +254,7 @@ public class BlockIndexer{
if(other == null) continue;
if(other.entity == null || other.getTeam() != team || !pred.get(other) || !other.block().targetable)
if(other.entity == null || other.team() != team || !pred.get(other) || !other.block().targetable)
continue;
Tilec e = other.entity;
@@ -305,8 +305,8 @@ public class BlockIndexer{
}
private void process(Tile tile){
if(tile.block().flags.size() > 0 && tile.getTeam() != Team.derelict){
ObjectSet<Tile>[] map = getFlagged(tile.getTeam());
if(tile.block().flags.size() > 0 && tile.team() != Team.derelict){
ObjectSet<Tile>[] map = getFlagged(tile.team());
for(BlockFlag flag : tile.block().flags){
@@ -316,9 +316,9 @@ public class BlockIndexer{
map[flag.ordinal()] = arr;
}
typeMap.put(tile.pos(), new TileIndex(tile.block().flags, tile.getTeam()));
typeMap.put(tile.pos(), new TileIndex(tile.block().flags, tile.team()));
}
activeTeams.add(tile.getTeam());
activeTeams.add(tile.team());
if(ores == null) return;
@@ -362,7 +362,7 @@ public class BlockIndexer{
GridBits bits = structQuadrant(team);
//fast-set this quadrant to 'occupied' if the tile just placed is already of this team
if(tile.getTeam() == team && tile.entity != null && tile.block().targetable){
if(tile.team() == team && tile.entity != null && tile.block().targetable){
bits.set(quadrantX, quadrantY);
continue; //no need to process futher
}
@@ -374,7 +374,7 @@ public class BlockIndexer{
for(int y = quadrantY * quadrantSize; y < world.height() && y < (quadrantY + 1) * quadrantSize; y++){
Tile result = world.ltile(x, y);
//when a targetable block is found, mark this quadrant as occupied and stop searching
if(result.entity != null && result.getTeam() == team){
if(result.entity != null && result.team() == team){
bits.set(quadrantX, quadrantY);
break outer;
}

View File

@@ -7,7 +7,6 @@ import arc.util.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.world.*;

View File

@@ -4,6 +4,8 @@ import arc.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import mindustry.entities.*;
import mindustry.gen.*;
@@ -34,6 +36,38 @@ public class Fx{
}),
itemTransfer = new Effect(30f, e -> {
if(!(e.data instanceof Position)) return;
Position to = e.data();
Tmp.v1.set(e.x, e.y).interpolate(Tmp.v2.set(to), e.fin(), Interpolation.pow3)
.add(Tmp.v2.sub(e.x, e.y).nor().rotate90(1).scl(Mathf.randomSeedRange(e.id, 1f) * e.fslope() * 10f));
float x = Tmp.v1.x, y = Tmp.v1.y;
stroke(e.fslope() * 2f, Pal.accent);
Lines.circle(x, y, e.fslope() * 2f);
color(e.color);
Fill.circle(x, y, e.fslope() * 1.5f);
}),
lightning = new Effect(10f, 500f, e -> {
if(!(e.data instanceof Array)) return;
Array<Vec2> lines = e.data();
stroke(3f * e.fout());
color(e.color, Color.white, e.fin());
beginLine();
linePoint(e.x, e.y);
lines.each(Lines::linePoint);
endLine();
int i = 0;
for(Vec2 p : lines){
Fill.square(p.x, p.y, (5f - (float)i++ / lines.size * 2f) * e.fout(), 45);
}
}),
commandSend = new Effect(28, e -> {
color(Pal.command);
stroke(e.fout() * 2f);

View File

@@ -29,12 +29,10 @@ public class ContentLoader{
private @Nullable Content lastAdded;
private ObjectSet<Cons<Content>> initialization = new ObjectSet<>();
private ContentList[] content = {
new Fx(),
new Items(),
new StatusEffects(),
new Liquids(),
new Bullets(),
new Mechs(),
new UnitTypes(),
new Blocks(),
new Loadouts(),

View File

@@ -3,20 +3,19 @@ package mindustry.core;
import arc.*;
import arc.assets.*;
import arc.audio.*;
import arc.struct.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.input.*;
import arc.math.geom.*;
import arc.scene.ui.*;
import arc.struct.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.core.GameState.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.gen.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.input.*;
import mindustry.maps.Map;
import mindustry.type.*;
@@ -63,21 +62,19 @@ public class Control implements ApplicationListener, Loadable{
});
Events.on(PlayEvent.class, event -> {
player.team(netServer.assignTeam(player, Groups.player.all()));
player.dead(true);
player.team(netServer.assignTeam(player));
player.add();
state.set(State.playing);
});
Events.on(WorldLoadEvent.class, event -> {
Core.app.post(() -> Core.app.post(() -> {
if(net.active() && player.closestCore() != null){
//set to closest core since that's where the player will probably respawn; prevents camera jumps
Core.camera.position.set(player.dead() ? player.closestCore() : player);
}else{
//locally, set to player position since respawning occurs immediately
Core.camera.position.set(player);
//TODO test this
app.post(() -> app.post(() -> {
//TODO 0,0 seems like a bad choice?
Tilec core = state.teams.closestCore(0, 0, player.team());
if(core != null){
camera.position.set(core);
}
}));
});
@@ -118,7 +115,7 @@ public class Control implements ApplicationListener, Loadable{
if(state.rules.pvp && !net.active()){
try{
net.host(port);
player.isAdmin = true;
player.admin(true);
}catch(IOException e){
ui.showException("$server.error", e);
Core.app.post(() -> state.set(State.menu));
@@ -139,7 +136,7 @@ public class Control implements ApplicationListener, Loadable{
});
Events.on(BlockDestroyEvent.class, e -> {
if(e.tile.getTeam() == player.team()){
if(e.tile.team() == player.team()){
state.stats.buildingsDestroyed++;
}
});
@@ -178,7 +175,7 @@ public class Control implements ApplicationListener, Loadable{
Events.on(UnitDestroyEvent.class, e -> {
if(world.isZone()){
data.unlockContent(e.unit.getType());
data.unlockContent(e.unit.type());
}
});
}
@@ -204,11 +201,9 @@ public class Control implements ApplicationListener, Loadable{
}
void createPlayer(){
player = new Playerc();
player.name = Core.settings.getString("name");
player.color.set(Core.settings.getInt("color-0"));
player.isLocal() = true;
player.isMobile = mobile;
//player = new Playerc();
player.name(Core.settings.getString("name"));
player.color().set(Core.settings.getInt("color-0"));
if(mobile){
input = new MobileInput();
@@ -304,14 +299,14 @@ public class Control implements ApplicationListener, Loadable{
}
}
Geometry.circle(coreb.x(), coreb.y(), 10, (cx, cy) -> {
Geometry.circle(coreb.x, coreb.y, 10, (cx, cy) -> {
Tile tile = world.ltile(cx, cy);
if(tile != null && tile.getTeam() == state.rules.defaultTeam && !(tile.block() instanceof CoreBlock)){
if(tile != null && tile.team() == state.rules.defaultTeam && !(tile.block() instanceof CoreBlock)){
tile.remove();
}
});
Geometry.circle(coreb.x(), coreb.y(), 5, (cx, cy) -> world.tile(cx, cy).clearOverlay());
Geometry.circle(coreb.x, coreb.y, 5, (cx, cy) -> world.tile(cx, cy).clearOverlay());
world.endMapLoad();

View File

@@ -56,7 +56,7 @@ public class Logic implements ApplicationListener{
}
}
TeamData data = state.teams.get(tile.getTeam());
TeamData data = state.teams.get(tile.team());
//remove existing blocks that have been placed here.
//painful O(n) iteration + copy
@@ -78,7 +78,7 @@ public class Logic implements ApplicationListener{
while(it.hasNext()){
BrokenBlock b = it.next();
Block block = content.block(b.block);
if(event.tile.block().bounds(event.tile.x, event.tile.y, Tmp.r1).overlaps(block.bounds(b.x(), b.y(), Tmp.r2))){
if(event.tile.block().bounds(event.tile.x, event.tile.y, Tmp.r1).overlaps(block.bounds(b.x, b.y, Tmp.r2))){
it.remove();
}
}
@@ -120,7 +120,7 @@ public class Logic implements ApplicationListener{
state.rules = new Rules();
state.stats = new Stats();
entities.clear();
Groups.all.clear();
Time.clear();
Events.fire(new ResetEvent());
}
@@ -205,7 +205,7 @@ public class Logic implements ApplicationListener{
if(!state.is(State.menu)){
if(!net.client()){
//TODO
//state.enemies = Groups.unit.count(b -> b.getTeam() == state.rules.waveTeam && b.countsAsEnemy());
//state.enemies = Groups.unit.count(b -> b.team() == state.rules.waveTeam && b.countsAsEnemy());
}
if(!state.isPaused()){

View File

@@ -11,10 +11,6 @@ import arc.util.serialization.*;
import mindustry.*;
import mindustry.annotations.Annotations.*;
import mindustry.core.GameState.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
@@ -22,7 +18,6 @@ import mindustry.net.Administration.*;
import mindustry.net.Net.*;
import mindustry.net.*;
import mindustry.net.Packets.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.modules.*;
@@ -127,7 +122,8 @@ public class NetClient implements ApplicationListener{
net.handleClient(InvokePacket.class, packet -> {
packet.writeBuffer.position(0);
RemoteReadClient.readPacket(packet.writeBuffer, packet.type);
//TODO fix remote read client
// RemoteReadClient.readPacket(packet.writeBuffer, packet.type);
});
}
@@ -180,7 +176,8 @@ public class NetClient implements ApplicationListener{
//invoke event for all clients but also locally
//this is required so other clients get the correct name even if they don't know who's sending it yet
Call.sendMessage(message, colorizeName(player.id(), player.name()), player);
//TODO uncomment when it works
//Call.sendMessage(message, colorizeName(player.id(), player.name()), player);
}else{
//log command to console but with brackets
Log.info("<&y{0}: &lm{1}&lg>", player.name(), message);
@@ -298,7 +295,7 @@ public class NetClient implements ApplicationListener{
@Remote(variants = Variant.both)
public static void onWorldDataBegin(){
entities.clear();
Groups.all.clear();
netClient.removed.clear();
logic.reset();
@@ -457,7 +454,8 @@ public class NetClient implements ApplicationListener{
connecting = false;
ui.join.hide();
net.setClientLoaded(true);
Core.app.post(Call::connectConfirm);
//TODO connect confirm
//Core.app.post(Call::connectConfirm);
Time.runTask(40f, platform::updateRPC);
Core.app.post(() -> ui.loadfrag.hide());
}
@@ -471,7 +469,7 @@ public class NetClient implements ApplicationListener{
quiet = false;
lastSent = 0;
entities.clear();
Groups.all.clear();
ui.chatfrag.clearMessages();
}
@@ -505,7 +503,8 @@ public class NetClient implements ApplicationListener{
}
void sync(){
//TODO implement
/*
if(timer.get(0, playerSyncTime)){
BuildRequest[] requests;
//limit to 10 to prevent buffer overflows
@@ -528,7 +527,7 @@ public class NetClient implements ApplicationListener{
if(timer.get(1, 60)){
Call.onPing(Time.millis());
}
}*/
}
String getUsid(String ip){

View File

@@ -9,16 +9,12 @@ import arc.util.*;
import arc.util.CommandHandler.*;
import arc.util.io.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.core.GameState.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.net.Administration;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.game.Teams.*;
import mindustry.gen.*;
import mindustry.net.*;
import mindustry.net.Administration.*;
import mindustry.net.Packets.*;
@@ -161,16 +157,14 @@ public class NetServer implements ApplicationListener{
boolean preventDuplicates = headless && netServer.admins.getStrict();
if(preventDuplicates){
for(Playerc player : Groups.player.all()){
if(player.name.trim().equalsIgnoreCase(packet.name.trim())){
con.kick(KickReason.nameInUse);
return;
}
if(Groups.player.contains(p -> p.name().trim().equalsIgnoreCase(packet.name.trim()))){
con.kick(KickReason.nameInUse);
return;
}
if(player.uuid != null && player.usid != null && (player.uuid.equals(packet.uuid) || player.usid.equals(packet.usid))){
con.kick(KickReason.idInUse);
return;
}
if(Groups.player.contains(player -> player.uuid().equals(packet.uuid) || player.usid().equals(packet.usid))){
con.kick(KickReason.idInUse);
return;
}
}
@@ -194,17 +188,15 @@ public class NetServer implements ApplicationListener{
con.modclient = true;
}
Playerc player = new Playerc();
player.isAdmin = admins.isAdmin(uuid, packet.usid);
player.con = con;
player.usid = packet.usid;
player.name = packet.name;
player.uuid = uuid;
player.isMobile = packet.mobile;
player.dead = true;
player.setNet(player.x, player.y);
player.color.set(packet.color);
player.color.a = 1f;
//TODO place instance of player here
Playerc player = null;//new Playerc();
player.admin(admins.isAdmin(uuid, packet.usid));
player.con(con);
player.con().usid = packet.usid;
player.con().uuid = uuid;
player.con().mobile = packet.mobile;
player.name(packet.name);
player.color().set(packet.color).a(1f);
try{
writeBuffer.position(0);
@@ -218,7 +210,7 @@ public class NetServer implements ApplicationListener{
con.player = player;
//playing in pvp mode automatically assigns players to teams
player.team(assignTeam(player, Groups.player.all()));
player.team(assignTeam(player));
sendWorldData(player);
@@ -230,7 +222,8 @@ public class NetServer implements ApplicationListener{
net.handleServer(InvokePacket.class, (con, packet) -> {
if(con.player == null) return;
try{
RemoteReadServer.readPacket(packet.writeBuffer, packet.type, con.player);
//TODO uncomment when compilation works
//RemoteReadServer.readPacket(packet.writeBuffer, packet.type, con.player);
}catch(ValidateException e){
Log.debug("Validation failed for '{0}': {1}", e.player, e.getMessage());
}catch(RuntimeException e){
@@ -279,7 +272,7 @@ public class NetServer implements ApplicationListener{
});
clientCommands.<Playerc>register("t", "<message...>", "Send a message only to your teammates.", (args, player) -> {
Groups.player.all().each(p -> p.getTeam() == player.team(), o -> o.sendMessage(args[0], player, "[#" + player.team().color.toString() + "]<T>" + NetClient.colorizeName(player.id, player.name())));
Groups.player.each(p -> p.team() == player.team(), o -> o.sendMessage(args[0], player, "[#" + player.team().color.toString() + "]<T>" + NetClient.colorizeName(player.id(), player.name())));
});
//duration of a a kick in seconds
@@ -301,7 +294,7 @@ public class NetServer implements ApplicationListener{
this.map = map;
this.task = Timer.schedule(() -> {
if(!checkPass()){
Call.sendMessage(Strings.format("[lightgray]Vote failed. Not enough votes to kick[orange] {0}[lightgray].", target.name));
Call.sendMessage(Strings.format("[lightgray]Vote failed. Not enough votes to kick[orange] {0}[lightgray].", target.name()));
map[0] = null;
task.cancel();
}
@@ -310,17 +303,17 @@ public class NetServer implements ApplicationListener{
void vote(Playerc player, int d){
votes += d;
voted.addAll(player.uuid, admins.getInfo(player.uuid).lastIP);
voted.addAll(player.uuid(), admins.getInfo(player.uuid()).lastIP);
Call.sendMessage(Strings.format("[orange]{0}[lightgray] has voted to kick[orange] {1}[].[accent] ({2}/{3})\n[lightgray]Type[orange] /vote <y/n>[] to agree.",
player.name(), target.name, votes, votesRequired()));
player.name(), target.name(), votes, votesRequired()));
}
boolean checkPass(){
if(votes >= votesRequired()){
Call.sendMessage(Strings.format("[orange]Vote passed.[scarlet] {0}[orange] will be banned from the server for {1} minutes.", target.name, (kickDuration/60)));
Call.sendMessage(Strings.format("[orange]Vote passed.[scarlet] {0}[orange] will be banned from the server for {1} minutes.", target.name(), (kickDuration/60)));
target.getInfo().lastKicked = Time.millis() + kickDuration*1000;
Groups.player.all().each(p -> p.uuid != null && p.uuid.equals(target.uuid), p -> p.con.kick(KickReason.vote));
Groups.player.each(p -> p.uuid().equals(target.uuid()), p -> p.kick(KickReason.vote));
map[0] = null;
task.cancel();
return true;
@@ -352,25 +345,24 @@ public class NetServer implements ApplicationListener{
if(args.length == 0){
StringBuilder builder = new StringBuilder();
builder.append("[orange]Players to kick: \n");
for(Playerc p : Groups.player.all()){
if(p.isAdmin || p.con == null || p == player) continue;
builder.append("[lightgray] ").append(p.name).append("[accent] (#").append(p.id).append(")\n");
}
Groups.player.each(p -> !p.admin() && p.con() != null && p != player, p -> {
builder.append("[lightgray] ").append(p.name()).append("[accent] (#").append(p.id()).append(")\n");
});
player.sendMessage(builder.toString());
}else{
Playerc found;
if(args[0].length() > 1 && args[0].startsWith("#") && Strings.canParseInt(args[0].substring(1))){
int id = Strings.parseInt(args[0].substring(1));
found = Groups.player.find(p -> p.id == id);
found = Groups.player.find(p -> p.id() == id);
}else{
found = Groups.player.find(p -> p.name.equalsIgnoreCase(args[0]));
found = Groups.player.find(p -> p.name().equalsIgnoreCase(args[0]));
}
if(found != null){
if(found.isAdmin){
if(found.admin()){
player.sendMessage("[scarlet]Did you really expect to be able to kick an admin?");
}else if(found.isLocal){
}else if(found.isLocal()){
player.sendMessage("[scarlet]Local players cannot be kicked.");
}else if(found.team() != player.team()){
player.sendMessage("[scarlet]Only players on your team can be kicked.");
@@ -401,7 +393,7 @@ public class NetServer implements ApplicationListener{
}
//hosts can vote all they want
if(player.uuid != null && (currentlyKicking[0].voted.contains(player.uuid) || currentlyKicking[0].voted.contains(admins.getInfo(player.uuid).lastIP))){
if((currentlyKicking[0].voted.contains(player.uuid()) || currentlyKicking[0].voted.contains(admins.getInfo(player.uuid()).lastIP))){
player.sendMessage("[scarlet]You've already voted. Sit down.");
return;
}
@@ -432,7 +424,7 @@ public class NetServer implements ApplicationListener{
}
player.getInfo().lastSyncTime = Time.millis();
Call.onWorldDataBegin(player.con);
Call.onWorldDataBegin(player.con());
netServer.sendWorldData(player);
}
});
@@ -442,6 +434,10 @@ public class NetServer implements ApplicationListener{
return 2 + (Groups.player.size() > 4 ? 1 : 0);
}
public Team assignTeam(Playerc current){
return assigner.assign(current, Groups.player);
}
public Team assignTeam(Playerc current, Iterable<Playerc> players){
return assigner.assign(current, players);
}
@@ -452,30 +448,30 @@ public class NetServer implements ApplicationListener{
NetworkIO.writeWorld(player, def);
WorldStream data = new WorldStream();
data.stream = new ByteArrayInputStream(stream.toByteArray());
player.con.sendStream(data);
player.con().sendStream(data);
Log.debug("Packed {0} compressed bytes of world data.", stream.size());
}
public static void onDisconnect(Playerc player, String reason){
//singleplayer multiplayer wierdness
if(player.con == null){
if(player.con() == null){
player.remove();
return;
}
if(!player.con.hasDisconnected){
if(player.con.hasConnected){
if(!player.con().hasDisconnected){
if(player.con().hasConnected){
Events.fire(new PlayerLeave(player));
if(Config.showConnectMessages.bool()) Call.sendMessage("[accent]" + player.name + "[accent] has disconnected.");
Call.onPlayerDisconnect(player.id);
if(Config.showConnectMessages.bool()) Call.sendMessage("[accent]" + player.name() + "[accent] has disconnected.");
Call.onPlayerDisconnect(player.id());
}
if(Config.showConnectMessages.bool()) Log.info("&lm[{1}] &lc{0} has disconnected. &lg&fi({2})", player.name(), player.uuid, reason);
if(Config.showConnectMessages.bool()) Log.info("&lm[{1}] &lc{0} has disconnected. &lg&fi({2})", player.name(), player.uuid(), reason);
}
player.remove();
player.con.hasDisconnected = true;
player.con().hasDisconnected = true;
}
@Remote(targets = Loc.client, unreliable = true)
@@ -491,7 +487,9 @@ public class NetServer implements ApplicationListener{
BuildRequest[] requests,
float viewX, float viewY, float viewWidth, float viewHeight
){
NetConnection connection = player.con;
//TODO this entire thing needs to be rewritten.
/*
NetConnection connection = player.con();
if(connection == null || snapshotID < connection.lastRecievedClientSnapshot) return;
boolean verifyPosition = !player.dead() && netServer.admins.getStrict() && headless;
@@ -534,7 +532,7 @@ public class NetServer implements ApplicationListener{
action.config = req.config;
})){
//force the player to remove this request if that's not the case
Call.removeQueueBlock(player.con, req.x, req.y, req.breaking);
Call.removeQueueBlock(player.con(), req.x, req.y, req.breaking);
connection.rejectedRequests.add(req);
continue;
}
@@ -562,7 +560,7 @@ public class NetServer implements ApplicationListener{
newx = x;
newy = y;
}else if(Mathf.dst(x, y, newx, newy) > correctDist){
Call.onPositionSet(player.con, newx, newy); //teleport and correct position when necessary
Call.onPositionSet(player.con(), newx, newy); //teleport and correct position when necessary
}
//reset player to previous synced position so it gets interpolated
@@ -574,7 +572,7 @@ public class NetServer implements ApplicationListener{
player.vel().set(xVelocity, yVelocity); //only for visual calculation purposes, doesn't actually update the player
connection.lastRecievedClientSnapshot = snapshotID;
connection.lastRecievedClientTime = Time.millis();
connection.lastRecievedClientTime = Time.millis();*/
}
@Remote(targets = Loc.client, called = Loc.server)
@@ -603,9 +601,10 @@ public class NetServer implements ApplicationListener{
other.kick(KickReason.kick);
Log.info("&lc{0} has kicked {1}.", player.name(), other.name());
}else if(action == AdminAction.trace){
TraceInfo info = new TraceInfo(other.con().address, other.uuid(), other.con().modclient, other.con.mobile);
TraceInfo info = new TraceInfo(other.con().address, other.uuid(), other.con().modclient, other.con().mobile);
if(player.con() != null){
Call.onTraceInfo(player.con(), other, info);
//TODO uncomment
//Call.onTraceInfo(player.con(), other, info);
}else{
NetClient.onTraceInfo(other, info);
}
@@ -635,7 +634,7 @@ public class NetServer implements ApplicationListener{
if(state.rules.pvp){
int used = 0;
for(TeamData t : state.teams.getActive()){
if(Groups.player.count(p -> p.getTeam() == t.team) > 0){
if(Groups.player.count(p -> p.team() == t.team) > 0){
used++;
}
}
@@ -687,11 +686,11 @@ public class NetServer implements ApplicationListener{
syncStream.reset();
short sent = 0;
for(Tilec entity : tileGroup.all()){
if(!entity.block.sync) continue;
for(Tilec entity : Groups.tile){
if(!entity.block().sync) continue;
sent ++;
dataStream.writeInt(entity.tile.pos());
dataStream.writeInt(entity.tile().pos());
entity.write(dataStream);
if(syncStream.size() > maxSnapshotSize){
@@ -725,35 +724,26 @@ public class NetServer implements ApplicationListener{
byte[] stateBytes = syncStream.toByteArray();
//write basic state data.
Call.onStateSnapshot(player.con, state.wavetime, state.wave, state.enemies, (short)stateBytes.length, net.compressSnapshot(stateBytes));
Call.onStateSnapshot(player.con(), state.wavetime, state.wave, state.enemies, (short)stateBytes.length, net.compressSnapshot(stateBytes));
viewport.setSize(player.con.viewWidth, player.con.viewHeight).setCenter(player.con.viewX, player.con.viewY);
//check for syncable groups
//make sure mapping is enabled for this group
if(!group.mappingEnabled()){
throw new RuntimeException("Entity group '" + group.getType() + "' contains SyncTrait entities, yet mapping is not enabled. In order for syncing to work, you must enable mapping for this group.");
}
viewport.setSize(player.con().viewWidth, player.con().viewHeight).setCenter(player.con().viewX, player.con().viewY);
syncStream.reset();
int sent = 0;
for(Entity entity : group.all()){
SyncTrait sync = (SyncTrait)entity;
for(Syncc entity : Groups.sync){
//write all entities now
dataStream.writeInt(entity.getID()); //write id
dataStream.writeByte(sync.getTypeID().id); //write type ID
sync.write(dataStream); //write entity
dataStream.writeInt(entity.id()); //write id
dataStream.writeByte(entity.classId()); //write type ID
entity.write(dataStream); //write entity
sent++;
if(syncStream.size() > maxSnapshotSize){
dataStream.close();
byte[] syncBytes = syncStream.toByteArray();
Call.onEntitySnapshot(player.con, (byte)group.getID(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
Call.onEntitySnapshot(player.con(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
sent = 0;
syncStream.reset();
}
@@ -763,7 +753,7 @@ public class NetServer implements ApplicationListener{
dataStream.close();
byte[] syncBytes = syncStream.toByteArray();
Call.onEntitySnapshot(player.con, (byte)group.getID(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
Call.onEntitySnapshot(player.con(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
}
}
@@ -821,22 +811,22 @@ public class NetServer implements ApplicationListener{
void sync(){
try{
//iterate through each player
for(int i = 0; i < Groups.player.size(); i++){
Playerc player = Groups.player.all().get(i);
if(player.isLocal()) continue;
if(player.con == null || !player.con.isConnected()){
Groups.player.each(p -> !p.isLocal(), player -> {
if(player.con() == null || !player.con().isConnected()){
onDisconnect(player, "disappeared");
continue;
return;
}
NetConnection connection = player.con;
NetConnection connection = player.con();
if(!player.timer.get(Playerc.timerSync, serverSyncTime) || !connection.hasConnected) continue;
if(!player.timer(0, serverSyncTime) || !connection.hasConnected) return;
writeEntitySnapshot(player);
}
try{
writeEntitySnapshot(player);
}catch(IOException e){
e.printStackTrace();
}
});
if(Groups.player.size() > 0 && Core.settings.getBool("blocksync") && timer.get(timerBlockSync, blockSyncTime)){
writeBlockSnapshots();

View File

@@ -1,8 +1,6 @@
package mindustry.core;
import arc.*;
import arc.files.*;
import arc.func.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.graphics.gl.*;
@@ -12,13 +10,8 @@ import arc.scene.ui.layout.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.core.GameState.*;
import mindustry.gen.*;
import mindustry.game.EventType.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.input.*;
import mindustry.ui.*;
import mindustry.world.blocks.defense.ForceProjector.*;
import static arc.Core.*;
import static mindustry.Vars.*;
@@ -80,6 +73,8 @@ public class Renderer implements ApplicationListener{
}else{
Vec2 position = Tmp.v3.set(player);
//TODO camera controls should be in input
/*
if(player.dead()){
Tilec core = player.closestCore();
if(core != null){
@@ -91,7 +86,7 @@ public class Renderer implements ApplicationListener{
}
}else if(control.input instanceof DesktopInput && !state.isPaused()){
camera.position.lerpDelta(position, 0.08f);
}
}*/
updateShake(0.75f);
if(pixelator.enabled()){
@@ -173,6 +168,10 @@ public class Renderer implements ApplicationListener{
}
}
public void draw(){
//TODO do it
}
/*
public void draw(){
camera.update();
@@ -339,7 +338,7 @@ public class Renderer implements ApplicationListener{
Groups.unit.draw(u -> u.isFlying() == flying && !u.isDead(), Unitc::drawOver);
Groups.player.draw(p -> p.isFlying() == flying, Unitc::drawOver);
}
}*/
public void scaleCamera(float amount){
targetscale += amount;
@@ -366,6 +365,8 @@ public class Renderer implements ApplicationListener{
}
public void takeMapScreenshot(){
//TODO uncomment
/*
drawGroundShadows();
int w = world.width() * tilesize, h = world.height() * tilesize;
@@ -414,7 +415,7 @@ public class Renderer implements ApplicationListener{
buffer.dispose();
Core.settings.put("animatedwater", hadWater);
Core.settings.put("animatedshields", hadShields);
Core.settings.put("animatedshields", hadShields);*/
}
}

View File

@@ -12,6 +12,7 @@ import mindustry.core.GameState.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.game.Teams.*;
import mindustry.gen.*;
import mindustry.io.*;
import mindustry.maps.*;
import mindustry.maps.filters.*;
@@ -163,7 +164,7 @@ public class World{
addDarkness(tiles);
}
entities.all().each(group -> group.resize(-finalWorldBounds, -finalWorldBounds, tiles.width() * tilesize + finalWorldBounds * 2, tiles.height() * tilesize + finalWorldBounds * 2));
Groups.resize(-finalWorldBounds, -finalWorldBounds, tiles.width() * tilesize + finalWorldBounds * 2, tiles.height() * tilesize + finalWorldBounds * 2);
generating = false;
Events.fire(new WorldLoadEvent());
@@ -377,7 +378,7 @@ public class World{
Tile tile = tiles.getn(x, y);
Block result = tile.block();
Team team = tile.getTeam();
Team team = tile.team();
int offsetx = -(result.size - 1) / 2;
int offsety = -(result.size - 1) / 2;

View File

@@ -65,7 +65,7 @@ public class DrawOperation{
tile.setFloor((Floor)content.block(to));
}else if(type == OpType.block.ordinal()){
Block block = content.block(to);
tile.setBlock(block, tile.getTeam(), tile.rotation());
tile.setBlock(block, tile.team(), tile.rotation());
}else if(type == OpType.rotation.ordinal()){
tile.rotation(to);
}else if(type == OpType.team.ordinal()){

View File

@@ -138,11 +138,12 @@ public class EditorTile extends Tile{
Block block = block();
if(block.hasEntity()){
entity = block.newEntity().init(this, false);
entity.cons = new ConsumeModule(entity);
if(block.hasItems) entity.items() = new ItemModule();
if(block.hasLiquids) entity.liquids() = new LiquidModule();
if(block.hasPower) entity.power() = new PowerModule();
//TODO uncomment once this mess is figure out
//entity = block.newEntity().init(this, false);
entity.cons(new ConsumeModule(entity));
if(block.hasItems) entity.items(new ItemModule());
if(block.hasLiquids) entity.liquids(new LiquidModule());
if(block.hasPower) entity.power(new PowerModule());
}
}

View File

@@ -138,7 +138,7 @@ public enum EditorTool{
//only fill synthetic blocks, it's meaningless otherwise
if(tile.link().synthetic()){
Team dest = tile.getTeam();
Team dest = tile.team();
if(dest == editor.drawTeam) return;
fill(editor, x, y, false, t -> t.getTeamID() == (int)dest.id && t.link().synthetic(), t -> t.setTeam(editor.drawTeam));
}

View File

@@ -83,7 +83,7 @@ public class MapEditor{
//re-add them
for(Tile tile : tiles){
if(tile.block().isMultiblock()){
tile.set(tile.block(), tile.getTeam());
tile.set(tile.block(), tile.team());
}
}

View File

@@ -283,7 +283,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
}
}
player.set(world.width() * tilesize/2f, world.height() * tilesize/2f);
player.dead(false);
//TODO figure out how to kill player
//player.dead(false);
logic.play();
});
}
@@ -295,7 +296,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
editor.getTags().put("rules", JsonIO.write(state.rules));
editor.getTags().remove("width");
editor.getTags().remove("height");
player.dead = true;
//TODO unkill player
//player.dead = true;
Map returned = null;

View File

@@ -124,7 +124,7 @@ public class MapGenerateDialog extends FloatingDialog{
Tile tile = editor.tile(x, y);
input.apply(x, y, tile.floor(), tile.block(), tile.overlay());
filter.apply(input);
writeTiles[x][y].set(input.floor, input.block, input.ore, tile.getTeam(), tile.rotation());
writeTiles[x][y].set(input.floor, input.block, input.ore, tile.team(), tile.rotation());
}
}
@@ -424,7 +424,7 @@ public class MapGenerateDialog extends FloatingDialog{
}
public GenTile set(Tile other){
set(other.floor(), other.block(), other.overlay(), other.getTeam(), other.rotation());
set(other.floor(), other.block(), other.overlay(), other.team(), other.rotation());
return this;
}

View File

@@ -111,7 +111,7 @@ public class MapRenderer implements Disposable{
IndexedRenderer mesh = chunks[x][y];
Tile tile = editor.tiles().getn(wx, wy);
Team team = tile.getTeam();
Team team = tile.team();
Block floor = tile.floor();
Block wall = tile.block();

View File

@@ -30,7 +30,7 @@ public class WaveInfoDialog extends FloatingDialog{
private Table table, preview;
private int start = 0;
private UnitType lastType = UnitTypes.dagger;
private UnitDef lastType = UnitTypes.dagger;
private float updateTimer, updatePeriod = 1f;
public WaveInfoDialog(MapEditor editor){
@@ -221,7 +221,7 @@ public class WaveInfoDialog extends FloatingDialog{
dialog.setFillParent(true);
dialog.cont.pane(p -> {
int i = 0;
for(UnitType type : content.units()){
for(UnitDef type : content.units()){
p.addButton(t -> {
t.left();
t.addImage(type.icon(mindustry.ui.Cicon.medium)).size(40f).padRight(2f);
@@ -256,7 +256,7 @@ public class WaveInfoDialog extends FloatingDialog{
for(int j = 0; j < spawned.length; j++){
if(spawned[j] > 0){
UnitType type = content.getByID(ContentType.unit, j);
UnitDef type = content.getByID(ContentType.unit, j);
table.addImage(type.icon(Cicon.medium)).size(8f * 4f).padRight(4);
table.add(spawned[j] + "x").color(Color.lightGray).padRight(6);
table.row();

View File

@@ -1,19 +1,17 @@
package mindustry.entities;
import arc.*;
import mindustry.annotations.Annotations.*;
import arc.struct.*;
import arc.func.*;
import arc.graphics.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.effect.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.world.*;
import static mindustry.Vars.*;
@@ -31,8 +29,8 @@ public class Damage{
public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, Color color){
for(int i = 0; i < Mathf.clamp(power / 20, 0, 6); i++){
int branches = 5 + Mathf.clamp((int)(power / 30), 1, 20);
Time.run(i * 2f + Mathf.random(4f), () -> Lightning.create(Team.derelict, Pal.power, 3,
x, y, Mathf.random(360f), branches + Mathf.range(2)));
//TODO uncomment
//Time.run(i * 2f + Mathf.random(4f), () -> Lightning.create(Team.derelict, Pal.power, 3, x, y, Mathf.random(360f), branches + Mathf.range(2)));
}
for(int i = 0; i < Mathf.clamp(flammability / 4, 0, 30); i++){
@@ -68,7 +66,8 @@ public class Damage{
float cy = y + Mathf.range(range);
Tile tile = world.tileWorld(cx, cy);
if(tile != null){
Fire.create(tile);
//TODO uncomment
//Fire.create(tile);
}
}
}
@@ -234,7 +233,7 @@ public class Damage{
if(scaledDamage <= 0 || tile == null) continue;
//apply damage to entity if needed
if(tile.entity != null && tile.getTeam() != team){
if(tile.entity != null && tile.team() != team){
int health = (int)tile.entity.health();
if(tile.entity.health() > 0){
tile.entity.damage(scaledDamage);
@@ -257,7 +256,7 @@ public class Damage{
for(int dx = -trad; dx <= trad; dx++){
for(int dy = -trad; dy <= trad; dy++){
Tile tile = world.tile(Math.round(x / tilesize) + dx, Math.round(y / tilesize) + dy);
if(tile != null && tile.entity != null && (team == null ||team.isEnemy(tile.getTeam())) && Mathf.dst(dx, dy) <= trad){
if(tile != null && tile.entity != null && (team == null ||team.isEnemy(tile.team())) && Mathf.dst(dx, dy) <= trad){
tile.entity.damage(damage);
}
}

View File

@@ -97,6 +97,10 @@ public class Effect{
this.data = data;
}
public <T> T data(){
return (T)data;
}
public void scaled(float lifetime, Cons<EffectContainer> cons){
if(innerContainer == null) innerContainer = new EffectContainer();
if(time <= lifetime){

View File

@@ -5,16 +5,19 @@ import arc.math.geom.*;
import arc.struct.*;
import mindustry.gen.*;
import java.util.*;
import static mindustry.Vars.*;
/** Represents a group of a certain type of entity.*/
@SuppressWarnings("unchecked")
public class EntityGroup<T extends Entityc>{
public class EntityGroup<T extends Entityc> implements Iterable<T>{
private final Array<T> array = new Array<>(false, 32);
private final Array<T> intersectArray = new Array<>();
private final Rect intersectRect = new Rect();
private IntMap<T> map;
private QuadTree tree;
private boolean clearing;
private int index;
@@ -44,6 +47,13 @@ public class EntityGroup<T extends Entityc>{
}
}
public void each(Boolf<T> filter, Cons<T> cons){
T[] items = array.items;
for(index = 0; index < array.size; index++){
if(filter.get(items[index])) cons.get(items[index]);
}
}
public boolean useTree(){
return map != null;
}
@@ -101,6 +111,10 @@ public class EntityGroup<T extends Entityc>{
return array.size;
}
public boolean contains(Boolf<T> pred){
return array.contains(pred);
}
public int count(Boolf<T> pred){
return array.count(pred);
}
@@ -110,11 +124,12 @@ public class EntityGroup<T extends Entityc>{
array.add(type);
if(mappingEnabled()){
map.put(type.getId(), type);
map.put(type.id(), type);
}
}
public void remove(T type){
if(clearing) return;
if(type == null) throw new RuntimeException("Cannot remove a null entity!");
int idx = array.indexOf(type, true);
if(idx != -1){
@@ -128,12 +143,22 @@ public class EntityGroup<T extends Entityc>{
}
public void clear(){
clearing = true;
array.each(Entityc::remove);
array.clear();
if(map != null)
map.clear();
clearing = false;
}
public T find(Boolf<T> pred){
return array.find(pred);
}
@Override
public Iterator<T> iterator(){
return array.iterator();
}
}

View File

@@ -0,0 +1,86 @@
package mindustry.entities;
import arc.graphics.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import mindustry.content.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.world.*;
import static mindustry.Vars.*;
//TODO move into a different class
public class Lightning{
private static final Rand random = new Rand();
private static final Rect rect = new Rect();
private static final Array<Unitc> entities = new Array<>();
private static final IntSet hit = new IntSet();
private static final int maxChain = 8;
private static final float hitRange = 30f;
private static boolean bhit = false;
private static int lastSeed = 0;
/** Create a lighting branch at a location. Use Team.none to damage everyone. */
public static void create(Team team, Color color, float damage, float x, float y, float targetAngle, int length){
createLightingInternal(lastSeed++, team, color, damage, x, y, targetAngle, length);
}
//TODO remote method
//@Remote(called = Loc.server, unreliable = true)
private static void createLightingInternal(int seed, Team team, Color color, float damage, float x, float y, float rotation, int length){
random.setSeed(seed);
hit.clear();
Array<Vec2> lines = new Array<>();
bhit = false;
for(int i = 0; i < length / 2; i++){
Bullets.damageLightning.create(null, team, x, y, 0f, damage, 1f, 1f, null);
lines.add(new Vec2(x + Mathf.range(3f), y + Mathf.range(3f)));
if(lines.size > 1){
bhit = false;
Vec2 from = lines.get(lines.size - 2);
Vec2 to = lines.get(lines.size - 1);
world.raycastEach(world.toTile(from.getX()), world.toTile(from.getY()), world.toTile(to.getX()), world.toTile(to.getY()), (wx, wy) -> {
Tile tile = world.ltile(wx, wy);
if(tile != null && tile.block().insulated){
bhit = true;
//snap it instead of removing
lines.get(lines.size -1).set(wx * tilesize, wy * tilesize);
return true;
}
return false;
});
if(bhit) break;
}
rect.setSize(hitRange).setCenter(x, y);
entities.clear();
if(hit.size < maxChain){
Units.nearbyEnemies(team, rect, u -> {
if(!hit.contains(u.id())){
entities.add(u);
}
});
}
Unitc furthest = Geometry.findFurthest(x, y, entities);
if(furthest != null){
hit.add(furthest.id());
x = furthest.x();
y = furthest.y();
}else{
rotation += random.range(20f);
x += Angles.trnsx(rotation, hitRange / 2f);
y += Angles.trnsy(rotation, hitRange / 2f);
}
}
Fx.lightning.at(x, y, rotation, color, lines);
}
}

View File

@@ -3,6 +3,8 @@ package mindustry.entities;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import mindustry.gen.*;
/**
* Class for predicting shoot angles based on velocities of targets.
*/
@@ -52,8 +54,8 @@ public class Predict{
/**
* See {@link #intercept(float, float, float, float, float, float, float)}.
*/
public static Vec2 intercept(Teamc src, Teamc dst, float v){
return intercept(src.getX(), src.getY(), dst.getX(), dst.getY(), dst.getTargetVelocityX() - src.getTargetVelocityX()/(2f*Time.delta()), dst.getTargetVelocityY() - src.getTargetVelocityY()/(2f*Time.delta()), v);
public static Vec2 intercept(Hitboxc src, Hitboxc dst, float v){
return intercept(src.getX(), src.getY(), dst.getX(), dst.getY(), dst.deltaX() - src.deltaX()/(2f*Time.delta()), dst.deltaY() - src.deltaX()/(2f*Time.delta()), v);
}
private static Vec2 quad(float a, float b, float c){

View File

@@ -1,9 +1,7 @@
package mindustry.entities;
import arc.func.*;
import arc.math.*;
import arc.math.geom.*;
import mindustry.gen.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.world.*;
@@ -41,8 +39,8 @@ public class Units{
}
/** See {@link #invalidateTarget(Teamc, Team, float, float, float)} */
public static boolean invalidateTarget(Teamc target, Unitc targeter){
return invalidateTarget(target, targeter.team(), targeter.x, targeter.y, targeter.getWeapon().bullet.range());
public static boolean invalidateTarget(Teamc target, Unitc targeter, float range){
return invalidateTarget(target, targeter.team(), targeter.x(), targeter.y(), range);
}
/** Returns whether there are any entities on this tile. */
@@ -56,7 +54,7 @@ public class Units{
nearby(x, y, width, height, unit -> {
if(boolResult) return;
if(!unit.isFlying()){
if(unit.isGrounded()){
unit.hitbox(hitrect);
if(hitrect.overlaps(x, y, width, height)){
@@ -118,7 +116,7 @@ public class Units{
nearbyEnemies(team, x - range, y - range, range*2f, range*2f, e -> {
if(e.dead() || !predicate.get(e)) return;
float dst2 = Mathf.dst2(e.x, e.y, x, y);
float dst2 = e.dst2(x, y);
if(dst2 < range*range && (result == null || dst2 < cdist)){
result = e;
cdist = dst2;
@@ -136,7 +134,7 @@ public class Units{
nearby(team, x, y, range, e -> {
if(!predicate.get(e)) return;
float dist = Mathf.dst2(e.x, e.y, x, y);
float dist = e.dst2(x, y);
if(result == null || dist < cdist){
result = e;
cdist = dist;
@@ -149,7 +147,7 @@ public class Units{
/** Iterates over all units in a rectangle. */
public static void nearby(Team team, float x, float y, float width, float height, Cons<Unitc> cons){
Groups.unit.intersect(x, y, width, height, u -> {
if(u.getTeam() == team){
if(u.team() == team){
cons.get(u);
}
});
@@ -158,7 +156,7 @@ public class Units{
/** Iterates over all units in a circle around this position. */
public static void nearby(Team team, float x, float y, float radius, Cons<Unitc> cons){
Groups.unit.intersect(x - radius, y - radius, radius*2f, radius*2f, unit -> {
if(unit.getTeam() == team && unit.withinDst(x, y, radius)){
if(unit.team() == team && unit.withinDst(x, y, radius)){
cons.get(unit);
}
});
@@ -177,7 +175,7 @@ public class Units{
/** Iterates over all units that are enemies of this team. */
public static void nearbyEnemies(Team team, float x, float y, float width, float height, Cons<Unitc> cons){
Groups.unit.intersect(x, y, width, height, u -> {
if(team.isEnemy(u.getTeam())){
if(team.isEnemy(u.team())){
cons.get(u);
}
});
@@ -188,13 +186,4 @@ public class Units{
nearbyEnemies(team, rect.x, rect.y, rect.width, rect.height, cons);
}
/** Iterates over all units. */
public static void all(Cons<Unitc> cons){
Groups.unit.all().each(cons);
}
public static void each(Team team, Cons<Unitc> cons){
Groups.unit.all().each(t -> t.getTeam() == team, cons);
}
}

View File

@@ -26,7 +26,7 @@ public class ArtilleryBulletType extends BasicBulletType{
public void update(Bulletc b){
super.update(b);
if(b.timer.get(0, 3 + b.fslope() * 2f)){
if(b.timer(0, 3 + b.fslope() * 2f)){
trailEffect.at(b.x(), b.y(), b.fslope() * 4f, backColor);
}
}

View File

@@ -2,11 +2,11 @@ package mindustry.entities.bullet;
import arc.audio.*;
import arc.math.*;
import arc.util.ArcAnnotate.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.effect.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
@@ -109,7 +109,7 @@ public abstract class BulletType extends Content{
}
public void hit(Bulletc b, float x, float y){
hitEffect.at(x, y, b.getRotation());
hitEffect.at(x, y, b.rotation());
hitSound.at(b);
Effects.shake(hitShake, hitShake, b);
@@ -132,7 +132,7 @@ public abstract class BulletType extends Content{
}
public void despawned(Bulletc b){
despawnEffect.at(b.getX(), b.getY(), b.getRotation());
despawnEffect.at(b.getX(), b.getY(), b.rotation());
hitSound.at(b);
if(fragBullet != null || splashDamageRadius > 0){
@@ -140,7 +140,7 @@ public abstract class BulletType extends Content{
}
for(int i = 0; i < lightining; i++){
Lightning.createLighting(Lightning.nextSeed(), b.team(), Pal.surge, damage, b.getX(), b.getY(), Mathf.random(360f), lightningLength);
Lightning.create(b.team(), Pal.surge, damage, b.getX(), b.getY(), Mathf.random(360f), lightningLength);
}
}
@@ -148,20 +148,20 @@ public abstract class BulletType extends Content{
}
public void init(Bulletc b){
if(killShooter && b.getOwner() instanceof Healthc){
((Healthc)b.getOwner()).kill();
if(killShooter && b.owner() instanceof Healthc){
((Healthc)b.owner()).kill();
}
if(instantDisappear){
b.setTime(lifetime);
b.time(lifetime);
}
}
public void update(Bulletc b){
if(homingPower > 0.0001f){
Teamc target = Units.closestTarget(b.team(), b.getX(), b.getY(), homingRange, e -> !e.isFlying() || collidesAir);
Teamc target = Units.closestTarget(b.team(), b.getX(), b.getY(), homingRange, e -> e.isGrounded() || collidesAir);
if(target != null){
b.vel().setAngle(Mathf.slerpDelta(b.getRotation(), b.angleTo(target), 0.08f));
b.vel().setAngle(Mathf.slerpDelta(b.rotation(), b.angleTo(target), 0.08f));
}
}
}
@@ -182,23 +182,24 @@ public abstract class BulletType extends Content{
}
public Bulletc create(Entityc owner, Team team, float x, float y, float angle, float velocityScl){
return create(owner, team, x, y, angle, velocityScl, 1f, null);
return create(owner, team, x, y, angle, -1, velocityScl, 1f, null);
}
public Bulletc create(Entityc owner, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl){
return create(owner, team, x, y, angle, velocityScl, lifetimeScl, null);
return create(owner, team, x, y, angle, -1, velocityScl, lifetimeScl, null);
}
public Bulletc create(Bulletc parent, float x, float y, float angle){
return create(parent.getOwner(), parent.team(), x, y, angle);
return create(parent.owner(), parent.team(), x, y, angle);
}
public Bulletc create(Bulletc parent, float x, float y, float angle, float velocityScl){
return create(parent.getOwner(), parent.team(), x, y, angle, velocityScl);
return create(parent.owner(), parent.team(), x, y, angle, velocityScl);
}
public Bulletc create(Entityc owner, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl, Object data){
public Bulletc create(@Nullable Entityc owner, Team team, float x, float y, float angle, float damage, float velocityScl, float lifetimeScl, Object data){
//TODO assign type damage is damage <0, else assign provided damage
//TODO implement
return null;
@@ -223,12 +224,12 @@ public abstract class BulletType extends Content{
return bullet;*/
}
public void createNet(Team team, float x, float y, float angle, float velocityScl, float lifetimeScl){
Call.createBullet(this, team, x, y, angle, velocityScl, lifetimeScl);
public void createNet(Team team, float x, float y, float angle, float damage, float velocityScl, float lifetimeScl){
Call.createBullet(this, team, x, y, damage, angle, velocityScl, lifetimeScl);
}
@Remote(called = Loc.server, unreliable = true)
public static void createBullet(BulletType type, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl){
type.create(null, team, x, y, angle, velocityScl, lifetimeScl, null);
public static void createBullet(BulletType type, Team team, float x, float y, float angle, float damage, float velocityScl, float lifetimeScl){
type.create(null, team, x, y, angle, damage, velocityScl, lifetimeScl, null);
}
}

View File

@@ -26,16 +26,16 @@ public class FlakBulletType extends BasicBulletType{
@Override
public void update(Bulletc b){
super.update(b);
if(b.getData() instanceof Integer) return;
if(b.data() instanceof Integer) return;
if(b.timer.get(2, 6)){
if(b.timer(2, 6)){
Units.nearbyEnemies(b.team(), rect.setSize(explodeRange * 2f).setCenter(b.x(), b.y()), unit -> {
if(b.getData() instanceof Float) return;
if(b.data() instanceof Float) return;
if(unit.dst(b) < explodeRange){
b.setData(0);
b.data(0);
Time.run(5f, () -> {
if(b.getData() instanceof Integer){
if(b.data() instanceof Integer){
b.time(b.lifetime());
}
});

View File

@@ -29,7 +29,7 @@ public class HealBulletType extends BulletType{
@Override
public boolean collides(Bulletc b, Tile tile){
return tile.getTeam() != b.team() || tile.entity.healthf() < 1f;
return tile.team() != b.team() || tile.entity.healthf() < 1f;
}
@Override
@@ -47,9 +47,9 @@ public class HealBulletType extends BulletType{
super.hit(b);
tile = tile.link();
if(tile.entity != null && tile.getTeam() == b.team() && !(tile.block() instanceof BuildBlock)){
if(tile.entity != null && tile.team() == b.team() && !(tile.block() instanceof BuildBlock)){
Fx.healBlockFull.at(tile.drawx(), tile.drawy(), tile.block().size, Pal.heal);
tile.entity.healBy(healPercent / 100f * tile.entity.maxHealth());
tile.entity.heal(healPercent / 100f * tile.entity.maxHealth());
}
}
}

View File

@@ -58,7 +58,7 @@ public class LaserBulletType extends BulletType{
Lines.stroke((cwidth *= lengthFalloff) * b.fout());
Lines.lineAngle(b.x(), b.y(), b.rotation(), baseLen, CapStyle.none);
Tmp.v1.trns(b.rotation(), baseLen);
Drawf.tri(b.x + Tmp.v1.x, b.y + Tmp.v1.y, Lines.getStroke() * 1.22f, cwidth * 2f + width / 2f, b.rotation());
Drawf.tri(b.x() + Tmp.v1.x, b.y() + Tmp.v1.y, Lines.getStroke() * 1.22f, cwidth * 2f + width / 2f, b.rotation());
Fill.circle(b.x(), b.y(), 1f * cwidth * b.fout());
for(int i : Mathf.signs){

View File

@@ -2,7 +2,7 @@ package mindustry.entities.bullet;
import arc.graphics.*;
import mindustry.content.*;
import mindustry.entities.effect.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.graphics.*;

View File

@@ -5,7 +5,6 @@ import arc.graphics.g2d.*;
import arc.math.geom.*;
import arc.util.ArcAnnotate.*;
import mindustry.content.*;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
@@ -66,7 +65,7 @@ public class LiquidBulletType extends BulletType{
@Override
public void hit(Bulletc b, float hitx, float hity){
hitEffect.at(liquid.color, hitx, hity);
hitEffect.at(hitx, hity, liquid.color);
Puddle.deposit(world.tileWorld(hitx, hity), liquid, puddleSize);
if(liquid.temperature <= 0.5f && liquid.flammability < 0.3f){

View File

@@ -38,17 +38,17 @@ public class MassDriverBolt extends BulletType{
@Override
public void update(Bulletc b){
//data MUST be an instance of DriverBulletData
if(!(b.getData() instanceof DriverBulletData)){
if(!(b.data() instanceof DriverBulletData)){
hit(b);
return;
}
float hitDst = 7f;
DriverBulletData data = (DriverBulletData)b.getData();
DriverBulletData data = (DriverBulletData)b.data();
//if the target is dead, just keep flying until the bullet explodes
if(data.to.isDead()){
if(data.to.dead()){
return;
}
@@ -67,7 +67,7 @@ public class MassDriverBolt extends BulletType{
if(Angles.near(angleTo, baseAngle, 2f)){
intersect = true;
//snap bullet position back; this is used for low-FPS situations
b.set(data.to.x + Angles.trnsx(baseAngle, hitDst), data.to.y + Angles.trnsy(baseAngle, hitDst));
b.set(data.to.x() + Angles.trnsx(baseAngle, hitDst), data.to.y() + Angles.trnsy(baseAngle, hitDst));
}
}
@@ -85,9 +85,9 @@ public class MassDriverBolt extends BulletType{
public void despawned(Bulletc b){
super.despawned(b);
if(!(b.getData() instanceof DriverBulletData)) return;
if(!(b.data() instanceof DriverBulletData)) return;
DriverBulletData data = (DriverBulletData)b.getData();
DriverBulletData data = (DriverBulletData)b.data();
for(int i = 0; i < data.items.length; i++){
int amountDropped = Mathf.random(0, data.items[i]);

View File

@@ -34,7 +34,7 @@ public class MissileBulletType extends BasicBulletType{
}
if(weaveMag > 0){
b.vel().rotate(Mathf.sin(Time.time() + b.id * 4422, weaveScale, weaveMag) * Time.delta());
b.vel().rotate(Mathf.sin(Time.time() + b.id() * 442, weaveScale, weaveMag) * Time.delta());
}
}
}

View File

@@ -20,12 +20,12 @@ import mindustry.core.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
import mindustry.entities.effect.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.input.*;
import mindustry.net.Administration.*;
import mindustry.net.*;
import mindustry.net.Packets.*;
@@ -177,21 +177,12 @@ public class EntityComps{
}
@Component
abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Drawc, Shielderc, Ownerc, Velc, Bulletc{
abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Drawc, Shielderc, Ownerc, Velc, Bulletc, Timerc{
private float lifeScl;
Object data;
BulletType type;
Interval timer = new Interval(6);
public boolean timer(int index, float time){
return timer.get(index, time);
}
@Override
public float getDamage(){
return type.damage;
}
float damage;
@Override
public void add(){
@@ -258,8 +249,8 @@ public class EntityComps{
Tile tile = world.ltile(x, y);
if(tile == null) return false;
if(tile.entity != null && tile.entity.collide(this) && type.collides(this, tile) && !tile.entity.dead() && (type.collidesTeam || tile.getTeam() != team())){
if(tile.getTeam() != team()){
if(tile.entity != null && tile.entity.collide(this) && type.collides(this, tile) && !tile.entity.dead() && (type.collidesTeam || tile.team() != team())){
if(tile.team() != team()){
tile.entity.collision(this);
}
@@ -295,6 +286,15 @@ public class EntityComps{
}
}
@Component
abstract class TimerComp{
@ReadOnly Interval timer = new Interval(6);
public boolean timer(int index, float time){
return timer.get(index, time);
}
}
@Component
abstract class DamageComp{
abstract float damage();
@@ -590,7 +590,7 @@ public class EntityComps{
Tile other = world.ltile(tile.x + point.x, tile.y + point.y);
if(other == null) continue;
if(other.entity == null || !(other.interactable(tile.getTeam()))) continue;
if(other.entity == null || !(other.interactable(tile.team()))) continue;
//add this tile to proximity of nearby tiles
if(!other.entity.proximity().contains(tile, true)){
@@ -671,7 +671,7 @@ public class EntityComps{
}
@Component
abstract class PlayerComp implements UnitController, Entityc, Syncc{
abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc{
@Nullable Unitc unit;
@ReadOnly Team team = Team.sharded;
@@ -684,6 +684,19 @@ public class EntityComps{
@Nullable String lastText;
float textFadeTime;
public @Nullable Tilec closestCore(){
return state.teams.closestCore(x(), y(), team);
}
public void reset(){
team = state.rules.defaultTeam;
admin = typing = false;
lastText = null;
textFadeTime = 0f;
unit.controller(unit.type().createController());
unit = null;
}
public void update(){
if(unit != null){
x(unit.x());
@@ -704,12 +717,16 @@ public class EntityComps{
unit.team(team);
}
boolean dead(){
return unit == null;
}
String uuid(){
return con == null ? "AAAAAAAA" : con.uuid;
return con == null ? "[LOCAL]" : con.uuid;
}
String usid(){
return con == null ? "AAAAAAAA" : con.usid;
return con == null ? "[LOCAL]" : con.usid;
}
void kick(KickReason reason){
@@ -801,7 +818,7 @@ public class EntityComps{
}
@Component
abstract class TeamComp implements Posc, Healthc{
abstract class TeamComp implements Posc{
transient float x, y;
Team team = Team.sharded;
@@ -944,8 +961,7 @@ public class EntityComps{
private void bullet(Weapon weapon, float x, float y, float angle){
Tmp.v1.trns(angle, 3f);
//TODO create the bullet
//Bullet.create(weapon.bullet, this, getTeam(), x + Tmp.v1.x, y + Tmp.v1.y, angle, (1f - weapon.velocityRnd) + Mathf.random(weapon.velocityRnd));
weapon.bullet.create(this, team(), x + Tmp.v1.x, y + Tmp.v1.y, angle, (1f - weapon.velocityRnd) + Mathf.random(weapon.velocityRnd));
}
}
@@ -1202,7 +1218,7 @@ public class EntityComps{
mineTile.worldy() + Mathf.range(tilesize / 2f), core.tile());
}else if(acceptsItem(item)){
//this is clientside, since items are synced anyway
ItemTransfer.transferItemToUnit(item,
InputHandler.transferItemToUnit(item,
mineTile.worldx() + Mathf.range(tilesize / 2f),
mineTile.worldy() + Mathf.range(tilesize / 2f),
this);
@@ -1480,6 +1496,16 @@ public class EntityComps{
boolean hasItem(){
return stack.amount > 0;
}
void addItem(Item item){
addItem(item, 1);
}
void addItem(Item item, int amount){
stack.amount = stack.item == item ? stack.amount + amount : amount;
stack.item = item;
stack.amount = Mathf.clamp(stack.amount, 0, itemCapacity());
}
}
@Component
@@ -1591,8 +1617,7 @@ public class EntityComps{
return;
}else if(entry.effect.reactsWith(effect)){ //find opposite
StatusEntry.tmp.effect = entry.effect;
//TODO unit cannot be null here
entry.effect.getTransition((mindustry.gen.Unitc)this, effect, entry.time, duration, StatusEntry.tmp);
entry.effect.getTransition((Unitc)this, effect, entry.time, duration, StatusEntry.tmp);
entry.time = StatusEntry.tmp.time;
if(StatusEntry.tmp.effect != entry.effect){
@@ -1611,6 +1636,10 @@ public class EntityComps{
statuses.add(entry);
}
boolean isBoss(){
return hasEffect(StatusEffects.boss);
}
boolean isImmune(StatusEffect effect){
return false;
}
@@ -1714,7 +1743,7 @@ public class EntityComps{
}
boolean isLocal(){
return this instanceof Unitc && ((Unitc)this).controller() == player || this == player;
return ((Object)this) == player || ((Object)this) instanceof Unitc && ((Unitc)((Object)this)).controller() == player;
}
<T> T as(Class<T> type){

View File

@@ -5,12 +5,17 @@ import mindustry.entities.def.EntityComps.*;
public class EntityGroupDefs{
@GroupDef(EntityComp.class)
void all(){
}
@GroupDef(PlayerComp.class)
void player(){
}
@GroupDef(UnitComp.class)
@GroupDef(value = UnitComp.class, spatial = true)
void unit(){
}

View File

@@ -1,228 +0,0 @@
package mindustry.entities.effect;
import arc.*;
import mindustry.annotations.Annotations.*;
import arc.struct.*;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import java.io.*;
import static mindustry.Vars.*;
public class Fire extends TimedEntity implements SaveTrait, SyncTrait{
private static final IntMap<Fire> map = new IntMap<>();
private static final float baseLifetime = 1000f, spreadChance = 0.05f, fireballChance = 0.07f;
private int loadedPosition = -1;
private Tile tile;
private Block block;
private float baseFlammability = -1, puddleFlammability;
private float lifetime;
/** Deserialization use only! */
public Fire(){
}
@Remote
public static void onRemoveFire(int fid){
fireGroup.removeByID(fid);
}
/** Start a fire on the tile. If there already is a file there, refreshes its lifetime. */
public static void create(Tile tile){
if(net.client() || tile == null) return; //not clientside.
Fire fire = map.get(tile.pos());
if(fire == null){
fire = new Fire();
fire.tile = tile;
fire.lifetime = baseLifetime;
fire.set(tile.worldx(), tile.worldy());
fire.add();
map.put(tile.pos(), fire);
}else{
fire.lifetime = baseLifetime;
fire.time = 0f;
}
}
public static boolean has(int x, int y){
if(!Structs.inBounds(x, y, world.width(), world.height()) || !map.containsKey(Pos.get(x, y))){
return false;
}
Fire fire = map.get(Pos.get(x, y));
return fire.isAdded() && fire.fin() < 1f && fire.tile != null && fire.tile.x == x && fire.tile.y == y;
}
/**
* Attempts to extinguish a fire by shortening its life. If there is no fire here, does nothing.
*/
public static void extinguish(Tile tile, float intensity){
if(tile != null && map.containsKey(tile.pos())){
Fire fire = map.get(tile.pos());
fire.time += intensity * Time.delta();
if(fire.time >= fire.lifetime()){
Events.fire(Trigger.fireExtinguish);
}
}
}
@Override
public TypeID getTypeID(){
return TypeIDs.fire;
}
@Override
public byte version(){
return 0;
}
@Override
public float lifetime(){
return lifetime;
}
@Override
public void update(){
if(Mathf.chance(0.1 * Time.delta())){
Fx.fire.at(x + Mathf.range(4f), y + Mathf.range(4f));
}
if(Mathf.chance(0.05 * Time.delta())){
Fx.fireSmoke.at(x + Mathf.range(4f), y + Mathf.range(4f));
}
if(Mathf.chance(0.001 * Time.delta())){
Sounds.fire.at(this);
}
time = Mathf.clamp(time + Time.delta(), 0, lifetime());
map.put(tile.pos(), this);
if(net.client()){
return;
}
if(time >= lifetime() || tile == null){
remove();
return;
}
Tilec entity = tile.link().entity;
boolean damage = entity != null;
float flammability = baseFlammability + puddleFlammability;
if(!damage && flammability <= 0){
time += Time.delta() * 8;
}
if(baseFlammability < 0 || block != tile.block()){
baseFlammability = tile.block().getFlammability(tile);
block = tile.block();
}
if(damage){
lifetime += Mathf.clamp(flammability / 8f, 0f, 0.6f) * Time.delta();
}
if(flammability > 1f && Mathf.chance(spreadChance * Time.delta() * Mathf.clamp(flammability / 5f, 0.3f, 2f))){
Point2 p = Geometry.d4[Mathf.random(3)];
Tile other = world.tile(tile.x + p.x, tile.y + p.y);
create(other);
if(Mathf.chance(fireballChance * Time.delta() * Mathf.clamp(flammability / 10f))){
Call.createBullet(Bullets.fireball, Team.derelict, x, y, Mathf.random(360f), 1, 1);
}
}
if(Mathf.chance(0.1 * Time.delta())){
Puddle p = Puddle.getPuddle(tile);
if(p != null){
puddleFlammability = p.getFlammability() / 3f;
}else{
puddleFlammability = 0;
}
if(damage){
entity.damage(0.4f);
}
Damage.damageUnits(null, tile.worldx(), tile.worldy(), tilesize, 3f,
unit -> !unit.isFlying() && !unit.isImmune(StatusEffects.burning),
unit -> unit.applyEffect(StatusEffects.burning, 60 * 5));
}
}
@Override
public void writeSave(DataOutput stream) throws IOException{
stream.writeInt(tile.pos());
stream.writeFloat(lifetime);
stream.writeFloat(time);
}
@Override
public void readSave(DataInput stream, byte version) throws IOException{
this.loadedPosition = stream.readInt();
this.lifetime = stream.readFloat();
this.time = stream.readFloat();
add();
}
@Override
public void write(DataOutput data) throws IOException{
data.writeInt(tile.pos());
data.writeFloat(lifetime);
}
@Override
public void read(DataInput data) throws IOException{
int pos = data.readInt();
this.lifetime = data.readFloat();
x = Pos.x(pos) * tilesize;
y = Pos.y(pos) * tilesize;
tile = world.tile(pos);
}
@Override
public void reset(){
loadedPosition = -1;
tile = null;
baseFlammability = -1;
puddleFlammability = 0f;
incrementID();
}
@Override
public void added(){
if(loadedPosition != -1){
map.put(loadedPosition, this);
tile = world.tile(loadedPosition);
set(tile.worldx(), tile.worldy());
}
}
@Override
public void removed(){
if(tile != null){
Call.onRemoveFire(id);
map.remove(tile.pos());
}
}
@Override
public EntityGroup targetGroup(){
return fireGroup;
}
}

View File

@@ -1,114 +0,0 @@
package mindustry.entities.effect;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import arc.util.pooling.*;
import mindustry.annotations.Annotations.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.world.*;
import static mindustry.Vars.effectGroup;
public class ItemTransfer extends TimedEntity implements DrawTrait{
private Vec2 from = new Vec2();
private Vec2 current = new Vec2();
private Vec2 tovec = new Vec2();
private Item item;
private float seed;
private Position to;
private Runnable done;
public ItemTransfer(){
}
@Remote(called = Loc.server, unreliable = true)
public static void transferItemEffect(Item item, float x, float y, Itemsc to){
if(to == null) return;
create(item, x, y, to, () -> {
});
}
@Remote(called = Loc.server, unreliable = true)
public static void transferItemToUnit(Item item, float x, float y, Itemsc to){
if(to == null) return;
create(item, x, y, to, () -> to.addItem(item));
}
@Remote(called = Loc.server, unreliable = true)
public static void transferItemTo(Item item, int amount, float x, float y, Tile tile){
if(tile == null || tile.entity == null || tile.entity.items() == null) return;
for(int i = 0; i < Mathf.clamp(amount / 3, 1, 8); i++){
Time.run(i * 3, () -> create(item, x, y, tile, () -> {}));
}
tile.entity.items().add(item, amount);
}
public static void create(Item item, float fromx, float fromy, Position to, Runnable done){
ItemTransfer tr = Pools.obtain(ItemTransfer.class, ItemTransfer::new);
tr.item = item;
tr.from.set(fromx, fromy);
tr.to = to;
tr.done = done;
tr.seed = Mathf.range(1f);
tr.add();
}
@Override
public float lifetime(){
return 60;
}
@Override
public void reset(){
super.reset();
item = null;
to = null;
done = null;
from.setZero();
current.setZero();
tovec.setZero();
}
@Override
public void removed(){
if(done != null){
done.run();
}
Pools.free(this);
}
@Override
public void update(){
if(to == null){
remove();
return;
}
super.update();
current.set(from).interpolate(tovec.set(to.getX(), to.getY()), fin(), Interpolation.pow3);
current.add(tovec.set(to.getX(), to.getY()).sub(from).nor().rotate90(1).scl(seed * fslope() * 10f));
set(current.x, current.y);
}
@Override
public void draw(){
Lines.stroke(fslope() * 2f, Pal.accent);
Lines.circle(x, y, fslope() * 2f);
Draw.color(item.color);
Fill.circle(x, y, fslope() * 1.5f);
Draw.reset();
}
@Override
public EntityGroup targetGroup(){
return effectGroup;
}
}

View File

@@ -1,154 +0,0 @@
package mindustry.entities.effect;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.pooling.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.world.*;
import static mindustry.Vars.*;
//TODO lightning should be an effect with custom logic + bullet with custom init logic
public class Lightning extends TimedEntity implements DrawTrait, TimeTrait{
public static final float lifetime = 10f;
private static final Rand random = new Rand();
private static final Rect rect = new Rect();
private static final Array<Unitc> entities = new Array<>();
private static final IntSet hit = new IntSet();
private static final int maxChain = 8;
private static final float hitRange = 30f;
private static int lastSeed = 0;
private Array<Vec2> lines = new Array<>();
private Color color = Pal.lancerLaser;
/** For pooling use only. Do not call directly! */
public Lightning(){
}
/** Create a lighting branch at a location. Use Team.none to damage everyone. */
public static void create(Team team, Color color, float damage, float x, float y, float targetAngle, int length){
Call.createLighting(nextSeed(), team, color, damage, x, y, targetAngle, length);
}
public static int nextSeed(){
return lastSeed++;
}
/** Do not invoke! */
@Remote(called = Loc.server, unreliable = true)
public static void createLighting(int seed, Team team, Color color, float damage, float x, float y, float rotation, int length){
Lightning l = Pools.obtain(Lightning.class, Lightning::new);
Float dmg = damage;
l.x = x;
l.y = y;
l.color = color;
l.add();
random.setSeed(seed);
hit.clear();
boolean[] bhit = {false};
for(int i = 0; i < length / 2; i++){
Bullet.create(Bullets.damageLightning, l, team, x, y, 0f, 1f, 1f, dmg);
l.lines.add(new Vec2(x + Mathf.range(3f), y + Mathf.range(3f)));
if(l.lines.size > 1){
bhit[0] = false;
Position from = l.lines.get(l.lines.size - 2);
Position to = l.lines.get(l.lines.size - 1);
world.raycastEach(world.toTile(from.getX()), world.toTile(from.getY()), world.toTile(to.getX()), world.toTile(to.getY()), (wx, wy) -> {
Tile tile = world.ltile(wx, wy);
if(tile != null && tile.block().insulated){
bhit[0] = true;
//snap it instead of removing
l.lines.get(l.lines.size -1).set(wx * tilesize, wy * tilesize);
return true;
}
return false;
});
if(bhit[0]) break;
}
rect.setSize(hitRange).setCenter(x, y);
entities.clear();
if(hit.size < maxChain){
Units.nearbyEnemies(team, rect, u -> {
if(!hit.contains(u.getID())){
entities.add(u);
}
});
}
Unitc furthest = Geometry.findFurthest(x, y, entities);
if(furthest != null){
hit.add(furthest.getID());
x = furthest.x;
y = furthest.y;
}else{
rotation += random.range(20f);
x += Angles.trnsx(rotation, hitRange / 2f);
y += Angles.trnsy(rotation, hitRange / 2f);
}
}
}
@Override
public float lifetime(){
return lifetime;
}
@Override
public void reset(){
super.reset();
color = Pal.lancerLaser;
lines.clear();
}
@Override
public void removed(){
super.removed();
Pools.free(this);
}
@Override
public void draw(){
Lines.stroke(3f * fout());
Draw.color(color, Color.white, fin());
Lines.beginLine();
Lines.linePoint(x, y);
for(Position p : lines){
Lines.linePoint(p.getX(), p.getY());
}
Lines.endLine();
int i = 0;
for(Position p : lines){
Fill.square(p.getX(), p.getY(), (5f - (float)i++ / lines.size * 2f) * fout(), 45);
}
Draw.reset();
}
@Override
public EntityGroup targetGroup(){
return bulletGroup;
}
}

View File

@@ -1,320 +0,0 @@
package mindustry.entities.effect;
import mindustry.annotations.Annotations.*;
import arc.struct.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import arc.util.pooling.Pool.*;
import arc.util.pooling.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import java.io.*;
import static mindustry.Vars.*;
public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrait, SyncTrait{
private static final IntMap<Puddle> map = new IntMap<>();
private static final float maxLiquid = 70f;
private static final int maxGeneration = 2;
private static final Color tmp = new Color();
private static final Rect rect = new Rect();
private static final Rect rect2 = new Rect();
private static int seeds;
private int loadedPosition = -1;
private float updateTime;
private float lastRipple;
private Tile tile;
private Liquid liquid;
private float amount, targetAmount;
private float accepting;
private byte generation;
/** Deserialization use only! */
public Puddle(){
}
/** Deposists a puddle between tile and source. */
public static void deposit(Tile tile, Tile source, Liquid liquid, float amount){
deposit(tile, source, liquid, amount, 0);
}
/** Deposists a puddle at a tile. */
public static void deposit(Tile tile, Liquid liquid, float amount){
deposit(tile, tile, liquid, amount, 0);
}
/** Returns the puddle on the specified tile. May return null. */
public static Puddle getPuddle(Tile tile){
return map.get(tile.pos());
}
private static void deposit(Tile tile, Tile source, Liquid liquid, float amount, int generation){
if(tile == null) return;
if(tile.floor().isLiquid && !canStayOn(liquid, tile.floor().liquidDrop)){
reactPuddle(tile.floor().liquidDrop, liquid, amount, tile,
(tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
Puddle p = map.get(tile.pos());
if(generation == 0 && p != null && p.lastRipple <= Time.time() - 40f){
Fx.ripple.at(tile.floor().liquidDrop.color,
(tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
p.lastRipple = Time.time();
}
return;
}
Puddle p = map.get(tile.pos());
if(p == null){
if(net.client()) return; //not clientside.
Puddle puddle = Pools.obtain(Puddle.class, Puddle::new);
puddle.tile = tile;
puddle.liquid = liquid;
puddle.amount = amount;
puddle.generation = (byte)generation;
puddle.set((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
puddle.add();
map.put(tile.pos(), puddle);
}else if(p.liquid == liquid){
p.accepting = Math.max(amount, p.accepting);
if(generation == 0 && p.lastRipple <= Time.time() - 40f && p.amount >= maxLiquid / 2f){
Fx.ripple.at(p.liquid.color, (tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
p.lastRipple = Time.time();
}
}else{
p.amount += reactPuddle(p.liquid, liquid, amount, p.tile, p.x, p.y);
}
}
/**
* Returns whether the first liquid can 'stay' on the second one.
* Currently, the only place where this can happen is oil on water.
*/
private static boolean canStayOn(Liquid liquid, Liquid other){
return liquid == Liquids.oil && other == Liquids.water;
}
/** Reacts two liquids together at a location. */
private static float reactPuddle(Liquid dest, Liquid liquid, float amount, Tile tile, float x, float y){
if((dest.flammability > 0.3f && liquid.temperature > 0.7f) ||
(liquid.flammability > 0.3f && dest.temperature > 0.7f)){ //flammable liquid + hot liquid
Fire.create(tile);
if(Mathf.chance(0.006 * amount)){
Call.createBullet(Bullets.fireball, Team.derelict, x, y, Mathf.random(360f), 1f, 1f);
}
}else if(dest.temperature > 0.7f && liquid.temperature < 0.55f){ //cold liquid poured onto hot puddle
if(Mathf.chance(0.5f * amount)){
Fx.steam.at(x, y);
}
return -0.1f * amount;
}else if(liquid.temperature > 0.7f && dest.temperature < 0.55f){ //hot liquid poured onto cold puddle
if(Mathf.chance(0.8f * amount)){
Fx.steam.at(x, y);
}
return -0.4f * amount;
}
return 0f;
}
@Remote(called = Loc.server)
public static void onPuddleRemoved(int puddleid){
puddleGroup.removeByID(puddleid);
}
public float getFlammability(){
return liquid.flammability * amount;
}
@Override
public TypeID getTypeID(){
return TypeIDs.puddle;
}
@Override
public byte version(){
return 0;
}
@Override
public void hitbox(Rect rect){
rect.setCenter(x, y).setSize(tilesize);
}
@Override
public void hitboxTile(Rect rect){
rect.setCenter(x, y).setSize(0f);
}
@Override
public void update(){
//no updating happens clientside
if(net.client()){
amount = Mathf.lerpDelta(amount, targetAmount, 0.15f);
}else{
//update code
float addSpeed = accepting > 0 ? 3f : 0f;
amount -= Time.delta() * (1f - liquid.viscosity) / (5f + addSpeed);
amount += accepting;
accepting = 0f;
if(amount >= maxLiquid / 1.5f && generation < maxGeneration){
float deposited = Math.min((amount - maxLiquid / 1.5f) / 4f, 0.3f) * Time.delta();
for(Point2 point : Geometry.d4){
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
if(other != null && other.block() == Blocks.air){
deposit(other, tile, liquid, deposited, generation + 1);
amount -= deposited / 2f; //tweak to speed up/slow down puddle propagation
}
}
}
amount = Mathf.clamp(amount, 0, maxLiquid);
if(amount <= 0f){
Call.onPuddleRemoved(getID());
}
}
//effects-only code
if(amount >= maxLiquid / 2f && updateTime <= 0f){
Units.nearby(rect.setSize(Mathf.clamp(amount / (maxLiquid / 1.5f)) * 10f).setCenter(x, y), unit -> {
if(unit.isFlying()) return;
unit.hitbox(rect2);
if(!rect.overlaps(rect2)) return;
unit.applyEffect(liquid.effect, 60 * 2);
if(unit.vel().len() > 0.1){
Fx.ripple.at(liquid.color, unit.x, unit.y);
}
});
if(liquid.temperature > 0.7f && (tile.link().entity != null) && Mathf.chance(0.3 * Time.delta())){
Fire.create(tile);
}
updateTime = 20f;
}
updateTime -= Time.delta();
}
@Override
public void draw(){
seeds = id;
boolean onLiquid = tile.floor().isLiquid;
float f = Mathf.clamp(amount / (maxLiquid / 1.5f));
float smag = onLiquid ? 0.8f : 0f;
float sscl = 20f;
Draw.color(tmp.set(liquid.color).shiftValue(-0.05f));
Fill.circle(x + Mathf.sin(Time.time() + seeds * 532, sscl, smag), y + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 8f);
Angles.randLenVectors(id, 3, f * 6f, (ex, ey) -> {
Fill.circle(x + ex + Mathf.sin(Time.time() + seeds * 532, sscl, smag),
y + ey + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 5f);
seeds++;
});
Draw.color();
if(liquid.lightColor.a > 0.001f && f > 0){
Color color = liquid.lightColor;
float opacity = color.a * f;
renderer.lights.add(tile.drawx(), tile.drawy(), 30f * f, color, opacity * 0.8f);
}
}
@Override
public float drawSize(){
return 20;
}
@Override
public void writeSave(DataOutput stream) throws IOException{
stream.writeInt(tile.pos());
stream.writeFloat(x);
stream.writeFloat(y);
stream.writeByte(liquid.id);
stream.writeFloat(amount);
stream.writeByte(generation);
}
@Override
public void readSave(DataInput stream, byte version) throws IOException{
this.loadedPosition = stream.readInt();
this.x = stream.readFloat();
this.y = stream.readFloat();
this.liquid = content.liquid(stream.readByte());
this.amount = stream.readFloat();
this.generation = stream.readByte();
add();
}
@Override
public void reset(){
loadedPosition = -1;
tile = null;
liquid = null;
amount = 0;
generation = 0;
accepting = 0;
}
@Override
public void added(){
if(loadedPosition != -1){
map.put(loadedPosition, this);
tile = world.tile(loadedPosition);
}
}
@Override
public void removed(){
if(tile != null){
map.remove(tile.pos());
}
reset();
}
@Override
public void write(DataOutput data) throws IOException{
data.writeFloat(x);
data.writeFloat(y);
data.writeByte(liquid.id);
data.writeShort((short)(amount * 4));
data.writeInt(tile.pos());
}
@Override
public void read(DataInput data) throws IOException{
x = data.readFloat();
y = data.readFloat();
liquid = content.liquid(data.readByte());
targetAmount = data.readShort() / 4f;
int pos = data.readInt();
tile = world.tile(pos);
map.put(pos, this);
}
@Override
public EntityGroup targetGroup(){
return puddleGroup;
}
}

View File

@@ -1,4 +1,17 @@
package mindustry.entities.units;
public class AIController extends UnitController{
import mindustry.gen.*;
public class AIController implements UnitController{
protected Unitc unit;
@Override
public void unit(Unitc unit){
this.unit = unit;
}
@Override
public Unitc unit(){
return unit;
}
}

View File

@@ -1,28 +0,0 @@
package mindustry.game;
import arc.Core;
/** Presets for time between waves. Currently unused.*/
public enum Difficulty{
easy(1.4f),
normal(1f),
hard(0.5f),
insane(0.25f);
/** Multiplier of the time between waves. */
public final float waveTime;
private String value;
Difficulty(float waveTime){
this.waveTime = waveTime;
}
@Override
public String toString(){
if(value == null){
value = Core.bundle.get("setting.difficulty." + name());
}
return value;
}
}

View File

@@ -315,7 +315,7 @@ public class Schematics implements Loadable{
for(int cy = y; cy <= y2; cy++){
Tile linked = world.ltile(cx, cy);
if(linked != null && linked.entity != null && linked.entity.block.isVisible() && !(linked.block() instanceof BuildBlock)){
if(linked != null && linked.entity != null && linked.entity.block().isVisible() && !(linked.block() instanceof BuildBlock)){
int top = linked.block().size/2;
int bot = linked.block().size % 2 == 1 ? -linked.block().size/2 : -(linked.block().size - 1)/2;
minx = Math.min(linked.x + bot, minx);
@@ -344,7 +344,7 @@ public class Schematics implements Loadable{
Tile tile = world.ltile(cx, cy);
if(tile != null && tile.entity != null && !counted.contains(tile.pos()) && !(tile.block() instanceof BuildBlock)
&& (tile.entity.block.isVisible() || (tile.entity.block instanceof CoreBlock && Core.settings.getBool("coreselect")))){
&& (tile.entity.block().isVisible() || (tile.entity.block() instanceof CoreBlock && Core.settings.getBool("coreselect")))){
int config = tile.entity.config();
if(tile.block().posConfig){
config = Pos.get(Pos.x(config) + offsetX, Pos.y(config) + offsetY);

View File

@@ -5,6 +5,7 @@ import arc.math.geom.*;
import arc.struct.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import mindustry.gen.*;
import mindustry.world.blocks.storage.CoreBlock.*;
import static mindustry.Vars.*;

View File

@@ -162,7 +162,7 @@ public class Tutorial{
},
withdraw(() -> event("withdraw")){
void begin(){
state.teams.playerCores().first().items.add(Items.copper, 10);
state.teams.playerCores().first().items().add(Items.copper, 10);
}
},
deposit(() -> event("deposit")),
@@ -242,8 +242,8 @@ public class Tutorial{
static void placeBlocks(){
Tilec core = state.teams.playerCores().first();
for(int i = 0; i < blocksToBreak; i++){
world.ltile(core.tile.x + blockOffset, core.tile.y + i).remove();
world.tile(core.tile.x + blockOffset, core.tile.y + i).setBlock(Blocks.scrapWall, state.rules.defaultTeam);
world.ltile(core.tile().x + blockOffset, core.tile().y + i).remove();
world.tile(core.tile().x + blockOffset, core.tile().y + i).setBlock(Blocks.scrapWall, state.rules.defaultTeam);
}
}
@@ -251,7 +251,7 @@ public class Tutorial{
Tilec core = state.teams.playerCores().first();
for(int i = 0; i < blocksToBreak; i++){
if(world.tile(core.tile.x + blockOffset, core.tile.y + i).block() == Blocks.scrapWall){
if(world.tile(core.tile().x + blockOffset, core.tile().y + i).block() == Blocks.scrapWall){
return false;
}
}
@@ -271,7 +271,7 @@ public class Tutorial{
}
static int item(Item item){
return state.rules.defaultTeam.data().noCores() ? 0 : state.rules.defaultTeam.core().items.get(item);
return state.rules.defaultTeam.data().noCores() ? 0 : state.rules.defaultTeam.core().items().get(item);
}
static boolean toggled(String name){

View File

@@ -275,7 +275,7 @@ public class BlockRenderer implements Disposable{
if(request.tile.entity != null && request.tile.entity.damaged()){
block.drawCracks(request.tile);
}
if(block.synthetic() && request.tile.getTeam() != player.team()){
if(block.synthetic() && request.tile.team() != player.team()){
block.drawTeam(request.tile);
}

View File

@@ -1,23 +1,20 @@
package mindustry.graphics;
import arc.Core;
import arc.struct.Array;
import arc.func.Floatc2;
import arc.graphics.Camera;
import arc.graphics.Color;
import arc.*;
import arc.func.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.graphics.gl.FrameBuffer;
import arc.graphics.gl.*;
import arc.math.*;
import arc.scene.ui.layout.Scl;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import arc.util.noise.RidgedPerlin;
import arc.util.noise.Simplex;
import mindustry.content.Blocks;
import mindustry.content.UnitTypes;
import mindustry.ui.Cicon;
import arc.util.noise.*;
import mindustry.content.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.blocks.Floor;
import mindustry.world.blocks.OreBlock;
import mindustry.world.blocks.*;
import static mindustry.Vars.*;
@@ -33,7 +30,7 @@ public class MenuRenderer implements Disposable{
private float time = 0f;
private float flyerRot = 45f;
private int flyers = Mathf.chance(0.2) ? Mathf.random(35) : Mathf.random(15);
private UnitType flyerType = Structs.select(UnitTypes.wraith, UnitTypes.wraith, UnitTypes.ghoul, UnitTypes.phantom, UnitTypes.phantom, UnitTypes.revenant);
private UnitDef flyerType = Structs.select(UnitTypes.wraith, UnitTypes.wraith, UnitTypes.ghoul, UnitTypes.phantom, UnitTypes.phantom, UnitTypes.revenant);
public MenuRenderer(){
Time.mark();

View File

@@ -76,7 +76,7 @@ public class MinimapRenderer implements Disposable{
updateUnitArray();
}else{
units.clear();
Units.all(units::add);
Groups.unit.each(units::add);
}
float sz = baseSize * zoom;
@@ -88,20 +88,19 @@ public class MinimapRenderer implements Disposable{
rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize);
for(Unitc unit : units){
if(unit.isDead()) continue;
float rx = !withLabels ? (unit.x - rect.x) / rect.width * w : unit.x / (world.width() * tilesize) * w;
float ry = !withLabels ? (unit.y - rect.y) / rect.width * h : unit.y / (world.height() * tilesize) * h;
float rx = !withLabels ? (unit.x() - rect.x) / rect.width * w : unit.x() / (world.width() * tilesize) * w;
float ry = !withLabels ? (unit.y() - rect.y) / rect.width * h : unit.y() / (world.height() * tilesize) * h;
Draw.mixcol(unit.getTeam().color, 1f);
Draw.mixcol(unit.team().color, 1f);
float scale = Scl.scl(1f) / 2f * scaling * 32f;
Draw.rect(unit.getIconRegion(), x + rx, y + ry, scale, scale, unit.rotation - 90);
Draw.rect(unit.type().region, x + rx, y + ry, scale, scale, unit.rotation() - 90);
Draw.reset();
if(withLabels && unit instanceof Playerc){
Playerc pl = (Playerc) unit;
if(!pl.isLocal){
if(!pl.isLocal()){
// Only display names for other players.
drawLabel(x + rx, y + ry, pl.name, unit.getTeam().color);
drawLabel(x + rx, y + ry, pl.name(), unit.team().color);
}
}
}
@@ -162,7 +161,7 @@ public class MinimapRenderer implements Disposable{
if(bc != 0){
return bc;
}
return Tmp.c1.set(MapIO.colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam())).mul(tile.block().cacheLayer == CacheLayer.walls ? 1f - tile.rotation() / 4f : 1f).rgba();
return Tmp.c1.set(MapIO.colorFor(tile.floor(), tile.block(), tile.overlay(), tile.team())).mul(tile.block().cacheLayer == CacheLayer.walls ? 1f - tile.rotation() / 4f : 1f).rgba();
}
@Override

View File

@@ -8,7 +8,6 @@ import arc.math.geom.*;
import arc.util.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.input.*;
import mindustry.type.*;
@@ -36,12 +35,12 @@ public class OverlayRenderer{
public void drawTop(){
if(Core.settings.getBool("indicators")){
for(Playerc player : Groups.player.all()){
for(Playerc player : Groups.player){
if(Vars.player != player && Vars.player.team() == player.team()){
if(!rect.setSize(Core.camera.width * 0.9f, Core.camera.height * 0.9f)
.setCenter(Core.camera.position.x, Core.camera.position.y).contains(player.x, player.y)){
.setCenter(Core.camera.position.x, Core.camera.position.y).contains(player.x(), player.y())){
Tmp.v1.set(player.x, player.y).sub(Core.camera.position.x, Core.camera.position.y).setLength(indicatorLength);
Tmp.v1.set(player.x(), player.y()).sub(Core.camera.position.x, Core.camera.position.y).setLength(indicatorLength);
Lines.stroke(2f, player.team().color);
Lines.lineAngle(Core.camera.position.x + Tmp.v1.x, Core.camera.position.y + Tmp.v1.y, Tmp.v1.angle(), 4f);
@@ -50,15 +49,15 @@ public class OverlayRenderer{
}
}
Units.all(unit -> {
if(unit != player && unit.team() != player.team() && !rect.setSize(Core.camera.width * 0.9f, Core.camera.height * 0.9f).setCenter(Core.camera.position.x, Core.camera.position.y).contains(unit.x, unit.y)){
Tmp.v1.set(unit.x, unit.y).sub(Core.camera.position.x, Core.camera.position.y).setLength(indicatorLength);
Groups.unit.each(unit -> {
if(unit != player && unit.team() != player.team() && !rect.setSize(Core.camera.width * 0.9f, Core.camera.height * 0.9f).setCenter(Core.camera.position.x, Core.camera.position.y).contains(unit.x(), unit.y())){
Tmp.v1.set(unit.x(), unit.y()).sub(Core.camera.position.x, Core.camera.position.y).setLength(indicatorLength);
Lines.stroke(1f, unit.team().color);
Lines.lineAngle(Core.camera.position.x + Tmp.v1.x, Core.camera.position.y + Tmp.v1.y, Tmp.v1.angle(), 3f);
Draw.reset();
}
});
Lines.stroke(1f, unit.team().color);
Lines.lineAngle(Core.camera.position.x + Tmp.v1.x, Core.camera.position.y + Tmp.v1.y, Tmp.v1.angle(), 3f);
Draw.reset();
}
});
if(ui.hudfrag.blockfrag.currentCategory == Category.upgrade){
for(Tile mechpad : indexer.getAllied(player.team(), BlockFlag.mechPad)){
@@ -98,9 +97,9 @@ public class OverlayRenderer{
float dst = core.dst(player);
if(dst < state.rules.enemyCoreBuildRadius * 2.2f){
Draw.color(Color.darkGray);
Lines.circle(core.x, core.y - 2, state.rules.enemyCoreBuildRadius);
Draw.color(Pal.accent, core.getTeam().color, 0.5f + Mathf.absin(Time.time(), 10f, 0.5f));
Lines.circle(core.x, core.y, state.rules.enemyCoreBuildRadius);
Lines.circle(core.x(), core.y() - 2, state.rules.enemyCoreBuildRadius);
Draw.color(Pal.accent, core.team().color, 0.5f + Mathf.absin(Time.time(), 10f, 0.5f));
Lines.circle(core.x(), core.y(), state.rules.enemyCoreBuildRadius);
}
});
}
@@ -109,7 +108,7 @@ public class OverlayRenderer{
Draw.color(Color.gray, Color.lightGray, Mathf.absin(Time.time(), 8f, 1f));
for(Tile tile : spawner.getGroundSpawns()){
if(tile.withinDst(player.x, player.y, state.rules.dropZoneRadius + spawnerMargin)){
if(tile.withinDst(player.x(), player.y(), state.rules.dropZoneRadius + spawnerMargin)){
Draw.alpha(Mathf.clamp(1f - (player.dst(tile) - state.rules.dropZoneRadius) / spawnerMargin));
Lines.dashCircle(tile.worldx(), tile.worldy(), state.rules.dropZoneRadius);
}
@@ -122,7 +121,7 @@ public class OverlayRenderer{
Vec2 vec = Core.input.mouseWorld(input.getMouseX(), input.getMouseY());
Tile tile = world.ltileWorld(vec.x, vec.y);
if(tile != null && tile.block() != Blocks.air && tile.getTeam() == player.team()){
if(tile != null && tile.block() != Blocks.air && tile.team() == player.team()){
tile.block().drawSelect(tile);
if(Core.input.keyDown(Binding.rotateplaced) && tile.block().rotate && tile.interactable(player.team())){
@@ -138,13 +137,13 @@ public class OverlayRenderer{
if(input.isDroppingItem()){
Vec2 v = Core.input.mouseWorld(input.getMouseX(), input.getMouseY());
float size = 8;
Draw.rect(player.item().item.icon(Cicon.medium), v.x, v.y, size, size);
Draw.rect(player.unit().item().icon(Cicon.medium), v.x, v.y, size, size);
Draw.color(Pal.accent);
Lines.circle(v.x, v.y, 6 + Mathf.absin(Time.time(), 5f, 1f));
Draw.reset();
Tile tile = world.ltileWorld(v.x, v.y);
if(tile != null && tile.interactable(player.team()) && tile.block().acceptStack(player.item().item, player.item().amount, tile, player) > 0){
if(tile != null && tile.interactable(player.team()) && tile.block().acceptStack(player.unit().item(), player.unit().stack().amount, tile, player.unit()) > 0){
Lines.stroke(3f, Pal.gray);
Lines.square(tile.drawx(), tile.drawy(), tile.block().size * tilesize / 2f + 3 + Mathf.absin(Time.time(), 5f, 1f));
Lines.stroke(1f, Pal.place);

View File

@@ -1,16 +1,13 @@
package mindustry.graphics;
import arc.Core;
import arc.graphics.Blending;
import arc.graphics.Texture.TextureFilter;
import arc.graphics.g2d.Draw;
import arc.graphics.gl.FrameBuffer;
import arc.util.Disposable;
import mindustry.gen.*;
import arc.*;
import arc.graphics.*;
import arc.graphics.Texture.*;
import arc.graphics.g2d.*;
import arc.graphics.gl.*;
import arc.util.*;
import static arc.Core.camera;
import static arc.Core.graphics;
import static mindustry.Groups.player;
import static arc.Core.*;
import static mindustry.Vars.renderer;
public class Pixelator implements Disposable{
@@ -55,7 +52,8 @@ public class Pixelator implements Disposable{
Draw.rect(Draw.wrap(buffer.getTexture()), Core.camera.position.x, Core.camera.position.y, Core.camera.width, -Core.camera.height);
Draw.blend();
Groups.player.draw(p -> !p.isDead(), Playerc::drawName);
//TODO implement drawing functions, maybe
//Groups.player.draw(p -> !p.isDead(), Playerc::drawName);
Core.camera.position.set(px, py);
Core.settings.put("animatedwater", hadWater);

View File

@@ -17,7 +17,6 @@ import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
@@ -67,6 +66,34 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
//methods to override
@Remote(called = Loc.server, unreliable = true)
public static <T extends Posc & Itemsc> void transferItemEffect(Item item, float x, float y, T to){
if(to == null) return;
createItemTransfer(item, x, y, to, null);
}
@Remote(called = Loc.server, unreliable = true)
public static <T extends Posc & Itemsc> void transferItemToUnit(Item item, float x, float y, T to){
if(to == null) return;
createItemTransfer(item, x, y, to, () -> to.addItem(item));
}
@Remote(called = Loc.server, unreliable = true)
public static void transferItemTo(Item item, int amount, float x, float y, Tile tile){
if(tile == null || tile.entity == null || tile.entity.items() == null) return;
for(int i = 0; i < Mathf.clamp(amount / 3, 1, 8); i++){
Time.run(i * 3, () -> createItemTransfer(item, x, y, tile, () -> {}));
}
tile.entity.items().add(item, amount);
}
public static void createItemTransfer(Item item, float x, float y, Position to, Runnable done){
Fx.itemTransfer.at(x, y, 0, item.color, to);
if(done != null){
Time.run(Fx.itemTransfer.lifetime, done);
}
}
@Remote(variants = Variant.one)
public static void removeQueueBlock(int x, int y, boolean breaking){
player.removeRequest(x, y, breaking);
@@ -1052,7 +1079,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
if(target == null){
isShooting = false;
if(Core.settings.getBool("autotarget")){
target = Units.closestTarget(team, x, y, mech.range, u -> u.team() != Team.derelict, u -> u.getTeam() != Team.derelict);
target = Units.closestTarget(team, x, y, mech.range, u -> u.team() != Team.derelict, u -> u.team() != Team.derelict);
if(mech.canHeal && target == null){
target = Geometry.findClosest(x, y, indexer.getDamaged(Team.sharded));

View File

@@ -75,11 +75,11 @@ public class MobileInput extends InputHandler implements GestureListener{
}else{
Tile tile = world.ltileWorld(x, y);
if(tile != null && tile.synthetic() && player.team().isEnemy(tile.getTeam())){
if(tile != null && tile.synthetic() && player.team().isEnemy(tile.team())){
Tilec entity = tile.entity;
player.setMineTile(null);
player.target = entity;
}else if(tile != null && player.mech.canHeal && tile.entity != null && tile.getTeam() == player.team() && tile.entity.damaged()){
}else if(tile != null && player.mech.canHeal && tile.entity != null && tile.team() == player.team() && tile.entity.damaged()){
player.setMineTile(null);
player.target = tile.entity;
}

View File

@@ -81,7 +81,7 @@ public class MapIO{
@Override
public void setBlock(Block type){
super.setBlock(type);
int c = colorFor(Blocks.air, block(), Blocks.air, getTeam());
int c = colorFor(Blocks.air, block(), Blocks.air, team());
if(c != black){
walls.draw(x, floors.getHeight() - 1 - y, c);
floors.draw(x, floors.getHeight() - 1 - y + 1, shade);
@@ -138,7 +138,7 @@ public class MapIO{
for(int x = 0; x < pixmap.getWidth(); x++){
for(int y = 0; y < pixmap.getHeight(); y++){
Tile tile = tiles.getn(x, y);
pixmap.draw(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam()));
pixmap.draw(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.overlay(), tile.team()));
}
}
return pixmap;

View File

@@ -6,6 +6,7 @@ import mindustry.ctype.*;
import mindustry.entities.bullet.*;
import mindustry.entities.units.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.net.Administration.*;
import mindustry.net.Packets.*;
import mindustry.type.*;
@@ -20,6 +21,16 @@ import static mindustry.Vars.*;
@SuppressWarnings("unused")
public class TypeIO{
@WriteClass(Entityc.class)
public static void writeEntity(ByteBuffer buffer, Entityc entity){
buffer.putInt(entity == null ? -1 : entity.id());
}
@ReadClass(Entityc.class)
public static <T extends Entityc> T readEntity(ByteBuffer buffer){
return (T)Groups.all.getByID(buffer.getInt());
}
@WriteClass(Tile.class)
public static void writeTile(ByteBuffer buffer, Tile tile){
buffer.putInt(tile == null ? Pos.get(-1, -1) : tile.pos());

View File

@@ -1,7 +1,6 @@
package mindustry.io.versions;
import arc.func.Prov;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.entities.type.base.*;

View File

@@ -3,7 +3,6 @@ package mindustry.io.versions;
import mindustry.ctype.ContentType;
import mindustry.entities.*;
import mindustry.io.*;
import mindustry.type.TypeID;
import java.io.*;

View File

@@ -23,7 +23,7 @@ public class CoreSpawnFilter extends GenerateFilter{
public void apply(Tiles tiles, GenerateInput in){
IntArray spawns = new IntArray();
for(Tile tile : tiles){
if(tile.getTeam() == state.rules.defaultTeam && tile.block() instanceof CoreBlock){
if(tile.team() == state.rules.defaultTeam && tile.block() instanceof CoreBlock){
spawns.add(tile.pos());
}
}

View File

@@ -68,7 +68,7 @@ public class MapGenerator extends Generator{
});
}
if(tile.block() instanceof CoreBlock && tile.getTeam() == state.rules.defaultTeam){
if(tile.block() instanceof CoreBlock && tile.team() == state.rules.defaultTeam){
schematics.placeLoadout(loadout, tile.x, tile.y);
anyCores = true;
}

View File

@@ -1,18 +0,0 @@
package mindustry.type;
import arc.func.*;
import mindustry.ctype.*;
import mindustry.ctype.ContentType;
public class TypeID extends MappableContent{
public final Prov<? extends TypeTrait> constructor;
public TypeID(String name, Prov<? extends TypeTrait> constructor){
super(name);
this.constructor = constructor;
}
@Override
public ContentType getContentType(){
return ContentType.typeid;
}
}

View File

@@ -5,15 +5,12 @@ import arc.audio.*;
import arc.func.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.ctype.*;
import mindustry.entities.type.base.*;
import mindustry.game.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.ui.*;
@@ -21,9 +18,7 @@ import mindustry.ui.*;
//TODO change to UnitType or Shell or something
public class UnitDef extends UnlockableContent{
//TODO implement
public @NonNull Prov<? extends Unitc> constructor = () -> this.flying ? new FlyingUnit() : new GroundUnit();
public TypeID typeID;
public @NonNull Prov<? extends UnitController> defaultController = AIController::new;
public boolean flying;
public float speed = 1.1f, boostSpeed = 0.75f, rotateSpeed = 0.2f, baseRotateSpeed = 0.1f;
public float drag = 0.3f, mass = 1f, accel = 0.1f;
@@ -52,15 +47,10 @@ public class UnitDef extends UnlockableContent{
public UnitDef(String name){
super(name);
//TODO replace with the sane constructor
typeID = new TypeID(name, constructor);
}
public Unitc create(Team team){
Unitc unit = constructor.get();
unit.init(this, team);
return unit;
public UnitController createController(){
return defaultController.get();
}
@Override
@@ -93,50 +83,4 @@ public class UnitDef extends UnlockableContent{
public ContentType getContentType(){
return ContentType.unit;
}
//TODO remove methods below!
public void update(Unitc player){
}
public void draw(Unitc player){
}
public void drawStats(Unitc player){
if(drawCell){
float health = player.healthf();
Draw.color(Color.black, player.team().color, health + Mathf.absin(Time.time(), health * 5f, 1f - health));
Draw.rect(player.getPowerCellRegion(),
player.x + Angles.trnsx(player.rotation, cellOffsetY, cellOffsetX),
player.y + Angles.trnsy(player.rotation, cellOffsetY, cellOffsetX),
player.rotation - 90);
Draw.reset();
}
if(drawItems){
//player.drawBackItems(0f, true);
}
}
public float getExtraArmor(Unitc player){
return 0f;
}
//TODO remove
public float spreadX(Unitc player){
return 0f;
}
//TODO remove
public float getRotationAlpha(Unitc player){
return 1f;
}
public boolean canShoot(Unitc player){
return true;
}
public void onLand(Unitc player){
}
}

View File

@@ -1,80 +1,22 @@
package mindustry.type;
import arc.util.ArcAnnotate.*;
import mindustry.annotations.Annotations.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.type.Weather.*;
import java.io.*;
import static mindustry.Vars.*;
public abstract class Weather<T extends WeatherEntity> extends MappableContent{
public abstract class Weather extends MappableContent{
protected float duration = 100f;
public Weather(String name){
super(name);
}
public abstract void update(T entity);
public abstract void update();
public abstract void draw(T entity);
public abstract void draw();
@Override
public ContentType getContentType(){
return ContentType.weather;
}
/** Represents the in-game state of a weather event. */
@SuppressWarnings("unchecked")
public static class WeatherEntity extends BaseEntity implements SaveTrait, DrawTrait{
/** How long this event has been occuring in ticks. */
protected float life;
/** Type of weather that is being simulated. */
protected @NonNull
Weather weather;
public WeatherEntity(Weather weather){
this.weather = weather;
}
@Override
public void update(){
weather.update(this);
}
@Override
public void draw(){
weather.draw(this);
}
@CallSuper
@Override
public void writeSave(DataOutput stream) throws IOException{
stream.writeShort(weather.id);
}
@CallSuper
@Override
public void readSave(DataInput stream, byte version) throws IOException{
weather = content.getByID(ContentType.weather, stream.readShort());
}
@Override
public byte version(){
return 0;
}
@Override
public TypeID getTypeID(){
return null;
}
@Override
public EntityGroup targetGroup(){
return weatherGroup;
}
}
//TODO implement
}

View File

@@ -1,34 +1,27 @@
package mindustry.ui.fragments;
import arc.*;
import mindustry.annotations.Annotations.*;
import arc.struct.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.input.*;
import arc.math.*;
import arc.math.geom.*;
import arc.scene.*;
import arc.scene.actions.*;
import arc.scene.event.*;
import arc.scene.style.*;
import arc.scene.ui.*;
import arc.scene.ui.ImageButton.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.core.GameState.*;
import mindustry.ctype.ContentType;
import mindustry.ctype.UnlockableContent;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.game.*;
import mindustry.ctype.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.input.*;
import mindustry.net.Packets.*;
import mindustry.ui.*;
import mindustry.ui.Cicon;
import mindustry.ui.dialogs.*;
import static mindustry.Vars.*;
@@ -179,59 +172,6 @@ public class HudFragment extends Fragment{
}
}
}).left();
if(enableUnitEditing){
t.row();
t.addImageTextButton("$editor.spawn", Icon.add, () -> {
FloatingDialog dialog = new FloatingDialog("$editor.spawn");
int i = 0;
for(UnitType type : content.<UnitType>getBy(ContentType.unit)){
dialog.cont.addImageButton(Tex.whiteui, 8 * 6f, () -> {
Call.spawnUnitEditor(player, type);
dialog.hide();
}).get().getStyle().imageUp = new TextureRegionDrawable(type.icon(Cicon.xlarge));
if(++i % 4 == 0) dialog.cont.row();
}
dialog.addCloseButton();
dialog.setFillParent(false);
dialog.show();
}).fillX();
float[] size = {0};
float[] position = {0, 0};
t.row();
t.addImageTextButton("$editor.removeunit", Icon.cancel, Styles.togglet, () -> {}).fillX().update(b -> {
boolean[] found = {false};
if(b.isChecked()){
Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true);
if(e == null){
Vec2 world = Core.input.mouseWorld();
Units.nearby(world.x, world.y, 1f, 1f, unit -> {
if(!found[0] && unit instanceof Unitc){
if(Core.input.keyTap(KeyCode.MOUSE_LEFT)){
Call.removeUnitEditor(player, (Unitc)unit);
}
found[0] = true;
unit.hitbox(Tmp.r1);
size[0] = Mathf.lerpDelta(size[0], Tmp.r1.width * 2f + Mathf.absin(Time.time(), 10f, 5f), 0.1f);
position[0] = unit.x;
position[1] = unit.y;
}
});
}
}
Draw.color(Pal.accent, Color.white, Mathf.absin(Time.time(), 8f, 1f));
Lines.poly(position[0], position[1], 4, size[0] / 2f);
Draw.reset();
if(!found[0]){
size[0] = Mathf.lerpDelta(size[0], 0f, 0.2f);
}
});
}
}).width(dsize * 5 + 4f);
editorMain.visible(() -> shown && state.isEditor());
}
@@ -255,7 +195,7 @@ public class HudFragment extends Fragment{
t.add(new Minimap());
t.row();
//position
t.label(() -> world.toTile(player.x) + "," + world.toTile(player.y))
t.label(() -> player.tileX() + "," + player.tileY())
.visible(() -> Core.settings.getBool("position") && !state.rules.tutorial);
t.top().right();
});
@@ -350,23 +290,6 @@ public class HudFragment extends Fragment{
}
}
@Remote(targets = Loc.both, called = Loc.server)
public static void spawnUnitEditor(Playerc player, UnitType type){
if(state.isEditor()){
Unitc unit = type.create(player.team());
unit.set(player.x, player.y);
unit.rotation = player.rotation;
unit.add();
}
}
@Remote(targets = Loc.both, called = Loc.server, forward = true)
public static void removeUnitEditor(Playerc player, Unitc unit){
if(state.isEditor() && unit != null){
unit.remove();
}
}
private void scheduleToast(Runnable run){
long duration = (int)(3.5 * 1000);
long since = Time.timeSinceMillis(lastToast);
@@ -645,12 +568,12 @@ public class HudFragment extends Fragment{
}
private boolean canSkipWave(){
return state.rules.waves && ((net.server() || player.isAdmin) || !net.active()) && state.enemies == 0 && !spawner.isSpawning() && !state.rules.tutorial;
return state.rules.waves && ((net.server() || player.admin()) || !net.active()) && state.enemies == 0 && !spawner.isSpawning() && !state.rules.tutorial;
}
private void addPlayButton(Table table){
table.right().addImageButton(Icon.play, Styles.righti, 30f, () -> {
if(net.client() && player.isAdmin){
if(net.client() && player.admin()){
Call.onAdminRequest(player, AdminAction.wave);
}else if(inLaunchWave()){
ui.showConfirm("$confirm", "$launch.skip.confirm", () -> !canSkipWave(), () -> state.wavetime = 0f);

View File

@@ -337,7 +337,7 @@ public class PlacementFragment extends Fragment{
t.add(new Image(lastDisplay.getDisplayIcon(hoverTile))).size(8 * 4);
t.labelWrap(lastDisplay.getDisplayName(hoverTile)).left().width(190f).padLeft(5);
}).growX().left();
if(hoverTile.getTeam() == player.team()){
if(hoverTile.team() == player.team()){
topTable.row();
topTable.table(t -> {
t.left().defaults().left();

View File

@@ -129,7 +129,7 @@ public class PlayerListFragment extends Fragment{
t.addImageButton(Icon.zoom, Styles.clearPartiali, () -> Call.onAdminRequest(user, AdminAction.trace));
}).padRight(12).size(bs + 10f, bs);
}else if(!user.isLocal && !user.isAdmin && net.client() && Groups.player.size() >= 3 && player.team() == user.getTeam()){ //votekick
}else if(!user.isLocal && !user.isAdmin && net.client() && Groups.player.size() >= 3 && player.team() == user.team()){ //votekick
button.add().growY();
button.addImageButton(Icon.hammer, Styles.clearPartiali,
@@ -138,7 +138,7 @@ public class PlayerListFragment extends Fragment{
content.add(button).padBottom(-6).width(350f).maxHeight(h + 14);
content.row();
content.addImage().height(4f).color(state.rules.pvp ? user.getTeam().color : Pal.gray).growX();
content.addImage().height(4f).color(state.rules.pvp ? user.team().color : Pal.gray).growX();
content.row();
});

View File

@@ -19,7 +19,6 @@ import arc.util.pooling.*;
import mindustry.annotations.Annotations.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
@@ -317,7 +316,7 @@ public class Block extends BlockStorage{
}
public void drawTeam(Tile tile){
Draw.color(tile.getTeam().color);
Draw.color(tile.team().color);
Draw.rect("block-border", tile.drawx() - size * tilesize / 2f + 4, tile.drawy() - size * tilesize / 2f + 4);
Draw.color();
}
@@ -372,7 +371,7 @@ public class Block extends BlockStorage{
/** Call when some content is produced. This unlocks the content if it is applicable. */
public void useContent(Tile tile, UnlockableContent content){
//only unlocks content in zones
if(!headless && tile.getTeam() == player.team() && world.isZone()){
if(!headless && tile.team() == player.team() && world.isZone()){
logic.handleContent(content);
}
}

View File

@@ -7,7 +7,6 @@ import arc.util.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.ctype.*;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.consumers.*;
@@ -48,7 +47,7 @@ public abstract class BlockStorage extends UnlockableContent{
/** Returns the amount of items this block can accept. */
public int acceptStack(Item item, int amount, Tile tile, Teamc source){
if(acceptItem(item, tile, tile) && hasItems && (source == null || source.team() == tile.getTeam())){
if(acceptItem(item, tile, tile) && hasItems && (source == null || source.team() == tile.team())){
return Math.min(getMaximumAccepted(tile, item) - tile.entity.items().get(item), amount);
}else{
return 0;
@@ -114,7 +113,7 @@ public abstract class BlockStorage extends UnlockableContent{
other = other.block().getLiquidDestination(other, in, liquid);
if(other != null && other.getTeam() == tile.getTeam() && other.block().hasLiquids && canDumpLiquid(tile, other, liquid) && other.entity.liquids() != null){
if(other != null && other.team() == tile.team() && other.block().hasLiquids && canDumpLiquid(tile, other, liquid) && other.entity.liquids() != null){
float ofract = other.entity.liquids().get(liquid) / other.block().liquidCapacity;
float fract = tile.entity.liquids().get(liquid) / liquidCapacity;
@@ -147,7 +146,7 @@ public abstract class BlockStorage extends UnlockableContent{
next = next.link();
next = next.block().getLiquidDestination(next, tile, liquid);
if(next.getTeam() == tile.getTeam() && next.block().hasLiquids && tile.entity.liquids().get(liquid) > 0f){
if(next.team() == tile.team() && next.block().hasLiquids && tile.entity.liquids().get(liquid) > 0f){
if(next.block().acceptLiquid(next, tile, liquid, 0f)){
float ofract = next.entity.liquids().get(liquid) / next.block().liquidCapacity;
@@ -199,7 +198,7 @@ public abstract class BlockStorage extends UnlockableContent{
incrementDump(tile, proximity.size);
Tile other = proximity.get((i + dump) % proximity.size);
Tile in = Edges.getFacingEdge(tile, other);
if(other.getTeam() == tile.getTeam() && other.block().acceptItem(item, other, in) && canDump(tile, other, item)){
if(other.team() == tile.team() && other.block().acceptItem(item, other, in) && canDump(tile, other, item)){
other.block().handleItem(item, other, in);
return;
}
@@ -236,7 +235,7 @@ public abstract class BlockStorage extends UnlockableContent{
for(int ii = 0; ii < Vars.content.items().size; ii++){
Item item = Vars.content.item(ii);
if(other.getTeam() == tile.getTeam() && entity.items().has(item) && other.block().acceptItem(item, other, in) && canDump(tile, other, item)){
if(other.team() == tile.team() && entity.items().has(item) && other.block().acceptItem(item, other, in) && canDump(tile, other, item)){
other.block().handleItem(item, other, in);
tile.entity.items().remove(item, 1);
incrementDump(tile, proximity.size);
@@ -245,7 +244,7 @@ public abstract class BlockStorage extends UnlockableContent{
}
}else{
if(other.getTeam() == tile.getTeam() && other.block().acceptItem(todump, other, in) && canDump(tile, other, todump)){
if(other.team() == tile.team() && other.block().acceptItem(todump, other, in) && canDump(tile, other, todump)){
other.block().handleItem(todump, other, in);
tile.entity.items().remove(todump, 1);
incrementDump(tile, proximity.size);
@@ -271,7 +270,7 @@ public abstract class BlockStorage extends UnlockableContent{
/** Try offloading an item to a nearby container in its facing direction. Returns true if success. */
public boolean offloadDir(Tile tile, Item item){
Tile other = tile.front();
if(other != null && other.getTeam() == tile.getTeam() && other.block().acceptItem(item, other, tile)){
if(other != null && other.team() == tile.team() && other.block().acceptItem(item, other, tile)){
other.block().handleItem(item, other, tile);
return true;
}

View File

@@ -15,7 +15,7 @@ public class CachedTile extends Tile{
}
@Override
public Team getTeam(){
public Team team(){
return Team.get(getTeamID());
}

View File

@@ -143,7 +143,7 @@ public class Tile implements Position{
return (T)block;
}
public Team getTeam(){
public Team team(){
return Team.get(link().team);
}
@@ -281,7 +281,7 @@ public class Tile implements Position{
}
public boolean isEnemyCheat(){
return getTeam() == state.rules.waveTeam && state.rules.enemyCheat;
return team() == state.rules.waveTeam && state.rules.enemyCheat;
}
public boolean isLinked(){
@@ -385,7 +385,7 @@ public class Tile implements Position{
}
public boolean interactable(Team team){
return state.teams.canInteract(team, getTeam());
return state.teams.canInteract(team, team());
}
public @Nullable Item drop(){
@@ -497,7 +497,7 @@ public class Tile implements Position{
@Override
public String toString(){
return floor.name + ":" + block.name + ":" + overlay + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : (entity.getClass())) + ":" + getTeam();
return floor.name + ":" + block.name + ":" + overlay + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : (entity.getClass())) + ":" + team();
}
//remote utility methods

View File

@@ -53,7 +53,7 @@ public class BuildBlock extends Block{
@Remote(called = Loc.server)
public static void onDeconstructFinish(Tile tile, Block block, int builderID){
Team team = tile.getTeam();
Team team = tile.team();
Fx.breakBlock.at(tile.drawx(), tile.drawy(), block.size);
Events.fire(new BlockBuildEndEvent(tile, Groups.player.getByID(builderID), team, true));
tile.remove();

View File

@@ -4,6 +4,7 @@ import arc.graphics.g2d.*;
import arc.math.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
@@ -11,7 +12,7 @@ import static mindustry.Vars.net;
public class RespawnBlock{
public static void drawRespawn(Tile tile, float heat, float progress, float time, Playerc player, Mech to){
public static void drawRespawn(Tile tile, float heat, float progress, float time, Playerc player, UnitDef to){
progress = Mathf.clamp(progress);
Draw.color(Pal.darkMetal);

View File

@@ -64,7 +64,7 @@ public class DeflectorWall extends Wall{
}
//bullet.updateVelocity();
bullet.resetOwner(entity, entity.getTeam());
bullet.resetOwner(entity, entity.team());
bullet.scaleTime(1f);
bullet.deflect();

View File

@@ -36,7 +36,7 @@ public class ForceProjector extends Block{
private static ForceProjector paramBlock;
private static ForceEntity paramEntity;
private static Cons<Shielderc> shieldConsumer = trait -> {
if(trait.team() != paramTile.getTeam() && Intersector.isInsideHexagon(trait.x(), trait.y(), paramBlock.realRadius(paramEntity) * 2f, paramTile.drawx(), paramTile.drawy())){
if(trait.team() != paramTile.team() && Intersector.isInsideHexagon(trait.x(), trait.y(), paramBlock.realRadius(paramEntity) * 2f, paramTile.drawx(), paramTile.drawy())){
trait.absorb();
Fx.absorb.at(trait);
paramEntity.hit = 1f;

View File

@@ -31,7 +31,7 @@ public class ShockMine extends Block{
@Override
public void drawLayer(Tile tile){
super.draw(tile);
Draw.color(tile.getTeam().color);
Draw.color(tile.team().color);
Draw.alpha(0.22f);
Fill.rect(tile.drawx(), tile.drawy(), 2f, 2f);
Draw.color();
@@ -49,9 +49,9 @@ public class ShockMine extends Block{
@Override
public void unitOn(Tile tile, Unitc unit){
if(unit.getTeam() != tile.getTeam() && tile.entity.timer(timerDamage, cooldown)){
if(unit.team() != tile.team() && tile.entity.timer(timerDamage, cooldown)){
for(int i = 0; i < tendrils; i++){
Lightning.create(tile.getTeam(), Pal.lancerLaser, damage, tile.drawx(), tile.drawy(), Mathf.random(360f), length);
Lightning.create(tile.team(), Pal.lancerLaser, damage, tile.drawx(), tile.drawy(), Mathf.random(360f), length);
}
tile.entity.damage(tileDamage);
}

View File

@@ -1,9 +1,9 @@
package mindustry.world.blocks.defense;
import arc.math.Mathf;
import mindustry.entities.effect.Lightning;
import arc.math.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.graphics.Pal;
import mindustry.graphics.*;
public class SurgeWall extends Wall{
public float lightningChance = 0.05f;
@@ -15,10 +15,10 @@ public class SurgeWall extends Wall{
}
@Override
public void handleBulletHit(Tilec entity, Bullet bullet){
public void handleBulletHit(Tilec entity, Bulletc bullet){
super.handleBulletHit(entity, bullet);
if(Mathf.chance(lightningChance)){
Lightning.create(entity.team(), Pal.surge, lightningDamage, bullet.x, bullet.y, bullet.rotation() + 180f, lightningLength);
Lightning.create(entity.team(), Pal.surge, lightningDamage, bullet.x(), bullet.y(), bullet.rotation() + 180f, lightningLength);
}
}
}

View File

@@ -36,7 +36,7 @@ public class ArtilleryTurret extends ItemTurret{
float maxTraveled = type.lifetime * type.speed;
for(int i = 0; i < shots; i++){
Bullet.create(ammo, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y,
Bullet.create(ammo, tile.entity, tile.team(), tile.drawx() + tr.x, tile.drawy() + tr.y,
entity.rotation + Mathf.range(inaccuracy + type.inaccuracy), 1f + Mathf.range(velocityInaccuracy), (dst / maxTraveled));
}

View File

@@ -3,6 +3,7 @@ package mindustry.world.blocks.defense.turrets;
import arc.math.*;
import arc.util.*;
import mindustry.entities.bullet.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.consumers.*;
@@ -94,7 +95,7 @@ public class LaserTurret extends PowerTurret{
protected void bullet(Tile tile, BulletType type, float angle){
LaserTurretEntity entity = tile.ent();
entity.bullet = Bullet.create(type, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle);
entity.bullet = Bullet.create(type, tile.entity, tile.team(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle);
entity.bulletLife = shootDuration;
}
@@ -106,7 +107,7 @@ public class LaserTurret extends PowerTurret{
}
class LaserTurretEntity extends TurretEntity{
Bullet bullet;
Bulletc bullet;
float bulletLife;
}
}

View File

@@ -5,7 +5,6 @@ import arc.graphics.g2d.*;
import arc.struct.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
import mindustry.entities.effect.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;

View File

@@ -131,7 +131,7 @@ public abstract class Turret extends Block{
@Override
public void drawSelect(Tile tile){
Drawf.dashCircle(tile.drawx(), tile.drawy(), range, tile.getTeam().color);
Drawf.dashCircle(tile.drawx(), tile.drawy(), range, tile.team().color);
}
@Override
@@ -184,16 +184,16 @@ public abstract class Turret extends Block{
protected boolean validateTarget(Tile tile){
TurretEntity entity = tile.ent();
return !Units.invalidateTarget(entity.target, tile.getTeam(), tile.drawx(), tile.drawy());
return !Units.invalidateTarget(entity.target, tile.team(), tile.drawx(), tile.drawy());
}
protected void findTarget(Tile tile){
TurretEntity entity = tile.ent();
if(targetAir && !targetGround){
entity.target = Units.closestEnemy(tile.getTeam(), tile.drawx(), tile.drawy(), range, e -> !e.dead() && e.isFlying());
entity.target = Units.closestEnemy(tile.team(), tile.drawx(), tile.drawy(), range, e -> !e.dead() && e.isFlying());
}else{
entity.target = Units.closestTarget(tile.getTeam(), tile.drawx(), tile.drawy(), range, e -> !e.dead() && (!e.isFlying() || targetAir) && (e.isFlying() || targetGround));
entity.target = Units.closestTarget(tile.team(), tile.drawx(), tile.drawy(), range, e -> !e.dead() && (!e.isFlying() || targetAir) && (e.isFlying() || targetGround));
}
}
@@ -267,7 +267,7 @@ public abstract class Turret extends Block{
}
protected void bullet(Tile tile, BulletType type, float angle){
Bullet.create(type, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle);
Bullet.create(type, tile.entity, tile.team(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle);
}
protected void effects(Tile tile){

View File

@@ -95,7 +95,7 @@ public class Conveyor extends Block implements Autotiler{
if(tile.front() != null && tile.front().entity != null){
entity.next = tile.front().entity;
entity.nextc = entity.next instanceof ConveyorEntity && entity.next.team() == tile.getTeam() ? (ConveyorEntity)entity.next : null;
entity.nextc = entity.next instanceof ConveyorEntity && entity.next.team() == tile.team() ? (ConveyorEntity)entity.next : null;
entity.aligned = entity.nextc != null && tile.rotation() == entity.next.tile.rotation();
}
}

View File

@@ -255,7 +255,7 @@ public class ItemBridge extends Block{
@Override
public boolean acceptItem(Item item, Tile tile, Tile source){
if(tile.getTeam() != source.getTeam()) return false;
if(tile.team() != source.team()) return false;
ItemBridgeEntity entity = tile.ent();
Tile other = world.tile(entity.link);
@@ -301,7 +301,7 @@ public class ItemBridge extends Block{
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
if(tile.getTeam() != source.getTeam() || !hasLiquids) return false;
if(tile.team() != source.team() || !hasLiquids) return false;
ItemBridgeEntity entity = tile.ent();
Tile other = world.tile(entity.link);

View File

@@ -57,7 +57,7 @@ public class Junction extends Block{
if(dest != null) dest = dest.link();
//skip blocks that don't want the item, keep waiting until they do
if(dest == null || !dest.block().acceptItem(item, dest, tile) || dest.getTeam() != tile.getTeam()){
if(dest == null || !dest.block().acceptItem(item, dest, tile) || dest.team() != tile.team()){
continue;
}
@@ -83,7 +83,7 @@ public class Junction extends Block{
if(entity == null || relative == -1 || !entity.buffer.accepts(relative)) return false;
Tile to = tile.getNearby(relative);
return to != null && to.link().entity != null && to.getTeam() == tile.getTeam();
return to != null && to.link().entity != null && to.team() == tile.team();
}
class JunctionEntity extends Tilec{

View File

@@ -214,7 +214,7 @@ public class MassDriver extends Block{
if(entity.link == other.pos()){
tile.configure(-1);
return false;
}else if(other.block() instanceof MassDriver && other.dst(tile) <= range && other.getTeam() == tile.getTeam()){
}else if(other.block() instanceof MassDriver && other.dst(tile) <= range && other.team() == tile.team()){
tile.configure(other.pos());
return false;
}
@@ -248,9 +248,9 @@ public class MassDriver extends Block{
float angle = tile.angleTo(target);
Bullet.create(Bullets.driverBolt, entity, entity.getTeam(),
Bullets.driverBolt.create(entity, entity.team(),
tile.drawx() + Angles.trnsx(angle, translation), tile.drawy() + Angles.trnsy(angle, translation),
angle, 1f, 1f, data);
angle, -1f, 1f, 1f, data);
shootEffect.at(tile.drawx() + Angles.trnsx(angle, translation),
tile.drawy() + Angles.trnsy(angle, translation), angle);
@@ -261,7 +261,7 @@ public class MassDriver extends Block{
Effects.shake(shake, shake, entity);
}
protected void handlePayload(MassDriverEntity entity, Bullet bullet, DriverBulletData data){
protected void handlePayload(MassDriverEntity entity, Bulletc bullet, DriverBulletData data){
int totalItems = entity.items().total();
//add all the items possible
@@ -297,7 +297,7 @@ public class MassDriver extends Block{
if(entity == null || entity.link == -1) return false;
Tile link = world.tile(entity.link);
return link != null && link.block() instanceof MassDriver && link.getTeam() == tile.getTeam() && tile.dst(link) <= range;
return link != null && link.block() instanceof MassDriver && link.team() == tile.team() && tile.dst(link) <= range;
}
public static class DriverBulletData implements Poolable{
@@ -322,8 +322,8 @@ public class MassDriver extends Block{
return waitingShooters.isEmpty() ? null : waitingShooters.first();
}
public void handlePayload(Bullet bullet, DriverBulletData data){
((MassDriver)block).handlePayload(this, bullet, data);
public void handlePayload(Bulletc bullet, DriverBulletData data){
((MassDriver)block()).handlePayload(this, bullet, data);
}
@Override

View File

@@ -63,7 +63,7 @@ public class OverflowGate extends Block{
public boolean acceptItem(Item item, Tile tile, Tile source){
OverflowGateEntity entity = tile.ent();
return tile.getTeam() == source.getTeam() && entity.lastItem == null && entity.items().total() == 0;
return tile.team() == source.team() && entity.lastItem == null && entity.items().total() == 0;
}
@Override
@@ -83,13 +83,13 @@ public class OverflowGate extends Block{
Tile to = tile.getNearby((from + 2) % 4);
if(to == null) return null;
Tile edge = Edges.getFacingEdge(tile, to);
boolean canForward = to.block().acceptItem(item, to, edge) && to.getTeam() == tile.getTeam() && !(to.block() instanceof OverflowGate);
boolean canForward = to.block().acceptItem(item, to, edge) && to.team() == tile.team() && !(to.block() instanceof OverflowGate);
if(!canForward || invert){
Tile a = tile.getNearby(Mathf.mod(from - 1, 4));
Tile b = tile.getNearby(Mathf.mod(from + 1, 4));
boolean ac = a != null && a.block().acceptItem(item, a, edge) && !(a.block() instanceof OverflowGate) && a.getTeam() == tile.getTeam();
boolean bc = b != null && b.block().acceptItem(item, b, edge) && !(b.block() instanceof OverflowGate) && b.getTeam() == tile.getTeam();
boolean ac = a != null && a.block().acceptItem(item, a, edge) && !(a.block() instanceof OverflowGate) && a.team() == tile.team();
boolean bc = b != null && b.block().acceptItem(item, b, edge) && !(b.block() instanceof OverflowGate) && b.team() == tile.team();
if(!ac && !bc){
return invert && canForward ? to : null;

View File

@@ -47,7 +47,7 @@ public class Router extends Block{
public boolean acceptItem(Item item, Tile tile, Tile source){
RouterEntity entity = tile.ent();
return tile.getTeam() == source.getTeam() && entity.lastItem == null && entity.items().total() == 0;
return tile.team() == source.team() && entity.lastItem == null && entity.items().total() == 0;
}
@Override

View File

@@ -74,7 +74,7 @@ public class Sorter extends Block{
public boolean acceptItem(Item item, Tile tile, Tile source){
Tile to = getTileTarget(item, tile, source, false);
return to != null && to.block().acceptItem(item, to, tile) && to.getTeam() == tile.getTeam();
return to != null && to.block().acceptItem(item, to, tile) && to.team() == tile.team();
}
@Override

View File

@@ -28,7 +28,7 @@ public class ArmoredConduit extends Conduit{
// draw the cap when a conduit would normally leak
Tile next = tile.front();
if(next != null && next.getTeam() == tile.getTeam() && next.block().hasLiquids) return;
if(next != null && next.team() == tile.team() && next.block().hasLiquids) return;
Draw.rect(capRegion, tile.drawx(), tile.drawy(), tile.rotation() * 90);
}

View File

@@ -27,7 +27,7 @@ public class PowerDiode extends Block{
public void update(Tile tile){
super.update(tile);
if(tile.front() == null || tile.back() == null || !tile.back().block().hasPower || !tile.front().block().hasPower || tile.back().getTeam() != tile.front().getTeam()) return;
if(tile.front() == null || tile.back() == null || !tile.back().block().hasPower || !tile.front().block().hasPower || tile.back().team() != tile.front().team()) return;
PowerGraph backGraph = tile.back().entity.power().graph;
PowerGraph frontGraph = tile.front().entity.power().graph;

View File

@@ -134,7 +134,7 @@ public class PowerNode extends PowerBlock{
private void getPotentialLinks(Tile tile, Cons<Tile> others){
Boolf<Tile> valid = other -> other != null && other != tile && other.entity != null && other.entity.power() != null &&
((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) &&
overlaps(tile.x * tilesize + offset(), tile.y * tilesize + offset(), other, laserRange * tilesize) && other.getTeam() == player.team()
overlaps(tile.x * tilesize + offset(), tile.y * tilesize + offset(), other, laserRange * tilesize) && other.team() == player.team()
&& !other.entity.proximity().contains(tile) && !graphs.contains(other.entity.power().graph);
tempTiles.clear();
@@ -289,7 +289,7 @@ public class PowerNode extends PowerBlock{
}
public boolean linkValid(Tile tile, Tile link, boolean checkMaxNodes){
if(tile == link || link == null || link.entity == null || tile.entity == null || !link.block().hasPower || tile.getTeam() != link.getTeam()) return false;
if(tile == link || link == null || link.entity == null || tile.entity == null || !link.block().hasPower || tile.team() != link.team()) return false;
if(overlaps(tile, link, laserRange * tilesize) || (link.block() instanceof PowerNode && overlaps(link, tile, link.<PowerNode>cblock().laserRange * tilesize))){
if(checkMaxNodes && link.block() instanceof PowerNode){

View File

@@ -83,7 +83,7 @@ public class CoreBlock extends StorageBlock{
public void onProximityUpdate(Tile tile){
CoreEntity entity = tile.ent();
for(Tilec other : state.teams.cores(tile.getTeam())){
for(Tilec other : state.teams.cores(tile.team())){
if(other.tile() != tile){
entity.items(other.items());
}
@@ -96,7 +96,7 @@ public class CoreBlock extends StorageBlock{
t.<StorageBlockEntity>ent().linkedCore = tile;
});
for(Tilec other : state.teams.cores(tile.getTeam())){
for(Tilec other : state.teams.cores(tile.team())){
if(other.tile() == tile) continue;
entity.storageCapacity += other.block().itemCapacity + other.proximity().sum(e -> isContainer(e) ? e.block().itemCapacity : 0);
}
@@ -107,7 +107,7 @@ public class CoreBlock extends StorageBlock{
}
}
for(CoreEntity other : state.teams.cores(tile.getTeam())){
for(CoreEntity other : state.teams.cores(tile.team())){
other.storageCapacity = entity.storageCapacity;
}
}
@@ -137,7 +137,7 @@ public class CoreBlock extends StorageBlock{
@Override
public float handleDamage(Tile tile, float amount){
//TODO implement
//if(player != null && tile.getTeam() == player.team()){
//if(player != null && tile.team() == player.team()){
// Events.fire(Trigger.teamCoreDamage);
//}
return amount;
@@ -152,7 +152,7 @@ public class CoreBlock extends StorageBlock{
public void removed(Tile tile){
CoreEntity entity = tile.ent();
int total = tile.entity.proximity().count(e -> e.entity != null && e.entity.items() != null && e.entity.items() == tile.entity.items());
float fract = 1f / total / state.teams.cores(tile.getTeam()).size;
float fract = 1f / total / state.teams.cores(tile.team()).size;
tile.entity.proximity().each(e -> isContainer(e) && e.entity.items() == tile.entity.items(), t -> {
StorageBlockEntity ent = (StorageBlockEntity)t.entity;
@@ -165,12 +165,12 @@ public class CoreBlock extends StorageBlock{
state.teams.unregisterCore(entity);
int max = itemCapacity * state.teams.cores(tile.getTeam()).size;
int max = itemCapacity * state.teams.cores(tile.team()).size;
for(Item item : content.items()){
tile.entity.items().set(item, Math.min(tile.entity.items().get(item), max));
}
for(CoreEntity other : state.teams.cores(tile.getTeam())){
for(CoreEntity other : state.teams.cores(tile.team())){
other.block().onProximityUpdate(other.tile());
}
}

View File

@@ -65,7 +65,7 @@ public class Unloader extends Block{
if(tile.entity.timer(timerUnload, speed / entity.timeScale) && tile.entity.items().total() == 0){
for(Tile other : tile.entity.proximity()){
if(other.interactable(tile.getTeam()) && other.block().unloadable && other.block().hasItems && entity.items().total() == 0 &&
if(other.interactable(tile.team()) && other.block().unloadable && other.block().hasItems && entity.items().total() == 0 &&
((entity.sortItem == null && other.entity.items().total() > 0) || hasItem(other, entity.sortItem))){
offloadNear(tile, removeItem(other, entity.sortItem));
}

View File

@@ -41,7 +41,7 @@ public class CommandCenter extends Block{
@Override
public void placed(Tile tile){
super.placed(tile);
ObjectSet<Tile> set = indexer.getAllied(tile.getTeam(), BlockFlag.comandCenter);
ObjectSet<Tile> set = indexer.getAllied(tile.team(), BlockFlag.comandCenter);
if(set.size > 0){
CommandCenterEntity entity = tile.ent();
@@ -54,10 +54,10 @@ public class CommandCenter extends Block{
public void removed(Tile tile){
super.removed(tile);
ObjectSet<Tile> set = indexer.getAllied(tile.getTeam(), BlockFlag.comandCenter);
ObjectSet<Tile> set = indexer.getAllied(tile.team(), BlockFlag.comandCenter);
if(set.size == 1){
Units.each(tile.getTeam(), u -> u.onCommand(UnitCommand.all[0]));
Groups.unit.each(t -> t.team() == tile.team(), u -> u.onCommand(UnitCommand.all[0]));
}
}
@@ -106,14 +106,14 @@ public class CommandCenter extends Block{
UnitCommand command = UnitCommand.all[value];
((CommandCenter)tile.block()).effect.at(tile);
for(Tile center : indexer.getAllied(tile.getTeam(), BlockFlag.comandCenter)){
for(Tile center : indexer.getAllied(tile.team(), BlockFlag.comandCenter)){
if(center.block() instanceof CommandCenter){
CommandCenterEntity entity = center.ent();
entity.command = command;
}
}
Units.each(tile.getTeam(), u -> u.onCommand(command));
Groups.unit.each(t -> t.team() == tile.team(), u -> u.onCommand(command));
Events.fire(new CommandIssueEvent(tile, command));
}

View File

@@ -127,7 +127,7 @@ public class RepairPoint extends Block{
if(entity.timer(timerTarget, 20)){
rect.setSize(repairRadius * 2).setCenter(tile.drawx(), tile.drawy());
entity.target = Units.closest(tile.getTeam(), tile.drawx(), tile.drawy(), repairRadius,
entity.target = Units.closest(tile.team(), tile.drawx(), tile.drawy(), repairRadius,
unit -> unit.health < unit.maxHealth());
}
}

View File

@@ -54,7 +54,7 @@ public class UnitFactory extends Block{
if(!net.client()){
//TODO create the unit
/*
Unitc unit = factory.unitType.create(tile.getTeam());
Unitc unit = factory.unitType.create(tile.team());
unit.setSpawner(tile);
unit.set(tile.drawx() + Mathf.range(4), tile.drawy() + Mathf.range(4));
unit.add();

View File

@@ -4,6 +4,7 @@ import arc.struct.*;
import arc.func.*;
import arc.scene.ui.layout.*;
import arc.util.ArcAnnotate.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.ui.Cicon;

View File

@@ -3,6 +3,7 @@ package mindustry.world.consumers;
import arc.struct.*;
import arc.scene.ui.layout.*;
import arc.util.ArcAnnotate.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.ui.Cicon;