Merge branch 'master' into ThePythonGuy3-patch-1
This commit is contained in:
@@ -876,7 +876,7 @@ public class Blocks implements ContentList{
|
||||
size = 4;
|
||||
}};
|
||||
|
||||
thruster = new Wall("thruster"){{
|
||||
thruster = new Thruster("thruster"){{
|
||||
health = 55 * 16 * wallHealthMultiplier;
|
||||
size = 4;
|
||||
}};
|
||||
@@ -989,9 +989,9 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
itemBridge = new BufferedItemBridge("bridge-conveyor"){{
|
||||
requirements(Category.distribution, with(Items.lead, 4, Items.copper, 4));
|
||||
requirements(Category.distribution, with(Items.lead, 6, Items.copper, 6));
|
||||
range = 4;
|
||||
speed = 70f;
|
||||
speed = 74f;
|
||||
bufferCapacity = 14;
|
||||
}};
|
||||
|
||||
@@ -1265,7 +1265,7 @@ public class Blocks implements ContentList{
|
||||
tier = 2;
|
||||
drillTime = 600;
|
||||
size = 2;
|
||||
drawMineItem = true;
|
||||
|
||||
consumes.liquid(Liquids.water, 0.05f).boost();
|
||||
}};
|
||||
|
||||
@@ -1274,7 +1274,7 @@ public class Blocks implements ContentList{
|
||||
tier = 3;
|
||||
drillTime = 400;
|
||||
size = 2;
|
||||
drawMineItem = true;
|
||||
|
||||
consumes.liquid(Liquids.water, 0.06f).boost();
|
||||
}};
|
||||
|
||||
@@ -1763,7 +1763,7 @@ public class Blocks implements ContentList{
|
||||
despawnEffect = Fx.instBomb;
|
||||
trailSpacing = 20f;
|
||||
damage = 1350;
|
||||
tileDamageMultiplier = 0.3f;
|
||||
buildingDamageMultiplier = 0.3f;
|
||||
speed = brange;
|
||||
hitShake = 6f;
|
||||
ammoMultiplier = 1f;
|
||||
@@ -1992,6 +1992,7 @@ public class Blocks implements ContentList{
|
||||
|
||||
powerSource = new PowerSource("power-source"){{
|
||||
requirements(Category.power, BuildVisibility.sandboxOnly, with());
|
||||
powerProduction = 10000f / 60f;
|
||||
alwaysUnlocked = true;
|
||||
}};
|
||||
|
||||
|
||||
@@ -465,6 +465,7 @@ public class Bullets implements ContentList{
|
||||
speed = 4f;
|
||||
knockback = 1.7f;
|
||||
puddleSize = 8f;
|
||||
orbSize = 4f;
|
||||
drag = 0.001f;
|
||||
ammoMultiplier = 0.4f;
|
||||
statusDuration = 60f * 4f;
|
||||
@@ -476,6 +477,7 @@ public class Bullets implements ContentList{
|
||||
speed = 4f;
|
||||
knockback = 1.3f;
|
||||
puddleSize = 8f;
|
||||
orbSize = 4f;
|
||||
drag = 0.001f;
|
||||
ammoMultiplier = 0.4f;
|
||||
statusDuration = 60f * 4f;
|
||||
@@ -487,6 +489,7 @@ public class Bullets implements ContentList{
|
||||
speed = 4f;
|
||||
knockback = 1.3f;
|
||||
puddleSize = 8f;
|
||||
orbSize = 4f;
|
||||
damage = 4.75f;
|
||||
drag = 0.001f;
|
||||
ammoMultiplier = 0.4f;
|
||||
@@ -498,6 +501,7 @@ public class Bullets implements ContentList{
|
||||
speed = 4f;
|
||||
knockback = 1.3f;
|
||||
puddleSize = 8f;
|
||||
orbSize = 4f;
|
||||
drag = 0.001f;
|
||||
ammoMultiplier = 0.4f;
|
||||
statusDuration = 60f * 4f;
|
||||
|
||||
@@ -182,7 +182,7 @@ public class UnitTypes implements ContentList{
|
||||
lightningLength = 6;
|
||||
lightningColor = Pal.surge;
|
||||
//standard bullet damage is far too much for lightning
|
||||
lightningDamage = 30;
|
||||
lightningDamage = 20;
|
||||
}};
|
||||
}},
|
||||
|
||||
@@ -336,7 +336,7 @@ public class UnitTypes implements ContentList{
|
||||
|
||||
bullet = new LightningBulletType(){{
|
||||
lightningColor = hitColor = Pal.heal;
|
||||
damage = 15f;
|
||||
damage = 12f;
|
||||
lightningLength = 7;
|
||||
lightningLengthRand = 7;
|
||||
shootEffect = Fx.shootHeal;
|
||||
@@ -1759,7 +1759,7 @@ public class UnitTypes implements ContentList{
|
||||
lifetime = 60f;
|
||||
shootEffect = Fx.shootSmall;
|
||||
smokeEffect = Fx.shootSmallSmoke;
|
||||
tileDamageMultiplier = 0.01f;
|
||||
buildingDamageMultiplier = 0.01f;
|
||||
}};
|
||||
}});
|
||||
}};
|
||||
@@ -1801,7 +1801,7 @@ public class UnitTypes implements ContentList{
|
||||
lifetime = 60f;
|
||||
shootEffect = Fx.shootSmall;
|
||||
smokeEffect = Fx.shootSmallSmoke;
|
||||
tileDamageMultiplier = 0.01f;
|
||||
buildingDamageMultiplier = 0.01f;
|
||||
}};
|
||||
}});
|
||||
}};
|
||||
@@ -1841,7 +1841,7 @@ public class UnitTypes implements ContentList{
|
||||
lifetime = 70f;
|
||||
shootEffect = Fx.shootSmall;
|
||||
smokeEffect = Fx.shootSmallSmoke;
|
||||
tileDamageMultiplier = 0.01f;
|
||||
buildingDamageMultiplier = 0.01f;
|
||||
homingPower = 0.04f;
|
||||
}};
|
||||
}});
|
||||
|
||||
@@ -351,7 +351,7 @@ public class Control implements ApplicationListener, Loadable{
|
||||
if(tile != null){
|
||||
tile.setBlock(content.block(plan.block), state.rules.waveTeam, plan.rotation);
|
||||
if(plan.config != null && tile.build != null){
|
||||
tile.build.configure(plan.config);
|
||||
tile.build.configureAny(plan.config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,13 +258,12 @@ public class Logic implements ApplicationListener{
|
||||
state.rules.weather.removeAll(w -> w.weather == null);
|
||||
|
||||
for(WeatherEntry entry : state.rules.weather){
|
||||
if(entry.weather == null) continue;
|
||||
//update cooldown
|
||||
entry.cooldown -= Time.delta;
|
||||
|
||||
//create new event when not active
|
||||
if(entry.cooldown < 0 && !entry.weather.isActive()){
|
||||
float duration = Mathf.random(entry.minDuration, entry.maxDuration);
|
||||
if((entry.cooldown < 0 || entry.always) && !entry.weather.isActive()){
|
||||
float duration = entry.always ? Float.POSITIVE_INFINITY : Mathf.random(entry.minDuration, entry.maxDuration);
|
||||
entry.cooldown = duration + Mathf.random(entry.minFrequency, entry.maxFrequency);
|
||||
Tmp.v1.setToRandomDirection();
|
||||
Call.createWeather(entry.weather, entry.intensity, duration, Tmp.v1.x, Tmp.v1.y);
|
||||
|
||||
@@ -700,6 +700,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
||||
if(core != 0) return core;
|
||||
int synth = Boolean.compare(b1.synthetic(), b2.synthetic());
|
||||
if(synth != 0) return synth;
|
||||
int editorVis = Boolean.compare(b1.buildVisibility == BuildVisibility.editorOnly, b2.buildVisibility == BuildVisibility.editorOnly);
|
||||
if(editorVis != 0) return editorVis;
|
||||
int ore = Boolean.compare(b1 instanceof OverlayFloor, b2 instanceof OverlayFloor);
|
||||
if(ore != 0) return ore;
|
||||
return Integer.compare(b1.id, b2.id);
|
||||
|
||||
@@ -126,6 +126,8 @@ public class Damage{
|
||||
boolean collide = tile != null && collidedBlocks.add(tile.pos());
|
||||
|
||||
if(hitter.damage > 0){
|
||||
float health = !collide ? 0 : tile.health;
|
||||
|
||||
if(collide && tile.team != team && tile.collide(hitter)){
|
||||
tile.collision(hitter);
|
||||
hitter.type.hit(hitter, tile.x, tile.y);
|
||||
@@ -133,7 +135,7 @@ public class Damage{
|
||||
|
||||
//try to heal the tile
|
||||
if(collide && hitter.type.testCollision(hitter, tile)){
|
||||
hitter.type.hitTile(hitter, tile, tile.health, false);
|
||||
hitter.type.hitTile(hitter, tile, health, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -389,9 +391,9 @@ public class Damage{
|
||||
if(scaledDamage <= 0 || tile == null) continue;
|
||||
|
||||
//apply damage to entity if needed
|
||||
if(tile.build != null && tile.team() != team){
|
||||
int health = (int)tile.build.health();
|
||||
if(tile.build.health() > 0){
|
||||
if(tile.build != null && tile.build.team != team){
|
||||
int health = (int)(tile.build.health / (tile.block().size * tile.block().size));
|
||||
if(tile.build.health > 0){
|
||||
tile.build.damage(scaledDamage);
|
||||
scaledDamage -= health;
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ public abstract class BulletType extends Content{
|
||||
/** Multiplied by turret reload speed to get final shoot speed. */
|
||||
public float reloadMultiplier = 1f;
|
||||
/** Multiplier of how much base damage is done to tiles. */
|
||||
public float tileDamageMultiplier = 1f;
|
||||
public float buildingDamageMultiplier = 1f;
|
||||
/** Recoil from shooter entities. */
|
||||
public float recoil;
|
||||
/** Whether to kill the shooter when this is shot. For suicide bombers. */
|
||||
|
||||
@@ -15,6 +15,7 @@ import static mindustry.Vars.*;
|
||||
public class LiquidBulletType extends BulletType{
|
||||
public Liquid liquid;
|
||||
public float puddleSize = 6f;
|
||||
public float orbSize = 3f;
|
||||
|
||||
public LiquidBulletType(@Nullable Liquid liquid){
|
||||
super(3.5f, 0);
|
||||
@@ -64,7 +65,7 @@ public class LiquidBulletType extends BulletType{
|
||||
public void draw(Bullet b){
|
||||
Draw.color(liquid.color, Color.white, b.fout() / 100f);
|
||||
|
||||
Fill.circle(b.x, b.y, puddleSize / 2);
|
||||
Fill.circle(b.x, b.y, orbSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,12 +6,6 @@ import mindustry.content.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.gen.*;
|
||||
|
||||
//TODO this class is bad for multiple reasons, remove/replace it.
|
||||
//- effects unreliable
|
||||
//- not really hitscan but works like it
|
||||
//- buggy trails
|
||||
//- looks bad
|
||||
//- generally unreliable
|
||||
public class RailBulletType extends BulletType{
|
||||
public Effect pierceEffect = Fx.hitBulletSmall, updateEffect = Fx.none;
|
||||
/** Multiplier of damage decreased per health pierced. */
|
||||
@@ -29,6 +23,7 @@ public class RailBulletType extends BulletType{
|
||||
despawnEffect = Fx.none;
|
||||
collides = false;
|
||||
lifetime = 1f;
|
||||
speed = 0.01f;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -37,7 +32,7 @@ public class RailBulletType extends BulletType{
|
||||
}
|
||||
|
||||
void handle(Bullet b, Posc pos, float initialHealth){
|
||||
float sub = initialHealth*pierceDamageFactor;
|
||||
float sub = Math.max(initialHealth*pierceDamageFactor, 0);
|
||||
|
||||
if(b.damage <= 0){
|
||||
b.fdata = Math.min(b.fdata, b.dst(pos));
|
||||
|
||||
@@ -33,7 +33,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{
|
||||
@Import Team team;
|
||||
|
||||
@SyncLocal Queue<BuildPlan> plans = new Queue<>(1);
|
||||
@SyncLocal transient boolean updateBuilding = true;
|
||||
@SyncLocal boolean updateBuilding = true;
|
||||
|
||||
public boolean canBuild(){
|
||||
return type.buildSpeed > 0;
|
||||
@@ -77,7 +77,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{
|
||||
|
||||
Tile tile = world.tile(current.x, current.y);
|
||||
|
||||
if(!(tile.block() instanceof ConstructBlock)){
|
||||
if(!(tile.build instanceof ConstructBuild cb)){
|
||||
if(!current.initialized && !current.breaking && Build.validPlace(current.block, team, current.x, current.y, current.rotation)){
|
||||
boolean hasAll = infinite || current.isRotation(team) || !Structs.contains(current.block.requirements, i -> core != null && !core.items.has(i.item));
|
||||
|
||||
@@ -92,7 +92,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{
|
||||
plans.removeFirst();
|
||||
return;
|
||||
}
|
||||
}else if(tile.team() != team && tile.team() != Team.derelict){
|
||||
}else if((tile.team() != team && tile.team() != Team.derelict) || (!current.breaking && cb.cblock != current.block)){
|
||||
plans.removeFirst();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1165,7 +1165,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
/** Handle a bullet collision.
|
||||
* @return whether the bullet should be removed. */
|
||||
public boolean collision(Bullet other){
|
||||
damage(other.damage() * other.type().tileDamageMultiplier);
|
||||
damage(other.damage() * other.type().buildingDamageMultiplier);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -51,8 +51,8 @@ abstract class FlyingComp implements Posc, Velc, Healthc, Hitboxc{
|
||||
}
|
||||
|
||||
void moveAt(Vec2 vector, float acceleration){
|
||||
Vec2 t = tmp1.set(vector).scl(floorSpeedMultiplier()); //target vector
|
||||
tmp2.set(t).sub(vel).limit(acceleration * vector.len() * Time.delta); //delta vector
|
||||
Vec2 t = tmp1.set(vector); //target vector
|
||||
tmp2.set(t).sub(vel).limit(acceleration * vector.len() * Time.delta * floorSpeedMultiplier()); //delta vector
|
||||
vel.add(tmp2);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,11 +51,7 @@ abstract class HealthComp implements Entityc, Posc{
|
||||
|
||||
/** Damage and pierce armor. */
|
||||
void damagePierce(float amount, boolean withEffect){
|
||||
if(this instanceof Shieldc){
|
||||
damage(amount + ((Shieldc)this).armor(), withEffect);
|
||||
}else{
|
||||
damage(amount, withEffect);
|
||||
}
|
||||
damage(amount, withEffect);
|
||||
}
|
||||
|
||||
/** Damage and pierce armor. */
|
||||
|
||||
@@ -14,7 +14,7 @@ abstract class ShieldComp implements Healthc, Posc{
|
||||
|
||||
/** Absorbs health damage. */
|
||||
float shield;
|
||||
/** Absorbs percentage of damage. */
|
||||
/** Substracts an amount from damage. */
|
||||
float armor;
|
||||
/** Shield opacity. */
|
||||
transient float shieldAlpha = 0f;
|
||||
@@ -26,8 +26,22 @@ abstract class ShieldComp implements Healthc, Posc{
|
||||
amount = Math.max(amount - armor, minArmorDamage * amount);
|
||||
amount /= healthMultiplier;
|
||||
|
||||
hitTime = 1f;
|
||||
rawDamage(amount);
|
||||
}
|
||||
|
||||
@Replace
|
||||
@Override
|
||||
public void damagePierce(float amount, boolean withEffect){
|
||||
float pre = hitTime;
|
||||
|
||||
rawDamage(amount);
|
||||
|
||||
if(!withEffect){
|
||||
hitTime = pre;
|
||||
}
|
||||
}
|
||||
|
||||
private void rawDamage(float amount){
|
||||
boolean hadShields = shield > 0.0001f;
|
||||
|
||||
if(hadShields){
|
||||
|
||||
@@ -139,7 +139,7 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
||||
|
||||
//flip weapon shoot side for alternating weapons at half reload
|
||||
if(weapon.otherSide != -1 && weapon.alternate && mount.side == weapon.flipSprite &&
|
||||
mount.reload + Time.delta > weapon.reload/2f && mount.reload <= weapon.reload/2f){
|
||||
mount.reload + Time.delta * reloadMultiplier > weapon.reload/2f && mount.reload <= weapon.reload/2f){
|
||||
mounts[weapon.otherSide].side = !mounts[weapon.otherSide].side;
|
||||
mount.side = !mount.side;
|
||||
}
|
||||
|
||||
@@ -154,6 +154,7 @@ public class DesktopInput extends InputHandler{
|
||||
}
|
||||
drawRequest(lineRequests.get(i));
|
||||
}
|
||||
lineRequests.each(this::drawOverRequest);
|
||||
}else if(isPlacing()){
|
||||
if(block.rotate){
|
||||
drawArrow(block, cursorX, cursorY, rotation);
|
||||
@@ -603,7 +604,6 @@ public class DesktopInput extends InputHandler{
|
||||
|
||||
protected void updateMovement(Unit unit){
|
||||
boolean omni = unit.type.omniMovement;
|
||||
boolean ground = unit.isGrounded();
|
||||
|
||||
float speed = unit.realSpeed();
|
||||
float xa = Core.input.axis(Binding.move_x);
|
||||
|
||||
@@ -48,7 +48,6 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
/** Maximum line length. */
|
||||
final static int maxLength = 100;
|
||||
final static Rect r1 = new Rect(), r2 = new Rect();
|
||||
final static Seq<Point2> tmpPoints = new Seq<>(), tmpPoints2 = new Seq<>();
|
||||
|
||||
public final OverlayFragment frag = new OverlayFragment();
|
||||
|
||||
@@ -1144,7 +1143,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
diagonal = !diagonal;
|
||||
}
|
||||
|
||||
if(block instanceof PowerNode){
|
||||
if(block != null && block.swapDiagonalPlacement){
|
||||
diagonal = !diagonal;
|
||||
}
|
||||
|
||||
@@ -1161,39 +1160,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
points = Placement.normalizeLine(startX, startY, endX, endY);
|
||||
}
|
||||
|
||||
if(block instanceof PowerNode node){
|
||||
var base = tmpPoints2;
|
||||
var result = tmpPoints.clear();
|
||||
|
||||
base.selectFrom(points, p -> p == points.first() || p == points.peek() || Build.validPlace(block, player.team(), p.x, p.y, rotation, false));
|
||||
boolean addedLast = false;
|
||||
|
||||
outer:
|
||||
for(int i = 0; i < base.size;){
|
||||
var point = base.get(i);
|
||||
result.add(point);
|
||||
if(i == base.size - 1) addedLast = true;
|
||||
|
||||
//find the furthest node that overlaps this one
|
||||
for(int j = base.size - 1; j > i; j--){
|
||||
var other = base.get(j);
|
||||
boolean over = node.overlaps(world.tile(point.x, point.y), world.tile(other.x, other.y));
|
||||
|
||||
if(over){
|
||||
//add node to list and start searching for node that overlaps the next one
|
||||
i = j;
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
//if it got here, that means nothing was found. try to proceed to the next node anyway
|
||||
i ++;
|
||||
}
|
||||
|
||||
if(!addedLast) result.add(base.peek());
|
||||
|
||||
points.clear();
|
||||
points.addAll(result);
|
||||
if(block != null){
|
||||
block.changePlacementPath(points, rotation);
|
||||
}
|
||||
|
||||
float angle = Angles.angle(startX, startY, endX, endY);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mindustry.input;
|
||||
|
||||
import arc.*;
|
||||
import arc.func.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
@@ -11,6 +12,7 @@ import mindustry.world.blocks.distribution.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class Placement{
|
||||
private final static Seq<Point2> tmpPoints = new Seq<>(), tmpPoints2 = new Seq<>();
|
||||
private static final NormalizeResult result = new NormalizeResult();
|
||||
private static final NormalizeDrawResult drawResult = new NormalizeDrawResult();
|
||||
private static Bresenham2 bres = new Bresenham2();
|
||||
@@ -68,6 +70,42 @@ public class Placement{
|
||||
return points;
|
||||
}
|
||||
|
||||
/** Calculates optimal node placement for nodes with spacing. Used for bridges and power nodes. */
|
||||
public static void calculateNodes(Seq<Point2> points, Block block, int rotation, Boolf2<Point2, Point2> overlapper){
|
||||
var base = tmpPoints2;
|
||||
var result = tmpPoints.clear();
|
||||
|
||||
base.selectFrom(points, p -> p == points.first() || p == points.peek() || Build.validPlace(block, player.team(), p.x, p.y, rotation, false));
|
||||
boolean addedLast = false;
|
||||
|
||||
outer:
|
||||
for(int i = 0; i < base.size;){
|
||||
var point = base.get(i);
|
||||
result.add(point);
|
||||
if(i == base.size - 1) addedLast = true;
|
||||
|
||||
//find the furthest node that overlaps this one
|
||||
for(int j = base.size - 1; j > i; j--){
|
||||
var other = base.get(j);
|
||||
boolean over = overlapper.get(point, other);
|
||||
|
||||
if(over){
|
||||
//add node to list and start searching for node that overlaps the next one
|
||||
i = j;
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
//if it got here, that means nothing was found. try to proceed to the next node anyway
|
||||
i ++;
|
||||
}
|
||||
|
||||
if(!addedLast) result.add(base.peek());
|
||||
|
||||
points.clear();
|
||||
points.addAll(result);
|
||||
}
|
||||
|
||||
private static float tileHeuristic(Tile tile, Tile other){
|
||||
Block block = control.input.block;
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public class StatusEffect extends MappableContent{
|
||||
if(damage > 0){
|
||||
unit.damageContinuousPierce(damage);
|
||||
}else if(damage < 0){ //heal unit
|
||||
unit.heal(damage * Time.delta);
|
||||
unit.heal(-1f * damage * Time.delta);
|
||||
}
|
||||
|
||||
if(effect != Fx.none && Mathf.chanceDelta(effectChance)){
|
||||
|
||||
@@ -61,12 +61,17 @@ public class Weather extends UnlockableContent{
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public WeatherState instance(){
|
||||
return Groups.weather.find(w -> w.weather() == this);
|
||||
}
|
||||
|
||||
public boolean isActive(){
|
||||
return Groups.weather.find(w -> w.weather() == this) != null;
|
||||
return instance() != null;
|
||||
}
|
||||
|
||||
public void remove(){
|
||||
Entityc e = Groups.weather.find(w -> w.weather() == this);
|
||||
var e = instance();
|
||||
if(e != null) e.remove();
|
||||
}
|
||||
|
||||
@@ -259,6 +264,8 @@ public class Weather extends UnlockableContent{
|
||||
public float cooldown;
|
||||
/** Intensity of the weather produced. */
|
||||
public float intensity = 1f;
|
||||
/** If true, this weather is always active. */
|
||||
public boolean always = false;
|
||||
|
||||
/** Creates a weather entry with some approximate weather values. */
|
||||
public WeatherEntry(Weather weather){
|
||||
|
||||
@@ -284,19 +284,23 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
f.defaults().padRight(4).left();
|
||||
|
||||
f.add("@rules.weather.duration");
|
||||
field(f, entry.minDuration / toMinutes, v -> entry.minDuration = v * toMinutes);
|
||||
field(f, entry.minDuration / toMinutes, v -> entry.minDuration = v * toMinutes).disabled(v -> entry.always);
|
||||
f.add("@waves.to");
|
||||
field(f, entry.maxDuration / toMinutes, v -> entry.maxDuration = v * toMinutes);
|
||||
field(f, entry.maxDuration / toMinutes, v -> entry.maxDuration = v * toMinutes).disabled(v -> entry.always);
|
||||
f.add("@unit.minutes");
|
||||
|
||||
f.row();
|
||||
|
||||
f.add("@rules.weather.frequency");
|
||||
field(f, entry.minFrequency / toMinutes, v -> entry.minFrequency = v * toMinutes);
|
||||
field(f, entry.minFrequency / toMinutes, v -> entry.minFrequency = v * toMinutes).disabled(v -> entry.always);
|
||||
f.add("@waves.to");
|
||||
field(f, entry.maxFrequency / toMinutes, v -> entry.maxFrequency = v * toMinutes);
|
||||
field(f, entry.maxFrequency / toMinutes, v -> entry.maxFrequency = v * toMinutes).disabled(v -> entry.always);
|
||||
f.add("@unit.minutes");
|
||||
|
||||
f.row();
|
||||
|
||||
f.check("@rules.weather.always", val -> entry.always = val).checked(cc -> entry.always).padBottom(4);
|
||||
|
||||
//intensity can't currently be customized
|
||||
|
||||
}).grow().left().pad(6).top();
|
||||
@@ -314,8 +318,8 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
dialog.addCloseButton();
|
||||
|
||||
dialog.buttons.button("@add", Icon.add, () -> {
|
||||
BaseDialog addd = new BaseDialog("@add");
|
||||
addd.cont.pane(t -> {
|
||||
BaseDialog add = new BaseDialog("@add");
|
||||
add.cont.pane(t -> {
|
||||
t.background(Tex.button);
|
||||
int i = 0;
|
||||
for(Weather weather : content.<Weather>getBy(ContentType.weather)){
|
||||
@@ -324,13 +328,13 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
rules.weather.add(new WeatherEntry(weather));
|
||||
rebuild[0].run();
|
||||
|
||||
addd.hide();
|
||||
add.hide();
|
||||
}).size(140f, 50f);
|
||||
if(++i % 2 == 0) t.row();
|
||||
}
|
||||
});
|
||||
addd.addCloseButton();
|
||||
addd.show();
|
||||
add.addCloseButton();
|
||||
add.show();
|
||||
}).width(170f);
|
||||
|
||||
//reset cooldown to random number
|
||||
|
||||
@@ -67,10 +67,15 @@ public class HostDialog extends BaseDialog{
|
||||
player.admin(true);
|
||||
|
||||
if(steam){
|
||||
Core.app.post(() -> Core.settings.getBoolOnce("steampublic2", () -> {
|
||||
Core.app.post(() -> Core.settings.getBoolOnce("steampublic3", () -> {
|
||||
ui.showCustomConfirm("@setting.publichost.name", "@public.confirm", "@yes", "@no", () -> {
|
||||
Core.settings.put("publichost", true);
|
||||
platform.updateLobby();
|
||||
ui.showCustomConfirm("@setting.publichost.name", "@public.confirm.really", "@no", "@yes", () -> {
|
||||
Core.settings.put("publichost", true);
|
||||
platform.updateLobby();
|
||||
}, () -> {
|
||||
Core.settings.put("publichost", false);
|
||||
platform.updateLobby();
|
||||
});
|
||||
}, () -> {
|
||||
Core.settings.put("publichost", false);
|
||||
platform.updateLobby();
|
||||
|
||||
@@ -399,6 +399,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
||||
void setup(){
|
||||
zoom = planets.zoom = 1f;
|
||||
selectAlpha = 1f;
|
||||
ui.minimapfrag.hide();
|
||||
|
||||
clearChildren();
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@ import static mindustry.Vars.net;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class SettingsMenuDialog extends SettingsDialog{
|
||||
private SettingsTable graphics;
|
||||
private SettingsTable game;
|
||||
private SettingsTable sound;
|
||||
public SettingsTable graphics;
|
||||
public SettingsTable game;
|
||||
public SettingsTable sound;
|
||||
|
||||
private Table prefs;
|
||||
private Table menu;
|
||||
|
||||
@@ -110,6 +110,10 @@ public class MinimapFragment extends Fragment{
|
||||
return shown;
|
||||
}
|
||||
|
||||
public void hide(){
|
||||
shown = false;
|
||||
}
|
||||
|
||||
public void toggle(){
|
||||
float size = baseSize * zoom * world.width();
|
||||
float ratio = (float)renderer.minimap.getTexture().height / renderer.minimap.getTexture().width;
|
||||
|
||||
@@ -143,6 +143,8 @@ public class Block extends UnlockableContent{
|
||||
public boolean sync;
|
||||
/** Whether this block uses conveyor-type placement mode. */
|
||||
public boolean conveyorPlacement;
|
||||
/** Whether to swap the diagonal placement modes. */
|
||||
public boolean swapDiagonalPlacement;
|
||||
/**
|
||||
* The color of this block when displayed on the minimap or map preview.
|
||||
* Do not set manually! This is overridden when loading for most blocks.
|
||||
@@ -386,6 +388,11 @@ public class Block extends UnlockableContent{
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Mutates the given list of points used during line placement. */
|
||||
public void changePlacementPath(Seq<Point2> points, int rotation){
|
||||
|
||||
}
|
||||
|
||||
public Object nextConfig(){
|
||||
if(saveConfig && lastConfig != null){
|
||||
return lastConfig;
|
||||
|
||||
@@ -50,37 +50,48 @@ public class Accelerator extends Block{
|
||||
}
|
||||
|
||||
public class AcceleratorBuild extends Building{
|
||||
public float heat, statusLerp;
|
||||
|
||||
@Override
|
||||
public void updateTile(){
|
||||
super.updateTile();
|
||||
heat = Mathf.lerpDelta(heat, consValid() ? 1f : 0f, 0.05f);
|
||||
statusLerp = Mathf.lerpDelta(statusLerp, power.status, 0.05f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
super.draw();
|
||||
|
||||
for(int l = 0; l < 4; l++){
|
||||
float length = 7f + l * 5f;
|
||||
Draw.color(team.color, Pal.darkMetal, Mathf.absin(Time.time + l*50f, 10f, 1f));
|
||||
Draw.color(Tmp.c1.set(Pal.darkMetal).lerp(team.color, statusLerp), Pal.darkMetal, Mathf.absin(Time.time + l*50f, 10f, 1f));
|
||||
|
||||
for(int i = 0; i < 4; i++){
|
||||
float rot = i*90f + 45f;
|
||||
Draw.rect(arrowRegion, x + Angles.trnsx(rot, length), y + Angles.trnsy(rot, length), rot + 180f);
|
||||
}
|
||||
}
|
||||
|
||||
if(heat < 0.0001f) return;
|
||||
|
||||
float rad = size * tilesize / 2f * 0.74f;
|
||||
float scl = 2f;
|
||||
|
||||
Draw.z(Layer.bullet - 0.0001f);
|
||||
Lines.stroke(1.75f, Pal.accent);
|
||||
Lines.stroke(1.75f * heat, Pal.accent);
|
||||
Lines.square(x, y, rad * 1.22f, 45f);
|
||||
|
||||
Lines.stroke(3f, Pal.accent);
|
||||
Lines.stroke(3f * heat, Pal.accent);
|
||||
Lines.square(x, y, rad, Time.time / scl);
|
||||
Lines.square(x, y, rad, -Time.time / scl);
|
||||
|
||||
Draw.color(team.color);
|
||||
Draw.alpha(Mathf.clamp(heat * 3f));
|
||||
|
||||
for(int i = 0; i < 4; i++){
|
||||
float rot = i*90f + 45f + (-Time.time /3f)%360f;
|
||||
float length = 26f;
|
||||
float length = 26f * heat;
|
||||
Draw.rect(arrowRegion, x + Angles.trnsx(rot, length), y + Angles.trnsy(rot, length), rot + 180f);
|
||||
}
|
||||
|
||||
|
||||
37
core/src/mindustry/world/blocks/defense/Thruster.java
Normal file
37
core/src/mindustry/world/blocks/defense/Thruster.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package mindustry.world.blocks.defense;
|
||||
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.util.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.entities.units.*;
|
||||
|
||||
public class Thruster extends Wall{
|
||||
public @Load("@-top") TextureRegion topRegion;
|
||||
|
||||
public Thruster(String name){
|
||||
super(name);
|
||||
rotate = true;
|
||||
quickRotate = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||
Draw.rect(region, req.drawx(), req.drawy());
|
||||
Draw.rect(topRegion, req.drawx(), req.drawy(), req.rotation * 90);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion[] icons(){
|
||||
return new TextureRegion[]{region, topRegion};
|
||||
}
|
||||
|
||||
public class ThrusterBuild extends WallBuild{
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
super.draw();
|
||||
|
||||
Draw.rect(topRegion, x, y, rotdeg());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ public class PointDefenseTurret extends ReloadTurret{
|
||||
|
||||
//retarget
|
||||
if(timer(timerTarget, retargetTime)){
|
||||
target = Groups.bullet.intersect(x - range, y - range, range*2, range*2).min(b -> b.team == team || !b.type().hittable ? Float.MAX_VALUE : b.dst2(this));
|
||||
target = Groups.bullet.intersect(x - range, y - range, range*2, range*2).min(b -> b.team != team && b.type().hittable, b -> b.dst2(this));
|
||||
}
|
||||
|
||||
//pooled bullets
|
||||
|
||||
@@ -118,7 +118,7 @@ public class TractorBeamTurret extends BaseTurret{
|
||||
}
|
||||
|
||||
any = true;
|
||||
target.impulseNet(Tmp.v1.set(this).sub(target).limit((force + (1f - target.dst(this) / range) * scaledForce) * efficiency() * timeScale));
|
||||
target.impulseNet(Tmp.v1.set(this).sub(target).limit((force + (1f - target.dst(this) / range) * scaledForce) * edelta() * timeScale));
|
||||
}
|
||||
}else{
|
||||
strength = Mathf.lerpDelta(strength, 0, 0.1f);
|
||||
|
||||
@@ -113,6 +113,7 @@ public class Turret extends ReloadTurret{
|
||||
stats.add(Stat.reload, 60f / reloadTime * (alternate ? 1 : shots), StatUnit.none);
|
||||
stats.add(Stat.targetsAir, targetAir);
|
||||
stats.add(Stat.targetsGround, targetGround);
|
||||
if(ammoPerShot != 1) stats.add(Stat.ammoUse, ammoPerShot, StatUnit.perShot);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -13,6 +13,7 @@ import mindustry.annotations.Annotations.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.input.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.meta.*;
|
||||
@@ -152,6 +153,11 @@ public class ItemBridge extends Block{
|
||||
lastPlan = plan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changePlacementPath(Seq<Point2> points, int rotation){
|
||||
Placement.calculateNodes(points, this, rotation, (point, other) -> Math.max(Math.abs(point.x - other.x), Math.abs(point.y - other.y)) <= range);
|
||||
}
|
||||
|
||||
public class ItemBridgeBuild extends Building{
|
||||
public int link = -1;
|
||||
public IntSet incoming = new IntSet();
|
||||
|
||||
@@ -29,7 +29,7 @@ public class StackConveyor extends Block implements Autotiler{
|
||||
|
||||
public float speed = 0f;
|
||||
public boolean splitOut = true;
|
||||
/** (minimum) amount of loading docks needed to fill a line */
|
||||
/** (minimum) amount of loading docks needed to fill a line. */
|
||||
public float recharge = 2f;
|
||||
public Effect loadEffect = Fx.plasticburn;
|
||||
public Effect unloadEffect = Fx.plasticburn;
|
||||
@@ -46,7 +46,6 @@ public class StackConveyor extends Block implements Autotiler{
|
||||
|
||||
ambientSound = Sounds.conveyor;
|
||||
ambientSoundVolume = 0.004f;
|
||||
unloadable = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -269,6 +268,11 @@ public class StackConveyor extends Block implements Autotiler{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void itemTaken(Item item){
|
||||
if(items.empty()) poofOut();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptItem(Building source, Item item){
|
||||
if(this == source) return true; // player threw items
|
||||
|
||||
@@ -37,6 +37,11 @@ public class BlockForge extends PayloadAcceptor{
|
||||
consumes.add(new ConsumeItemDynamic((BlockForgeBuild e) -> e.recipe != null ? e.recipe.requirements : ItemStack.empty));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion[] icons(){
|
||||
return new TextureRegion[]{region, outRegion};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBars(){
|
||||
super.setBars();
|
||||
|
||||
@@ -31,6 +31,11 @@ public class BlockLoader extends PayloadAcceptor{
|
||||
rotate = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion[] icons(){
|
||||
return new TextureRegion[]{region, inRegion, outRegion, topRegion};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean outputsItems(){
|
||||
return false;
|
||||
@@ -72,7 +77,7 @@ public class BlockLoader extends PayloadAcceptor{
|
||||
//draw input
|
||||
for(int i = 0; i < 4; i++){
|
||||
if(blends(i) && i != rotation){
|
||||
Draw.rect(inRegion, x, y, i * 90);
|
||||
Draw.rect(inRegion, x, y, (i * 90) - 180);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -194,6 +194,7 @@ public class LogicBlock extends Block{
|
||||
public LExecutor executor = new LExecutor();
|
||||
public float accumulator = 0;
|
||||
public Seq<LogicLink> links = new Seq<>();
|
||||
public boolean checkedDuplicates = false;
|
||||
|
||||
public void readCompressed(byte[] data, boolean relative){
|
||||
DataInputStream stream = new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(data)));
|
||||
@@ -362,6 +363,21 @@ public class LogicBlock extends Block{
|
||||
public void updateTile(){
|
||||
executor.team = team;
|
||||
|
||||
if(!checkedDuplicates){
|
||||
checkedDuplicates = true;
|
||||
var removal = new IntSet();
|
||||
var removeLinks = new Seq<LogicLink>();
|
||||
for(var link : links){
|
||||
var build = world.build(link.x, link.y);
|
||||
if(build != null){
|
||||
if(!removal.add(build.id)){
|
||||
removeLinks.add(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
links.removeAll(removeLinks);
|
||||
}
|
||||
|
||||
//check for previously invalid links to add after configuration
|
||||
boolean changed = false;
|
||||
|
||||
@@ -371,7 +387,7 @@ public class LogicBlock extends Block{
|
||||
if(!l.active) continue;
|
||||
|
||||
boolean valid = validLink(world.build(l.x, l.y));
|
||||
if(valid != l.valid ){
|
||||
if(valid != l.valid){
|
||||
changed = true;
|
||||
l.valid = valid;
|
||||
if(valid){
|
||||
|
||||
@@ -92,11 +92,6 @@ public class ItemLiquidGenerator extends PowerGenerator{
|
||||
return generateTime > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float ambientVolume(){
|
||||
return Mathf.clamp(productionEfficiency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTile(){
|
||||
//Note: Do not use this delta when calculating the amount of power or the power efficiency, but use it for resource consumption if necessary.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mindustry.world.blocks.power;
|
||||
|
||||
import arc.*;
|
||||
import arc.math.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
@@ -50,6 +51,11 @@ public class PowerGenerator extends PowerDistributor{
|
||||
/** The efficiency of the producer. An efficiency of 1.0 means 100% */
|
||||
public float productionEfficiency = 0.0f;
|
||||
|
||||
@Override
|
||||
public float ambientVolume(){
|
||||
return Mathf.clamp(productionEfficiency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPowerProduction(){
|
||||
return powerProduction * productionEfficiency;
|
||||
|
||||
@@ -14,6 +14,7 @@ import mindustry.entities.units.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.input.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.meta.*;
|
||||
@@ -25,7 +26,8 @@ public class PowerNode extends PowerBlock{
|
||||
protected static boolean returnValue = false;
|
||||
protected static BuildPlan otherReq;
|
||||
|
||||
protected final ObjectSet<PowerGraph> graphs = new ObjectSet<>();
|
||||
protected final static ObjectSet<PowerGraph> graphs = new ObjectSet<>();
|
||||
protected final static Seq<Point2> tmpPoints = new Seq<>(), tmpPoints2 = new Seq<>();
|
||||
|
||||
public @Load("laser") TextureRegion laser;
|
||||
public @Load("laser-end") TextureRegion laserEnd;
|
||||
@@ -40,6 +42,7 @@ public class PowerNode extends PowerBlock{
|
||||
consumesPower = false;
|
||||
outputsPower = false;
|
||||
canOverdrive = false;
|
||||
swapDiagonalPlacement = true;
|
||||
|
||||
config(Integer.class, (entity, value) -> {
|
||||
PowerModule power = entity.power;
|
||||
@@ -149,17 +152,20 @@ public class PowerNode extends PowerBlock{
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
protected void setupColor(float satisfaction){
|
||||
float fract = 1f - satisfaction;
|
||||
@Override
|
||||
public void changePlacementPath(Seq<Point2> points, int rotation){
|
||||
Placement.calculateNodes(points, this, rotation, (point, other) -> overlaps(world.tile(point.x, point.y), world.tile(other.x, other.y)));
|
||||
}
|
||||
|
||||
Draw.color(laserColor1, laserColor2, fract * 0.86f + Mathf.absin(3f, 0.1f));
|
||||
protected void setupColor(float satisfaction){
|
||||
Draw.color(laserColor1, laserColor2, (1f - satisfaction) * 0.86f + Mathf.absin(3f, 0.1f));
|
||||
Draw.alpha(renderer == null ? 0.5f : renderer.laserOpacity);
|
||||
}
|
||||
|
||||
protected void drawLaser(Team team, float x1, float y1, float x2, float y2, int size1, int size2){
|
||||
float angle1 = Angles.angle(x1, y1, x2, y2);
|
||||
float vx = Mathf.cosDeg(angle1), vy = Mathf.sinDeg(angle1);
|
||||
float len1 = size1 * tilesize / 2f - 1.5f, len2 = size2 * tilesize / 2f - 1.5f;
|
||||
float angle1 = Angles.angle(x1, y1, x2, y2),
|
||||
vx = Mathf.cosDeg(angle1), vy = Mathf.sinDeg(angle1),
|
||||
len1 = size1 * tilesize / 2f - 1.5f, len2 = size2 * tilesize / 2f - 1.5f;
|
||||
|
||||
Drawf.laser(team, laser, laserEnd, x1 + vx*len1, y1 + vy*len1, x2 - vx*len2, y2 - vy*len2, 0.25f);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class Drill extends Block{
|
||||
protected int returnCount;
|
||||
|
||||
/** Whether to draw the item this drill is mining. */
|
||||
public boolean drawMineItem = false;
|
||||
public boolean drawMineItem = true;
|
||||
/** Effect played when an item is produced. This is colored. */
|
||||
public Effect drillEffect = Fx.mine;
|
||||
/** Speed the drill bit rotates at. */
|
||||
@@ -57,6 +57,7 @@ public class Drill extends Block{
|
||||
public @Load("@-rim") TextureRegion rimRegion;
|
||||
public @Load("@-rotator") TextureRegion rotatorRegion;
|
||||
public @Load("@-top") TextureRegion topRegion;
|
||||
public @Load(value = "@-item", fallback = "drill-item-@size") TextureRegion itemRegion;
|
||||
|
||||
public Drill(String name){
|
||||
super(name);
|
||||
@@ -76,11 +77,11 @@ public class Drill extends Block{
|
||||
Tile tile = req.tile();
|
||||
if(tile == null) return;
|
||||
|
||||
countOre(req.tile());
|
||||
if(returnItem == null) return;
|
||||
countOre(tile);
|
||||
if(returnItem == null || !drawMineItem) return;
|
||||
|
||||
Draw.color(returnItem.color);
|
||||
Draw.rect("drill-top", req.drawx(), req.drawy());
|
||||
Draw.rect(itemRegion, req.drawx(), req.drawy());
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
@@ -124,6 +125,12 @@ public class Drill extends Block{
|
||||
Draw.rect(returnItem.icon(Cicon.small), dx, dy - 1);
|
||||
Draw.reset();
|
||||
Draw.rect(returnItem.icon(Cicon.small), dx, dy);
|
||||
|
||||
if(drawMineItem){
|
||||
Draw.color(returnItem.color);
|
||||
Draw.rect(itemRegion, tile.worldx() + offset, tile.worldy() + offset);
|
||||
Draw.color();
|
||||
}
|
||||
}else{
|
||||
Tile to = tile.getLinkedTilesAs(this, tempTiles).find(t -> t.drop() != null && t.drop().hardness > tier);
|
||||
Item item = to == null ? null : to.drop();
|
||||
@@ -304,7 +311,7 @@ public class Drill extends Block{
|
||||
|
||||
if(dominantItem != null && drawMineItem){
|
||||
Draw.color(dominantItem.color);
|
||||
Draw.rect("drill-top", x, y);
|
||||
Draw.rect(itemRegion, x, y);
|
||||
Draw.color();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class SolidPump extends Pump{
|
||||
stats.remove(Stat.output);
|
||||
stats.add(Stat.output, result, 60f * pumpAmount, true);
|
||||
if(attribute != null){
|
||||
stats.add(baseEfficiency > 0.0001f ? Stat.affinities : Stat.tiles, attribute);
|
||||
stats.add(baseEfficiency > 0.0001f ? Stat.affinities : Stat.tiles, attribute, floating, 1f, baseEfficiency <= 0.001f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import mindustry.world.blocks.power.*;
|
||||
|
||||
public class PowerSource extends PowerNode{
|
||||
|
||||
public float powerProduction = 10000f;
|
||||
|
||||
public PowerSource(String name){
|
||||
super(name);
|
||||
maxNodes = 100;
|
||||
@@ -14,7 +16,7 @@ public class PowerSource extends PowerNode{
|
||||
public class PowerSourceBuild extends PowerNodeBuild{
|
||||
@Override
|
||||
public float getPowerProduction(){
|
||||
return enabled ? 10000f : 0f;
|
||||
return enabled ? powerProduction : 0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -386,6 +386,13 @@ public class CoreBlock extends StorageBlock{
|
||||
}else{
|
||||
super.handleItem(source, item);
|
||||
}
|
||||
}else if(incinerate()){
|
||||
if(items.get(item) >= storageCapacity){
|
||||
//create item incineration effect at random intervals
|
||||
if(!noEffect){
|
||||
incinerateEffect(this, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class Reconstructor extends UnitBlock{
|
||||
|
||||
@Override
|
||||
public TextureRegion[] icons(){
|
||||
return new TextureRegion[]{region, outRegion, topRegion};
|
||||
return new TextureRegion[]{region, inRegion, outRegion, topRegion};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -129,7 +129,7 @@ public class Reconstructor extends UnitBlock{
|
||||
//draw input
|
||||
for(int i = 0; i < 4; i++){
|
||||
if(blends(i) && i != rotation){
|
||||
Draw.rect(inRegion, x, y, i * 90);
|
||||
Draw.rect(inRegion, x, y, (i * 90) - 180);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ public enum Stat{
|
||||
targetsGround(StatCat.function),
|
||||
damage(StatCat.function),
|
||||
ammo(StatCat.function),
|
||||
ammoUse(StatCat.function),
|
||||
shieldHealth(StatCat.function),
|
||||
cooldownTime(StatCat.function),
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ public enum StatUnit{
|
||||
minutes,
|
||||
perSecond,
|
||||
perMinute,
|
||||
perShot,
|
||||
timesSpeed(false),
|
||||
percent(false),
|
||||
shieldHealth,
|
||||
|
||||
@@ -55,22 +55,22 @@ public class Stats{
|
||||
}
|
||||
|
||||
public void add(Stat stat, Attribute attr){
|
||||
add(stat, attr, false, 1f);
|
||||
add(stat, attr, false, 1f, false);
|
||||
}
|
||||
|
||||
public void add(Stat stat, Attribute attr, float scale){
|
||||
add(stat, attr, false, scale);
|
||||
add(stat, attr, false, scale, false);
|
||||
}
|
||||
|
||||
public void add(Stat stat, Attribute attr, boolean floating){
|
||||
add(stat, attr, floating, 1f);
|
||||
add(stat, attr, floating, 1f, false);
|
||||
}
|
||||
|
||||
public void add(Stat stat, Attribute attr, boolean floating, float scale){
|
||||
public void add(Stat stat, Attribute attr, boolean floating, float scale, boolean startZero){
|
||||
for(var block : Vars.content.blocks()
|
||||
.select(block -> block instanceof Floor f && f.attributes.get(attr) != 0 && !(f.isLiquid && !floating))
|
||||
.<Floor>as().with(s -> s.sort(f -> f.attributes.get(attr)))){
|
||||
add(stat, new FloorEfficiencyValue(block, block.attributes.get(attr) * scale));
|
||||
add(stat, new FloorEfficiencyValue(block, block.attributes.get(attr) * scale, startZero));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,10 @@ public class AmmoListValue<T extends UnlockableContent> implements StatValue{
|
||||
bt.add(Core.bundle.format("bullet.damage", type.damage));
|
||||
}
|
||||
|
||||
if(type.buildingDamageMultiplier != 1){
|
||||
sep(bt, Core.bundle.format("bullet.buildingdamage", type.buildingDamageMultiplier * 100));
|
||||
}
|
||||
|
||||
if(type.splashDamage > 0){
|
||||
sep(bt, Core.bundle.format("bullet.splashdamage", (int)type.splashDamage, Strings.fixed(type.splashDamageRadius / tilesize, 1)));
|
||||
}
|
||||
|
||||
@@ -10,16 +10,18 @@ import mindustry.world.meta.*;
|
||||
public class FloorEfficiencyValue implements StatValue{
|
||||
private final Floor floor;
|
||||
private final float multiplier;
|
||||
private final boolean startZero;
|
||||
|
||||
public FloorEfficiencyValue(Floor floor, float multiplier){
|
||||
public FloorEfficiencyValue(Floor floor, float multiplier, boolean startZero){
|
||||
this.floor = floor;
|
||||
this.multiplier = multiplier;
|
||||
this.startZero = startZero;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(Table table){
|
||||
table.stack(new Image(floor.icon(Cicon.medium)).setScaling(Scaling.fit), new Table(t -> {
|
||||
t.top().right().add((multiplier < 0 ? "[scarlet]" : "[accent]+") + (int)((multiplier) * 100) + "%").style(Styles.outlineLabel);
|
||||
t.top().right().add((multiplier < 0 ? "[scarlet]" : startZero ? "[accent]" : "[accent]+") + (int)((multiplier) * 100) + "%").style(Styles.outlineLabel);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user