Many things
This commit is contained in:
@@ -246,8 +246,28 @@ public class TechTree implements ContentList{
|
||||
});
|
||||
});
|
||||
|
||||
node(spiritFactory, () -> {
|
||||
node(phantomFactory);
|
||||
node(draugFactory, () -> {
|
||||
node(spiritFactory, () -> {
|
||||
node(phantomFactory);
|
||||
});
|
||||
|
||||
node(daggerFactory, () -> {
|
||||
node(crawlerFactory, () -> {
|
||||
node(titanFactory, () -> {
|
||||
node(fortressFactory, () -> {
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
node(wraithFactory, () -> {
|
||||
node(spiritFactory, () -> {
|
||||
node(revenantFactory, () -> {
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
node(dartPad, () -> {
|
||||
|
||||
@@ -84,6 +84,7 @@ public class Zones implements ContentList{
|
||||
launchPeriod = 5;
|
||||
loadout = Loadouts.basicFoundation;
|
||||
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};
|
||||
}};
|
||||
|
||||
|
||||
@@ -6,17 +6,21 @@ import io.anuke.arc.ApplicationListener;
|
||||
import io.anuke.arc.Events;
|
||||
import io.anuke.arc.collection.ObjectSet.ObjectSetIterator;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.mindustry.content.Fx;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.*;
|
||||
import io.anuke.mindustry.entities.type.Player;
|
||||
import io.anuke.mindustry.entities.type.TileEntity;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
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.type.Item;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
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.*;
|
||||
|
||||
@@ -39,13 +43,25 @@ public class Logic implements ApplicationListener{
|
||||
p.respawns = state.rules.respawns;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
collisions.setCollider(tilesize, (x, y) -> {
|
||||
Tile tile = world.tile(x, y);
|
||||
return tile != null && tile.solid();
|
||||
Events.on(BlockDestroyEvent.class, event -> {
|
||||
//blocks that get broken are appended to the team's broken block queue
|
||||
Tile tile = event.tile;
|
||||
Block block = tile.block();
|
||||
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(playerGroup, playerGroup);
|
||||
}
|
||||
|
||||
world.pathfinder.update();
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.IntSet;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.math.geom.*;
|
||||
import io.anuke.mindustry.entities.traits.Entity;
|
||||
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{
|
||||
//range for tile collision scanning
|
||||
@@ -14,29 +17,15 @@ public class EntityCollisions{
|
||||
private static final float seg = 1f;
|
||||
|
||||
//tile collisions
|
||||
private float tilesize;
|
||||
private Rectangle tmp = new Rectangle();
|
||||
private TileCollider collider;
|
||||
private TileHitboxProvider hitboxProvider;
|
||||
private Vector2 vector = new Vector2();
|
||||
private Vector2 l1 = new Vector2();
|
||||
private Rectangle r1 = new Rectangle();
|
||||
private Rectangle r2 = new Rectangle();
|
||||
|
||||
//entity collisions
|
||||
private IntSet collided = new IntSet();
|
||||
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){
|
||||
|
||||
boolean movedx = false;
|
||||
@@ -67,8 +56,6 @@ public class EntityCollisions{
|
||||
}
|
||||
|
||||
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;
|
||||
entity.hitboxTile(rect);
|
||||
@@ -81,9 +68,8 @@ public class EntityCollisions{
|
||||
for(int dx = -r; dx <= r; dx++){
|
||||
for(int dy = -r; dy <= r; dy++){
|
||||
int wx = dx + tilex, wy = dy + tiley;
|
||||
if(collider.solid(wx, wy) && entity.collidesGrid(wx, wy)){
|
||||
|
||||
hitboxProvider.getHitbox(wx, wy, tmp);
|
||||
if(solid(wx, wy) && entity.collidesGrid(wx, wy)){
|
||||
tmp.setSize(tilesize).setCenter(wx * tilesize, wy * tilesize);
|
||||
|
||||
if(tmp.overlaps(rect)){
|
||||
Vector2 v = Geometry.overlap(rect, tmp, x);
|
||||
@@ -99,9 +85,6 @@ public class EntityCollisions{
|
||||
}
|
||||
|
||||
public boolean overlapsTile(Rectangle rect){
|
||||
if(collider == null)
|
||||
throw new IllegalArgumentException("No tile collider specified! Call setCollider() first.");
|
||||
|
||||
rect.getCenter(vector);
|
||||
int r = 1;
|
||||
|
||||
@@ -112,8 +95,8 @@ public class EntityCollisions{
|
||||
for(int dx = -r; dx <= r; dx++){
|
||||
for(int dy = -r; dy <= r; dy++){
|
||||
int wx = dx + tilex, wy = dy + tiley;
|
||||
if(collider.solid(wx, wy)){
|
||||
hitboxProvider.getHitbox(wx, wy, r2);
|
||||
if(solid(wx, wy)){
|
||||
r2.setSize(tilesize).setCenter(wx * tilesize, wy * tilesize);
|
||||
|
||||
if(r2.overlaps(rect)){
|
||||
return true;
|
||||
@@ -126,7 +109,6 @@ public class EntityCollisions{
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Entity> void updatePhysics(EntityGroup<T> group){
|
||||
collided.clear();
|
||||
|
||||
QuadTree tree = group.tree();
|
||||
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){
|
||||
|
||||
SolidTrait a = (SolidTrait)entity;
|
||||
@@ -221,10 +208,9 @@ public class EntityCollisions{
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void collideGroups(EntityGroup<?> groupa, EntityGroup<?> groupb){
|
||||
collided.clear();
|
||||
|
||||
for(Entity entity : groupa.all()){
|
||||
if(!(entity instanceof SolidTrait) || collided.contains(entity.getID()))
|
||||
if(!(entity instanceof SolidTrait))
|
||||
continue;
|
||||
|
||||
SolidTrait solid = (SolidTrait)entity;
|
||||
@@ -241,20 +227,10 @@ public class EntityCollisions{
|
||||
|
||||
for(SolidTrait sc : arrOut){
|
||||
sc.hitbox(r1);
|
||||
if(r2.overlaps(r1) && !collided.contains(sc.getID())){
|
||||
if(r2.overlaps(r1)){
|
||||
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 final Tile tile;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import io.anuke.annotations.Annotations.Struct;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
@@ -43,6 +44,7 @@ public class Teams{
|
||||
|
||||
public class TeamData{
|
||||
public final ObjectSet<Tile> cores = new ObjectSet<>();
|
||||
public final LongQueue brokenBlocks = new LongQueue();
|
||||
public final EnumSet<Team> enemies;
|
||||
public final Team team;
|
||||
|
||||
@@ -51,4 +53,11 @@ public class Teams{
|
||||
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.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 -> {
|
||||
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");
|
||||
if(mobile && locked(node)){
|
||||
b.row();
|
||||
b.addImageTextButton("$research", "icon-check", "node", 16 * 2, () -> unlock(node))
|
||||
.disabled(i -> !data.hasItems(node.requirements)).growX().height(44f).colspan(3);
|
||||
}
|
||||
}).pad(9);
|
||||
});
|
||||
|
||||
if(mobile && locked(node)){
|
||||
infoTable.row();
|
||||
infoTable.addImageTextButton("$research", "icon-check", "node", 16 * 2, () -> unlock(node))
|
||||
.disabled(b -> !data.hasItems(node.requirements)).growX().height(44f).colspan(3);
|
||||
infoTable.row();
|
||||
if(node.block.description != null){
|
||||
infoTable.table("dialogDim", t -> t.margin(3f).left().labelWrap(node.block.description).color(Color.LIGHT_GRAY).growX()).fillX();
|
||||
}
|
||||
|
||||
|
||||
addChild(infoTable);
|
||||
infoTable.pack();
|
||||
infoTable.act(Core.graphics.getDeltaTime());
|
||||
|
||||
@@ -170,7 +170,7 @@ public class BuildBlock extends Block{
|
||||
* 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.
|
||||
*/
|
||||
public Block cblock;
|
||||
public @Nullable Block cblock;
|
||||
|
||||
public float progress = 0;
|
||||
public float buildCost;
|
||||
|
||||
Reference in New Issue
Block a user