Merge branch 'master' of https://github.com/Anuken/Mindustry into 7.0-features

 Conflicts:
	core/src/mindustry/content/Blocks.java
	core/src/mindustry/net/CrashSender.java
	core/src/mindustry/ui/Links.java
	core/src/mindustry/ui/dialogs/SchematicsDialog.java
	core/src/mindustry/world/blocks/power/LightBlock.java
	gradle.properties
This commit is contained in:
Anuken
2021-07-23 17:58:02 -04:00
90 changed files with 690 additions and 389 deletions

View File

@@ -141,27 +141,23 @@ public class Effect{
}
public static void create(Effect effect, float x, float y, float rotation, Color color, Object data){
if(headless || effect == Fx.none) return;
if(Core.settings.getBool("effects")){
Rect view = Core.camera.bounds(Tmp.r1);
Rect pos = Tmp.r2.setSize(effect.clip).setCenter(x, y);
if(headless || effect == Fx.none || !Core.settings.getBool("effects")) return;
if(view.overlaps(pos)){
if(!effect.initialized){
effect.initialized = true;
effect.init();
}
EffectState entity = EffectState.create();
entity.effect = effect;
entity.rotation = rotation;
entity.data = data;
entity.lifetime = effect.lifetime;
entity.set(x, y);
entity.color.set(color);
if(effect.followParent && data instanceof Posc) entity.parent = ((Posc)data);
entity.add();
if(Core.camera.bounds(Tmp.r1).overlaps(Tmp.r2.setCentered(x, y, effect.clip))){
if(!effect.initialized){
effect.initialized = true;
effect.init();
}
EffectState entity = EffectState.create();
entity.effect = effect;
entity.rotation = rotation;
entity.data = data;
entity.lifetime = effect.lifetime;
entity.set(x, y);
entity.color.set(color);
if(effect.followParent && data instanceof Posc p) entity.parent = p;
entity.add();
}
}

View File

@@ -9,8 +9,8 @@ import mindustry.gen.*;
* Class for predicting shoot angles based on velocities of targets.
*/
public class Predict{
private static Vec2 vec = new Vec2();
private static Vec2 vresult = new Vec2();
private static final Vec2 vec = new Vec2();
private static final Vec2 vresult = new Vec2();
/**
* Calculates of intercept of a stationary and moving target. Do not call from multiple threads!
@@ -52,6 +52,10 @@ public class Predict{
}
public static Vec2 intercept(Position src, Position dst, float v){
return intercept(src, dst, 0, 0, v);
}
public static Vec2 intercept(Position src, Position dst, float offsetx, float offsety, float v){
float ddx = 0, ddy = 0;
if(dst instanceof Hitboxc h){
ddx += h.deltaX();
@@ -61,7 +65,7 @@ public class Predict{
ddx -= h.deltaX();
ddy -= h.deltaY();
}
return intercept(src.getX(), src.getY(), dst.getX(), dst.getY(), ddx, ddy, v);
return intercept(src.getX(), src.getY(), dst.getX() + offsetx, dst.getY() + offsety, ddx, ddy, v);
}
/**

View File

@@ -184,7 +184,7 @@ public class Units{
}
}
/** Returns the closest target enemy. First, units are checked, then tile entities. */
/** Returns the closest target enemy. First, units are checked, then buildings. */
public static Teamc bestTarget(Team team, float x, float y, float range, Boolf<Unit> unitPred, Boolf<Building> tilePred, Sortf sort){
if(team == Team.derelict) return null;

View File

@@ -371,7 +371,7 @@ public class BulletType extends Content implements Cloneable{
e -> e.checkTarget(collidesAir, collidesGround) && e.team != b.team,
t -> collidesGround && (t.team != b.team || t.damaged()));
}else{
target = Units.closestTarget(b.team, b.x, b.y, homingRange, e -> e.checkTarget(collidesAir, collidesGround), t -> collidesGround);
target = Units.closestTarget(b.team, b.x, b.y, homingRange, e -> e.checkTarget(collidesAir, collidesGround) && !b.hasCollided(e.id), t -> collidesGround && !b.hasCollided(t.id));
}
if(target != null){

View File

@@ -9,7 +9,7 @@ import static mindustry.Vars.*;
@Component
abstract class BoundedComp implements Velc, Posc, Healthc, Flyingc{
static final float warpDst = 40f;
static final float warpDst = 30f;
@Import float x, y;

View File

@@ -178,7 +178,7 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{
//requests that you have at least *started* are considered
if(state.rules.infiniteResources || team.rules().infiniteResources || request.breaking || core == null || request.isRotation(team)) return false;
return (request.stuck && !core.items.has(request.block.requirements)) || (Structs.contains(request.block.requirements, i -> !core.items.has(i.item) && Mathf.round(i.amount * state.rules.buildCostMultiplier) > 0) && !request.initialized);
return (request.stuck && !core.items.has(request.block.requirements)) || (Structs.contains(request.block.requirements, i -> !core.items.has(i.item, Math.min(i.amount, 15)) && Mathf.round(i.amount * state.rules.buildCostMultiplier) > 0) && !request.initialized);
}
void removeBuild(int x, int y, boolean breaking){

View File

@@ -1018,6 +1018,11 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
}
/** @return the cap for item amount calculations, used when this block explodes. */
public int explosionItemCap(){
return block.itemCapacity;
}
/** Called when the block is destroyed. The tile is still intact at this stage. */
public void onDestroyed(){
float explosiveness = block.baseExplosiveness;
@@ -1026,7 +1031,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
if(block.hasItems){
for(Item item : content.items()){
int amount = items.get(item);
int amount = Math.min(items.get(item), explosionItemCap());
explosiveness += item.explosiveness * amount;
flammability += item.flammability * amount;
power += item.charge * amount * 100f;

View File

@@ -80,6 +80,10 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
remove();
}
public boolean hasCollided(int id){
return collided.size != 0 && !collided.contains(id);
}
@Replace
public float clipSize(){
return type.drawSize;
@@ -90,7 +94,7 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
public boolean collides(Hitboxc other){
return type.collides && (other instanceof Teamc t && t.team() != team)
&& !(other instanceof Flyingc f && !f.checkTarget(type.collidesAir, type.collidesGround))
&& !(type.pierce && collided.contains(other.id())); //prevent multiple collisions
&& !(type.pierce && hasCollided(other.id())); //prevent multiple collisions
}
@MethodPriority(100)
@@ -116,16 +120,16 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
if(type.collidesTiles && type.collides && type.collidesGround){
world.raycastEach(World.toTile(lastX()), World.toTile(lastY()), tileX(), tileY(), (x, y) -> {
Building tile = world.build(x, y);
if(tile == null || !isAdded()) return false;
Building build = world.build(x, y);
if(build == null || !isAdded()) return false;
if(tile.collide(self()) && type.testCollision(self(), tile) && !tile.dead() && (type.collidesTeam || tile.team != team) && !(type.pierceBuilding && collided.contains(tile.id))){
if(build.collide(self()) && type.testCollision(self(), build) && !build.dead() && (type.collidesTeam || build.team != team) && !(type.pierceBuilding && hasCollided(build.id))){
boolean remove = false;
float health = tile.health;
float health = build.health;
if(tile.team != team){
remove = tile.collision(self());
if(build.team != team){
remove = build.collision(self());
}
if(remove || type.collidesTeam){
@@ -133,11 +137,11 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
hit = true;
remove();
}else{
collided.add(tile.id);
collided.add(build.id);
}
}
type.hitTile(self(), tile, health, true);
type.hitTile(self(), build, health, true);
return !type.pierceBuilding;
}

View File

@@ -9,6 +9,7 @@ import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.payloads.*;
import mindustry.world.meta.*;
import static mindustry.Vars.*;
@@ -178,6 +179,14 @@ public class AIController implements UnitController{
return Geometry.findClosest(unit.x, unit.y, Vars.spawner.getSpawns());
}
protected void unloadPayloads(){
if(unit instanceof Payloadc pay && pay.hasPayload() && target instanceof Building && pay.payloads().peek() instanceof UnitPayload){
if(target.within(unit, Math.max(unit.type().range + 1f, 75f))){
pay.dropLastPayload();
}
}
}
protected void circle(Position target, float circleLength){
circle(target, circleLength, unit.speed());
}