Merge branch 'master' of https://github.com/Anuken/Mindustry into v105

This commit is contained in:
Petr Gašparík
2020-05-28 08:23:37 +02:00
27 changed files with 921 additions and 701 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 826 KiB

After

Width:  |  Height:  |  Size: 822 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 128 KiB

View File

@@ -34,6 +34,9 @@ public class UnitTypes implements ContentList{
//TODO implement other starter drones
public static @EntityDef({Unitc.class, Builderc.class, Minerc.class}) UnitType alpha, beta, gamma;
//air + building + mining + payload
public static @EntityDef({Unitc.class, Builderc.class, Minerc.class, Payloadc.class}) UnitType trident;
//water
public static @EntityDef({Unitc.class, WaterMovec.class, Commanderc.class}) UnitType vanguard;
@@ -264,6 +267,7 @@ public class UnitTypes implements ContentList{
engineOffset = 7.8f;
range = 140f;
faceTarget = false;
weapons.add(new Weapon(){{
x = 3f;
shootY = 0f;
@@ -423,6 +427,45 @@ public class UnitTypes implements ContentList{
}};
}});
}};
trident = new UnitType("trident"){{
//wraith.upgrade = this;
tier = 3;
health = 500;
speed = 2f;
accel = 0.05f;
drag = 0.016f;
lowAltitude = true;
flying = true;
engineOffset = 10.5f;
rotateShooting = false;
hitsize = 14f;
engineSize = 3f;
for(boolean b : Mathf.booleans){
weapons.add(
new Weapon("heal-weapon-mount"){{
reload = 25f;
x = 8f * Mathf.sign(b);
y = -6f;
rotate = true;
mirror = false;
flipSprite = !b;
bullet = Bullets.healBulletBig;
}},
new Weapon("heal-weapon-mount"){{
reload = 15f;
x = 4f * Mathf.sign(b);
y = 5f;
rotate = true;
mirror = false;
flipSprite = !b;
bullet = Bullets.healBullet;
}}
);
}
}};
/*
chaosArray = new UnitType("chaos-array", GroundUnit::new){{

View File

@@ -14,12 +14,11 @@ import static mindustry.Vars.content;
public class MassDriverBolt extends BulletType{
public MassDriverBolt(){
super(5.3f, 50);
super(1f, 50);
collidesTiles = false;
lifetime = 200f;
lifetime = 1f;
despawnEffect = Fx.smeltsmoke;
hitEffect = Fx.hitBulletBig;
drag = 0.005f;
}
@Override

View File

@@ -10,7 +10,7 @@ import static mindustry.Vars.tilesize;
abstract class BlockUnitComp implements Unitc{
@Import Team team;
@ReadOnly Tilec tile;
@ReadOnly transient Tilec tile;
public void tile(Tilec tile){
this.tile = tile;

View File

@@ -1,12 +1,20 @@
package mindustry.entities.comp;
import arc.math.*;
import arc.struct.*;
import arc.util.*;
import mindustry.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.gen.*;
import mindustry.world.*;
import mindustry.world.blocks.payloads.*;
/** An entity that holds a payload. */
@Component
abstract class PayloadComp{
abstract class PayloadComp implements Posc, Rotc{
@Import float x, y, rotation;
Array<Payload> payloads = new Array<>();
boolean hasPayload(){
@@ -16,4 +24,72 @@ abstract class PayloadComp{
void addPayload(Payload load){
payloads.add(load);
}
void pickup(Unitc unit){
unit.remove();
payloads.add(new UnitPayload(unit));
Fx.unitPickup.at(unit);
}
void pickup(Tilec tile){
tile.tile().remove();
payloads.add(new BlockPayload(tile));
Fx.unitPickup.at(tile);
}
boolean dropLastPayload(){
if(payloads.isEmpty()) return false;
Payload load = payloads.peek();
if(tryDropPayload(load)){
payloads.pop();
return true;
}
return false;
}
boolean tryDropPayload(Payload payload){
if(payload instanceof BlockPayload){
return dropBlock((BlockPayload)payload);
}else if(payload instanceof UnitPayload){
return dropUnit((UnitPayload)payload);
}
return false;
}
boolean dropUnit(UnitPayload payload){
//TODO create an effect here and/or make them be at a lower elevation
Unitc u = payload.unit;
//can't drop ground units
if((tileOn() == null || tileOn().solid()) && u.elevation() < 0.1f){
return false;
}
u.set(this);
u.trns(Tmp.v1.rnd(Mathf.random(2f)));
u.rotation(rotation);
u.add();
Fx.unitDrop.at(u);
return true;
}
/** @return whether the tile has been successfully placed. */
boolean dropBlock(BlockPayload payload){
Tilec tile = payload.entity;
int tx = Vars.world.toTile(x - tile.block().offset()), ty = Vars.world.toTile(y - tile.block().offset());
Tile on = Vars.world.tile(tx, ty);
if(on != null && Build.validPlace(tile.team(), tx, ty, tile.block(), tile.rotation())){
int rot = (int)((rotation() + 45f) / 90f) % 4;
payload.place(on, rot);
Fx.unitDrop.at(tile);
Fx.placeBlock.at(on.drawx(), on.drawy(), on.block().size);
return true;
}
return false;
}
}

View File

@@ -40,13 +40,17 @@ abstract class PosComp implements Position{
}
/** Returns air if this unit is on a non-air top block. */
public Floor floorOn(){
Floor floorOn(){
Tile tile = tileOn();
return tile == null || tile.block() != Blocks.air ? (Floor)Blocks.air : tile.floor();
}
public @Nullable
Tile tileOn(){
Block blockOn(){
Tile tile = tileOn();
return tile == null ? Blocks.air : tile.block();
}
@Nullable Tile tileOn(){
return world.tileWorld(x, y);
}

View File

@@ -27,7 +27,8 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc{
@Import float x, y;
float amount, lastRipple, accepting, updateTime;
transient float accepting, updateTime, lastRipple;
float amount;
int generation;
Tile tile;
Liquid liquid;

View File

@@ -10,24 +10,32 @@ public enum Binding implements KeyBind{
move_x(new Axis(KeyCode.a, KeyCode.d), "general"),
move_y(new Axis(KeyCode.s, KeyCode.w)),
mouse_move(KeyCode.mouseBack),
boost(KeyCode.shiftLeft),
control(KeyCode.controlLeft),
respawn(KeyCode.v),
select(KeyCode.mouseLeft),
deselect(KeyCode.mouseRight),
break_block(KeyCode.mouseRight),
pickupCargo(KeyCode.leftBracket),
dropCargo(KeyCode.rightBracket),
clear_building(KeyCode.q),
pause_building(KeyCode.e),
rotate(new Axis(KeyCode.scroll)),
rotateplaced(KeyCode.r),
diagonal_placement(KeyCode.controlLeft),
pick(KeyCode.mouseMiddle),
schematic_select(KeyCode.f),
schematic_flip_x(KeyCode.z),
schematic_flip_y(KeyCode.x),
schematic_menu(KeyCode.t),
category_prev(KeyCode.comma),
category_next(KeyCode.period),
block_select_left(KeyCode.left),
block_select_right(KeyCode.right),
block_select_up(KeyCode.up),
@@ -42,6 +50,7 @@ public enum Binding implements KeyBind{
block_select_08(KeyCode.num8),
block_select_09(KeyCode.num9),
block_select_10(KeyCode.num0),
zoom(new Axis(KeyCode.scroll), "view"),
menu(Core.app.getType() == ApplicationType.Android ? KeyCode.back : KeyCode.escape),
fullscreen(KeyCode.f11),

View File

@@ -25,6 +25,7 @@ import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.meta.*;
import static arc.Core.scene;
import static mindustry.Vars.*;
@@ -607,5 +608,25 @@ public class DesktopInput extends InputHandler{
isBoosting = Core.input.keyDown(Binding.boost) && !movement.isZero();
player.boosting(isBoosting);
if(unit instanceof Payloadc){
Payloadc pay = (Payloadc)unit;
if(Core.input.keyTap(Binding.pickupCargo) && pay.payloads().size < unit.type().payloadCapacity){
Unitc target = Units.closest(player.team(), pay.x(), pay.y(), 30f, u -> u.isAI() && u.isGrounded());
if(target != null){
pay.pickup(target);
}else if(!pay.hasPayload()){
Tilec tile = world.entWorld(pay.x(), pay.y());
if(tile != null && tile.team() == unit.team() && tile.block().synthetic() && tile.block().buildVisibility != BuildVisibility.hidden && tile.block().size <= 3){
pay.pickup(tile);
}
}
}
if(Core.input.keyTap(Binding.dropCargo)){
pay.dropLastPayload();
}
}
}
}

View File

@@ -17,6 +17,7 @@ import mindustry.net.Packets.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.blocks.payloads.*;
import java.io.*;
import java.nio.*;
@@ -87,6 +88,14 @@ public class TypeIO{
}
}
public static void writePayload(Writes writes, Payload payload){
Payload.write(payload, writes);
}
public static Payload readPayload(Reads read){
return Payload.read(read);
}
//only for players!
public static void writeUnit(Writes write, Unitc unit){
write.b(unit.isNull() ? 0 : unit instanceof BlockUnitc ? 1 : 2);

View File

@@ -21,6 +21,7 @@ import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.ui.*;
import mindustry.world.blocks.environment.*;
import mindustry.world.blocks.payloads.*;
import static mindustry.Vars.*;
@@ -40,6 +41,7 @@ public class UnitType extends UnlockableContent{
public boolean faceTarget = true, rotateShooting = true, isCounted = true, lowAltitude = false;
public boolean canBoost = false;
public float sway = 1f;
public int payloadCapacity = 1;
public int legCount = 4;
public float legLength = 24f, legSpeed = 0.1f, legTrns = 1f;
@@ -159,6 +161,11 @@ public class UnitType extends UnlockableContent{
}
Draw.z(Math.min(z - 0.01f, Layer.bullet - 1f));
if(unit instanceof Payloadc){
drawPayload((Payloadc)unit);
}
drawOcclusion(unit);
Draw.z(z);
@@ -178,6 +185,14 @@ public class UnitType extends UnlockableContent{
}
}
public void drawPayload(Payloadc unit){
if(unit.hasPayload()){
Payload pay = unit.payloads().first();
pay.set(unit.x(), unit.y(), unit.rotation());
pay.draw();
}
}
public void drawShield(Unitc unit){
float alpha = unit.shieldAlpha();
float radius = unit.hitSize() * 1.3f;

View File

@@ -7,7 +7,7 @@ import mindustry.graphics.*;
public class SurgeWall extends Wall{
public float lightningChance = 0.05f;
public float lightningDamage = 15f;
public float lightningDamage = 20f;
public int lightningLength = 17;
public SurgeWall(String name){

View File

@@ -26,6 +26,8 @@ public class MassDriver extends Block{
public int minDistribute = 10;
public float knockback = 4f;
public float reloadTime = 100f;
public float bulletSpeed = 5.5f;
public float bulletLifetime = 200f;
public Effect shootEffect = Fx.shootBig2;
public Effect smokeEffect = Fx.shootBigSmoke2;
public Effect recieveEffect = Fx.mineBig;
@@ -252,8 +254,8 @@ public class MassDriver extends Block{
float angle = tile.angleTo(target);
Bullets.driverBolt.create(this, team(),
x + Angles.trnsx(angle, translation), y + Angles.trnsy(angle, translation),
angle, -1f, 1f, 1f, data);
x + Angles.trnsx(angle, translation), y + Angles.trnsy(angle, translation),
angle, -1f, bulletSpeed, bulletLifetime, data);
shootEffect.at(x + Angles.trnsx(angle, translation),
y + Angles.trnsy(angle, translation), angle);
@@ -287,19 +289,16 @@ public class MassDriver extends Block{
}
protected boolean shooterValid(Tile other){
if(other == null) return true;
if(!(other.block() instanceof MassDriver)) return false;
MassDriverEntity entity = other.ent();
return link == tile.pos() && tile.dst(other) <= range;
return entity.link == tile.pos() && tile.dst(other) <= range;
}
protected boolean linkValid(){
if(tile == null) return false;
if(link == -1) return false;
Tilec link = world.ent(this.link);
return link != null && link.block() instanceof MassDriver && link.team() == team && tile.dst(link) <= range;
Tile link = world.tile(this.link);
return link != null && link.block() instanceof MassDriver && link.team() == tile.team() && tile.dst(link) <= range;
}
@Override

View File

@@ -17,6 +17,10 @@ public class BlockPayload implements Payload{
this.entity = block.newEntity().create(block, team);
}
public BlockPayload(Tilec entity){
this.entity = entity;
}
public Block block(){
return entity.block();
}

View File

@@ -1,5 +1,6 @@
package mindustry.world.blocks.production;
import arc.scene.ui.layout.*;
import arc.util.ArcAnnotate.*;
import arc.util.io.*;
import mindustry.*;
@@ -16,6 +17,7 @@ public class ResearchBlock extends Block{
solid = true;
hasPower = true;
hasItems = true;
configurable = true;
}
public class ResearchBlockEntity extends TileEntity{
@@ -26,6 +28,11 @@ public class ResearchBlock extends Block{
}
@Override
public void buildConfiguration(Table table){
}
@Override
public void write(Writes write){
super.write(write);

View File

@@ -54,6 +54,8 @@ public class LaunchPad extends Block{
public void draw(){
super.draw();
if(!Vars.state.isCampaign()) return;
if(lightRegion.found()){
Draw.color(lightColor);
float progress = Math.min((float)items.total() / itemCapacity, timer.getTime(timerLaunch) / (launchTime / timeScale));
@@ -89,6 +91,7 @@ public class LaunchPad extends Block{
@Override
public void updateTile(){
if(!Vars.state.isCampaign()) return;
//launch when full and base conditions are met
if(items.total() >= itemCapacity && efficiency() >= 1f && timer(timerLaunch, launchTime / timeScale)){