Many things

This commit is contained in:
Anuken
2019-06-15 23:26:43 -04:00
parent 2500d0a930
commit 273c74b275
11 changed files with 112 additions and 81 deletions
+1
View File
@@ -352,6 +352,7 @@ zone.desolateRift.name = Desolate Rift
zone.nuclearComplex.name = Nuclear Production Complex zone.nuclearComplex.name = Nuclear Production Complex
zone.overgrowth.name = Overgrowth zone.overgrowth.name = Overgrowth
zone.tarFields.name = Tar Fields zone.tarFields.name = Tar Fields
zone.saltFlats.name = Salt Flats
settings.language = Language settings.language = Language
settings.reset = Reset to Defaults settings.reset = Reset to Defaults
Binary file not shown.
@@ -246,8 +246,28 @@ public class TechTree implements ContentList{
}); });
}); });
node(spiritFactory, () -> { node(draugFactory, () -> {
node(phantomFactory); node(spiritFactory, () -> {
node(phantomFactory);
});
node(daggerFactory, () -> {
node(crawlerFactory, () -> {
node(titanFactory, () -> {
node(fortressFactory, () -> {
});
});
});
node(wraithFactory, () -> {
node(spiritFactory, () -> {
node(revenantFactory, () -> {
});
});
});
});
}); });
node(dartPad, () -> { node(dartPad, () -> {
@@ -84,6 +84,7 @@ public class Zones implements ContentList{
launchPeriod = 5; launchPeriod = 5;
loadout = Loadouts.basicFoundation; loadout = Loadouts.basicFoundation;
zoneRequirements = ZoneRequirement.with(desertWastes, 60); zoneRequirements = ZoneRequirement.with(desertWastes, 60);
blockRequirements = new Block[]{Blocks.daggerFactory, Blocks.draugFactory};
resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand}; resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand};
}}; }};
+24 -9
View File
@@ -6,17 +6,21 @@ import io.anuke.arc.ApplicationListener;
import io.anuke.arc.Events; import io.anuke.arc.Events;
import io.anuke.arc.collection.ObjectSet.ObjectSetIterator; import io.anuke.arc.collection.ObjectSet.ObjectSetIterator;
import io.anuke.arc.util.Time; import io.anuke.arc.util.Time;
import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.content.*;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.entities.type.Player;
import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.type.TileEntity;
import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.Teams.TeamData;
import io.anuke.mindustry.gen.BrokenBlock;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.BuildBlock;
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -39,13 +43,25 @@ public class Logic implements ApplicationListener{
p.respawns = state.rules.respawns; p.respawns = state.rules.respawns;
} }
}); });
}
@Override Events.on(BlockDestroyEvent.class, event -> {
public void init(){ //blocks that get broken are appended to the team's broken block queue
collisions.setCollider(tilesize, (x, y) -> { Tile tile = event.tile;
Tile tile = world.tile(x, y); Block block = tile.block();
return tile != null && tile.solid(); if(block instanceof BuildBlock){
BuildEntity entity = tile.entity();
//update block to reflect the fact that something was being constructed
if(entity.cblock != null && entity.cblock.synthetic()){
block = entity.cblock;
}else{
//otherwise this was a deconstruction that was interrupted, don't want to rebuild that
return;
}
}
TeamData data = state.teams.get(tile.getTeam());
data.brokenBlocks.addFirst(BrokenBlock.get(tile.x, tile.y, block.id, tile.rotation()));
}); });
} }
@@ -197,7 +213,6 @@ public class Logic implements ApplicationListener{
} }
collisions.collideGroups(bulletGroup, playerGroup); collisions.collideGroups(bulletGroup, playerGroup);
collisions.collideGroups(playerGroup, playerGroup);
} }
world.pathfinder.update(); world.pathfinder.update();
@@ -1,11 +1,14 @@
package io.anuke.mindustry.entities; package io.anuke.mindustry.entities;
import io.anuke.arc.collection.Array; import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.IntSet;
import io.anuke.arc.math.Mathf; import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.*; import io.anuke.arc.math.geom.*;
import io.anuke.mindustry.entities.traits.Entity; import io.anuke.mindustry.entities.traits.Entity;
import io.anuke.mindustry.entities.traits.SolidTrait; import io.anuke.mindustry.entities.traits.SolidTrait;
import io.anuke.mindustry.world.Tile;
import static io.anuke.mindustry.Vars.tilesize;
import static io.anuke.mindustry.Vars.world;
public class EntityCollisions{ public class EntityCollisions{
//range for tile collision scanning //range for tile collision scanning
@@ -14,29 +17,15 @@ public class EntityCollisions{
private static final float seg = 1f; private static final float seg = 1f;
//tile collisions //tile collisions
private float tilesize;
private Rectangle tmp = new Rectangle(); private Rectangle tmp = new Rectangle();
private TileCollider collider;
private TileHitboxProvider hitboxProvider;
private Vector2 vector = new Vector2(); private Vector2 vector = new Vector2();
private Vector2 l1 = new Vector2(); private Vector2 l1 = new Vector2();
private Rectangle r1 = new Rectangle(); private Rectangle r1 = new Rectangle();
private Rectangle r2 = new Rectangle(); private Rectangle r2 = new Rectangle();
//entity collisions //entity collisions
private IntSet collided = new IntSet();
private Array<SolidTrait> arrOut = new Array<>(); private Array<SolidTrait> arrOut = new Array<>();
public void setCollider(float tilesize, TileCollider collider, TileHitboxProvider hitbox){
this.tilesize = tilesize;
this.collider = collider;
this.hitboxProvider = hitbox;
}
public void setCollider(float tilesize, TileCollider collider){
setCollider(tilesize, collider, (x, y, out) -> out.setSize(tilesize).setCenter(x * tilesize, y * tilesize));
}
public void move(SolidTrait entity, float deltax, float deltay){ public void move(SolidTrait entity, float deltax, float deltay){
boolean movedx = false; boolean movedx = false;
@@ -67,8 +56,6 @@ public class EntityCollisions{
} }
public void moveDelta(SolidTrait entity, float deltax, float deltay, boolean x){ public void moveDelta(SolidTrait entity, float deltax, float deltay, boolean x){
if(collider == null)
throw new IllegalArgumentException("No tile collider specified! Call setCollider() first.");
Rectangle rect = r1; Rectangle rect = r1;
entity.hitboxTile(rect); entity.hitboxTile(rect);
@@ -81,9 +68,8 @@ public class EntityCollisions{
for(int dx = -r; dx <= r; dx++){ for(int dx = -r; dx <= r; dx++){
for(int dy = -r; dy <= r; dy++){ for(int dy = -r; dy <= r; dy++){
int wx = dx + tilex, wy = dy + tiley; int wx = dx + tilex, wy = dy + tiley;
if(collider.solid(wx, wy) && entity.collidesGrid(wx, wy)){ if(solid(wx, wy) && entity.collidesGrid(wx, wy)){
tmp.setSize(tilesize).setCenter(wx * tilesize, wy * tilesize);
hitboxProvider.getHitbox(wx, wy, tmp);
if(tmp.overlaps(rect)){ if(tmp.overlaps(rect)){
Vector2 v = Geometry.overlap(rect, tmp, x); Vector2 v = Geometry.overlap(rect, tmp, x);
@@ -99,9 +85,6 @@ public class EntityCollisions{
} }
public boolean overlapsTile(Rectangle rect){ public boolean overlapsTile(Rectangle rect){
if(collider == null)
throw new IllegalArgumentException("No tile collider specified! Call setCollider() first.");
rect.getCenter(vector); rect.getCenter(vector);
int r = 1; int r = 1;
@@ -112,8 +95,8 @@ public class EntityCollisions{
for(int dx = -r; dx <= r; dx++){ for(int dx = -r; dx <= r; dx++){
for(int dy = -r; dy <= r; dy++){ for(int dy = -r; dy <= r; dy++){
int wx = dx + tilex, wy = dy + tiley; int wx = dx + tilex, wy = dy + tiley;
if(collider.solid(wx, wy)){ if(solid(wx, wy)){
hitboxProvider.getHitbox(wx, wy, r2); r2.setSize(tilesize).setCenter(wx * tilesize, wy * tilesize);
if(r2.overlaps(rect)){ if(r2.overlaps(rect)){
return true; return true;
@@ -126,7 +109,6 @@ public class EntityCollisions{
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends Entity> void updatePhysics(EntityGroup<T> group){ public <T extends Entity> void updatePhysics(EntityGroup<T> group){
collided.clear();
QuadTree tree = group.tree(); QuadTree tree = group.tree();
tree.clear(); tree.clear();
@@ -140,6 +122,11 @@ public class EntityCollisions{
} }
} }
private static boolean solid(int x, int y){
Tile tile = world.tile(x, y);
return tile != null && tile.solid();
}
private void checkCollide(Entity entity, Entity other){ private void checkCollide(Entity entity, Entity other){
SolidTrait a = (SolidTrait)entity; SolidTrait a = (SolidTrait)entity;
@@ -221,10 +208,9 @@ public class EntityCollisions{
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void collideGroups(EntityGroup<?> groupa, EntityGroup<?> groupb){ public void collideGroups(EntityGroup<?> groupa, EntityGroup<?> groupb){
collided.clear();
for(Entity entity : groupa.all()){ for(Entity entity : groupa.all()){
if(!(entity instanceof SolidTrait) || collided.contains(entity.getID())) if(!(entity instanceof SolidTrait))
continue; continue;
SolidTrait solid = (SolidTrait)entity; SolidTrait solid = (SolidTrait)entity;
@@ -241,20 +227,10 @@ public class EntityCollisions{
for(SolidTrait sc : arrOut){ for(SolidTrait sc : arrOut){
sc.hitbox(r1); sc.hitbox(r1);
if(r2.overlaps(r1) && !collided.contains(sc.getID())){ if(r2.overlaps(r1)){
checkCollide(entity, sc); checkCollide(entity, sc);
} }
} }
collided.add(entity.getID());
} }
} }
public interface TileCollider{
boolean solid(int x, int y);
}
public interface TileHitboxProvider{
void getHitbox(int x, int y, Rectangle out);
}
} }
@@ -129,6 +129,8 @@ public class EventType{
} }
} }
/** Called right before a block is destroyed.
* The tile entity of the tile in this event cannot be null when this happens.*/
public static class BlockDestroyEvent{ public static class BlockDestroyEvent{
public final Tile tile; public final Tile tile;
@@ -1,5 +1,6 @@
package io.anuke.mindustry.game; package io.anuke.mindustry.game;
import io.anuke.annotations.Annotations.Struct;
import io.anuke.arc.collection.*; import io.anuke.arc.collection.*;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
@@ -43,6 +44,7 @@ public class Teams{
public class TeamData{ public class TeamData{
public final ObjectSet<Tile> cores = new ObjectSet<>(); public final ObjectSet<Tile> cores = new ObjectSet<>();
public final LongQueue brokenBlocks = new LongQueue();
public final EnumSet<Team> enemies; public final EnumSet<Team> enemies;
public final Team team; public final Team team;
@@ -51,4 +53,11 @@ public class Teams{
this.enemies = enemies; this.enemies = enemies;
} }
} }
/** Represents a block made by this team that was destroyed somewhere on the map.
* This does not include deconstructed blocks.*/
@Struct
public class BrokenBlockStruct{
public short x, y, rotation, block;
}
} }
@@ -246,44 +246,51 @@ public class TechTreeDialog extends FloatingDialog{
} }
}); });
infoTable.background("content-background");
infoTable.update(() -> infoTable.setPosition(button.getX() + button.getWidth(), button.getY() + button.getHeight(), Align.topLeft)); infoTable.update(() -> infoTable.setPosition(button.getX() + button.getWidth(), button.getY() + button.getHeight(), Align.topLeft));
infoTable.margin(0).left().defaults().left(); infoTable.left();
infoTable.addImageButton("icon-info", "node", 14 * 2, () -> ui.content.show(node.block)).growY().width(50f); infoTable.table("content-background", b -> {
b.margin(0).left().defaults().left();
infoTable.add().grow(); b.addImageButton("icon-info", "node", 14 * 2, () -> ui.content.show(node.block)).growY().width(50f);
b.add().grow();
b.table(desc -> {
desc.left().defaults().left();
desc.add(node.block.localizedName);
desc.row();
if(locked(node)){
desc.table(t -> {
t.left();
for(ItemStack req : node.requirements){
t.table(list -> {
list.left();
list.addImage(req.item.getContentIcon()).size(8 * 3).padRight(3);
list.add(req.item.localizedName()).color(Color.LIGHT_GRAY);
list.label(() -> " " + Math.min(data.getItem(req.item), req.amount) + " / " + req.amount)
.update(l -> l.setColor(data.has(req.item, req.amount) ? Color.LIGHT_GRAY : Color.SCARLET));
}).fillX().left();
t.row();
}
});
}else{
desc.add("$completed");
}
}).pad(9);
infoTable.table(desc -> { if(mobile && locked(node)){
desc.left().defaults().left(); b.row();
desc.add(node.block.localizedName); b.addImageTextButton("$research", "icon-check", "node", 16 * 2, () -> unlock(node))
desc.row(); .disabled(i -> !data.hasItems(node.requirements)).growX().height(44f).colspan(3);
if(locked(node)){
desc.table(t -> {
t.left();
for(ItemStack req : node.requirements){
t.table(list -> {
list.left();
list.addImage(req.item.getContentIcon()).size(8 * 3).padRight(3);
list.add(req.item.localizedName()).color(Color.LIGHT_GRAY);
list.label(() -> " " + Math.min(data.getItem(req.item), req.amount) + " / " + req.amount)
.update(l -> l.setColor(data.has(req.item, req.amount) ? Color.LIGHT_GRAY : Color.SCARLET));
}).fillX().left();
t.row();
}
});
}else{
desc.add("$completed");
} }
}).pad(9); });
if(mobile && locked(node)){ infoTable.row();
infoTable.row(); if(node.block.description != null){
infoTable.addImageTextButton("$research", "icon-check", "node", 16 * 2, () -> unlock(node)) infoTable.table("dialogDim", t -> t.margin(3f).left().labelWrap(node.block.description).color(Color.LIGHT_GRAY).growX()).fillX();
.disabled(b -> !data.hasItems(node.requirements)).growX().height(44f).colspan(3);
} }
addChild(infoTable); addChild(infoTable);
infoTable.pack(); infoTable.pack();
infoTable.act(Core.graphics.getDeltaTime()); infoTable.act(Core.graphics.getDeltaTime());
@@ -170,7 +170,7 @@ public class BuildBlock extends Block{
* The recipe of the block that is being constructed. * The recipe of the block that is being constructed.
* If there is no recipe for this block, as is the case with rocks, 'previous' is used. * If there is no recipe for this block, as is the case with rocks, 'previous' is used.
*/ */
public Block cblock; public @Nullable Block cblock;
public float progress = 0; public float progress = 0;
public float buildCost; public float buildCost;
+1 -1
View File
@@ -70,7 +70,7 @@ public class Generators{
ImagePacker.generate("block-icons", () -> { ImagePacker.generate("block-icons", () -> {
Image colors = new Image(content.blocks().size, 1); Image colors = new Image(content.blocks().size, 1);
Color outlineColor = Color.valueOf("4d4e58"); Color outlineColor = Color.valueOf("404049");
for(Block block : content.blocks()){ for(Block block : content.blocks()){
TextureRegion[] regions = block.getGeneratedIcons(); TextureRegion[] regions = block.getGeneratedIcons();