This commit is contained in:
Ngọc Lam
2020-11-30 15:58:43 +07:00
committed by GitHub
25 changed files with 90 additions and 60 deletions

View File

@@ -47,6 +47,8 @@ public class Vars implements Loadable{
public static final int bufferSize = 8192;
/** global charset, since Android doesn't support the Charsets class */
public static final Charset charset = Charset.forName("UTF-8");
/** mods suggested for import */
public static final String[] suggestedMods = {""};
/** main application name, capitalized */
public static final String appName = "Mindustry";
/** URL for itch.io donations. */
@@ -56,7 +58,7 @@ public class Vars implements Loadable{
/** URL for sending crash reports to */
public static final String crashReportURL = "http://192.99.169.18/report";
/** URL the links to the wiki's modding guide.*/
public static final String modGuideURL = "https://mindustrygame.github.io/wiki/modding/";
public static final String modGuideURL = "https://mindustrygame.github.io/wiki/modding/1-modding/";
/** URL to the JSON file containing all the global, public servers. Not queried in BE. */
public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers.json";
/** URL to the JSON file containing all the BE servers. Only queried in BE. */

View File

@@ -13,6 +13,7 @@ import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.world.*;
import mindustry.world.blocks.storage.*;
import mindustry.world.meta.*;
import static mindustry.Vars.*;
@@ -115,7 +116,7 @@ public class Pathfinder implements Runnable{
}
return PathTile.get(
tile.build == null || !tile.solid() ? 0 : Math.min((int)(tile.build.health / 40), 80),
tile.build == null || !tile.solid() || tile.block() instanceof CoreBlock ? 0 : Math.min((int)(tile.build.health / 40), 80),
tile.getTeamID(),
tile.solid(),
tile.floor().isLiquid,
@@ -458,7 +459,7 @@ public class Pathfinder implements Runnable{
/** costs of getting to a specific tile */
public int[][] weights;
/** search IDs of each position - the highest, most recent search is prioritized and overwritten */
int[][] searches;
public int[][] searches;
/** search frontier, these are Pos objects */
IntQueue frontier = new IntQueue();
/** all target positions; these positions have a cost of 0, and must be synchronized on! */

View File

@@ -1657,6 +1657,7 @@ public class UnitTypes implements ContentList{
recoil = 3f;
occlusion = 12f;
ejectEffect = Fx.casing3;
shootSound = Sounds.shootBig;
shots = 3;
shotDelay = 4f;

View File

@@ -340,7 +340,7 @@ public class Control implements ApplicationListener, Loadable{
state.rules.waves = true;
//reset win wave??
state.rules.winWave = state.rules.attackMode ? -1 : sector.preset != null ? sector.preset.captureWave : 40;
state.rules.winWave = state.rules.attackMode ? -1 : sector.preset != null ? sector.preset.captureWave : state.rules.winWave > state.wave ? state.rules.winWave : 40;
//if there's still an enemy base left, fix it
if(state.rules.attackMode){

View File

@@ -258,11 +258,11 @@ public class UI implements ApplicationListener, Loadable{
TextField field = cont.field(def, t -> {}).size(330f, 50f).get();
field.setFilter((f, c) -> field.getText().length() < textLength && filter.acceptChar(f, c));
buttons.defaults().size(120, 54).pad(4);
buttons.button("@cancel", this::hide);
buttons.button("@ok", () -> {
confirmed.get(field.getText());
hide();
}).disabled(b -> field.getText().isEmpty());
buttons.button("@cancel", this::hide);
keyDown(KeyCode.enter, () -> {
String text = field.getText();
if(!text.isEmpty()){

View File

@@ -53,7 +53,7 @@ public class Lightning{
world.raycastEach(World.toTile(from.getX()), World.toTile(from.getY()), World.toTile(to.getX()), World.toTile(to.getY()), (wx, wy) -> {
Tile tile = world.tile(wx, wy);
if(tile != null && tile.block().insulated){
if(tile != null && tile.block().insulated && tile.team() != team){
bhit = true;
//snap it instead of removing
lines.get(lines.size -1).set(wx * tilesize, wy * tilesize);

View File

@@ -30,7 +30,7 @@ public class RepairFieldAbility extends Ability{
Units.nearby(unit.team, unit.x, unit.y, range, other -> {
if(other.damaged()){
healEffect.at(unit);
healEffect.at(other);
wasHealed = true;
}
other.heal(amount);

View File

@@ -16,11 +16,13 @@ abstract class BoundedComp implements Velc, Posc, Healthc, Flyingc{
@Override
public void update(){
//repel unit out of bounds
if(x < 0) vel.x += (-x/warpDst);
if(y < 0) vel.y += (-y/warpDst);
if(x > world.unitWidth()) vel.x -= (x - world.unitWidth())/warpDst;
if(y > world.unitHeight()) vel.y -= (y - world.unitHeight())/warpDst;
if(!net.client() || isLocal()){
//repel unit out of bounds
if(x < 0) vel.x += (-x/warpDst);
if(y < 0) vel.y += (-y/warpDst);
if(x > world.unitWidth()) vel.x -= (x - world.unitWidth())/warpDst;
if(y > world.unitHeight()) vel.y -= (y - world.unitHeight())/warpDst;
}
//clamp position if not flying
if(isGrounded()){

View File

@@ -11,6 +11,7 @@ import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
@@ -28,6 +29,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{
@Import float x, y, rotation;
@Import UnitType type;
@Import Team team;
@SyncLocal Queue<BuildPlan> plans = new Queue<>(1);
@SyncLocal transient boolean updateBuilding = true;
@@ -75,27 +77,27 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{
Tile tile = world.tile(current.x, current.y);
if(!(tile.block() instanceof ConstructBlock)){
if(!current.initialized && !current.breaking && Build.validPlace(current.block, team(), current.x, current.y, current.rotation)){
if(!current.initialized && !current.breaking && Build.validPlace(current.block, team, current.x, current.y, current.rotation)){
boolean hasAll = infinite || !Structs.contains(current.block.requirements, i -> core != null && !core.items.has(i.item));
if(hasAll){
Call.beginPlace(current.block, team(), current.x, current.y, current.rotation);
Call.beginPlace(self(), current.block, team, current.x, current.y, current.rotation);
}else{
current.stuck = true;
}
}else if(!current.initialized && current.breaking && Build.validBreak(team(), current.x, current.y)){
Call.beginBreak(team(), current.x, current.y);
}else if(!current.initialized && current.breaking && Build.validBreak(team, current.x, current.y)){
Call.beginBreak(self(), team, current.x, current.y);
}else{
plans.removeFirst();
return;
}
}else if(tile.team() != team()){
}else if(tile.team() != team){
plans.removeFirst();
return;
}
if(tile.build instanceof ConstructBuild && !current.initialized){
Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, team(), (Builderc)this, current.breaking)));
Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, team, self(), current.breaking)));
current.initialized = true;
}
@@ -128,7 +130,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{
control.input.drawBreaking(request);
}else{
request.block.drawRequest(request, control.input.allRequests(),
Build.validPlace(request.block, team(), request.x, request.y, request.rotation) || control.input.requestMatches(request));
Build.validPlace(request.block, team, request.x, request.y, request.rotation) || control.input.requestMatches(request));
}
}
@@ -138,7 +140,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{
/** @return whether this request should be skipped, in favor of the next one. */
boolean shouldSkip(BuildPlan request, @Nullable Building core){
//requests that you have at least *started* are considered
if(state.rules.infiniteResources || team().rules().infiniteResources || request.breaking || core == null) return false;
if(state.rules.infiniteResources || team.rules().infiniteResources || request.breaking || core == null) 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);
}

View File

@@ -90,8 +90,8 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
public float prefRotation(){
if(activelyBuilding()){
return angleTo(buildPlan());
}else if(mineTile() != null){
return angleTo(mineTile());
}else if(mineTile != null){
return angleTo(mineTile);
}else if(moving()){
return vel().angle();
}
@@ -310,7 +310,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
drag = type.drag * (isGrounded() ? (floorOn().dragMultiplier) : 1f);
//apply knockback based on spawns
if(team != state.rules.waveTeam && state.hasSpawns()){
if(team != state.rules.waveTeam && state.hasSpawns() && (!net.client() || isLocal())){
float relativeSize = state.rules.dropZoneRadius + hitSize/2f + 1f;
for(Tile spawn : spawner.getSpawns()){
if(within(spawn.worldx(), spawn.worldy(), relativeSize)){

View File

@@ -278,11 +278,13 @@ public class EventType{
public static class BlockBuildBeginEvent{
public final Tile tile;
public final Team team;
public final @Nullable Unit unit;
public final boolean breaking;
public BlockBuildBeginEvent(Tile tile, Team team, boolean breaking){
public BlockBuildBeginEvent(Tile tile, Team team, Unit unit, boolean breaking){
this.tile = tile;
this.team = team;
this.unit = unit;
this.breaking = breaking;
}
}
@@ -310,10 +312,10 @@ public class EventType{
public static class BuildSelectEvent{
public final Tile tile;
public final Team team;
public final Builderc builder;
public final Unit builder;
public final boolean breaking;
public BuildSelectEvent(Tile tile, Team team, Builderc builder, boolean breaking){
public BuildSelectEvent(Tile tile, Team team, Unit builder, boolean breaking){
this.tile = tile;
this.team = team;
this.builder = builder;

View File

@@ -225,9 +225,11 @@ public class Universe{
if(sector.isBeingPlayed()){
state.rules.winWave = waveMax;
state.rules.waves = true;
state.rules.attackMode = false;
}else{
sector.info.winWave = waveMax;
sector.info.waves = true;
sector.info.attack = false;
sector.saveInfo();
}

View File

@@ -37,6 +37,7 @@ public class PlanetRenderer implements Disposable{
public final VertexBatch3D batch = new VertexBatch3D(20000, false, true, 0);
public float zoom = 1f;
public float orbitAlpha = 1f;
private final Mesh[] outlines = new Mesh[10];
public final PlaneBatch3D projector = new PlaneBatch3D();
@@ -168,7 +169,7 @@ public class PlanetRenderer implements Disposable{
Vec3 center = planet.parent.position;
float radius = planet.orbitRadius;
int points = (int)(radius * 10);
Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray));
Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray.write(Tmp.c1).a(orbitAlpha)));
batch.flush(Gl.lineLoop);
}

View File

@@ -629,8 +629,8 @@ public class DesktopInput extends InputHandler{
unit.moveAt(movement);
}else{
unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len()));
if(!movement.isZero() && ground){
unit.vel.rotateTo(movement.angle(), unit.type.rotateSpeed);
if(!movement.isZero()){
unit.vel.rotateTo(movement.angle(), unit.type.rotateSpeed * Math.max(Time.delta, 1));
}
}

View File

@@ -769,7 +769,7 @@ public class MobileInput extends InputHandler implements GestureListener{
@Override
public boolean pan(float x, float y, float deltaX, float deltaY){
if(Core.scene.hasDialog() || Core.settings.getBool("keyboard")) return false;
if(Core.scene == null || Core.scene.hasDialog() || Core.settings.getBool("keyboard")) return false;
float scale = Core.camera.width / Core.graphics.getWidth();
deltaX *= scale;
@@ -836,7 +836,7 @@ public class MobileInput extends InputHandler implements GestureListener{
if(type == null) return;
boolean omni = unit.type.omniMovement;
boolean legs = unit.isGrounded();
boolean ground = unit.isGrounded();
boolean allowHealing = type.canHeal;
boolean validHealTarget = allowHealing && target instanceof Building && ((Building)target).isValid() && target.team() == unit.team &&
((Building)target).damaged() && target.within(unit, type.range);
@@ -908,8 +908,8 @@ public class MobileInput extends InputHandler implements GestureListener{
unit.moveAt(movement);
}else{
unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len()));
if(!movement.isZero() && legs){
unit.vel.rotateTo(movement.angle(), type.rotateSpeed);
if(!movement.isZero()){
unit.vel.rotateTo(movement.angle(), unit.type.rotateSpeed * Math.max(Time.delta, 1));
}
}

View File

@@ -309,6 +309,10 @@ public class ContentParser{
}
if(value.has("controller")){
unit.defaultController = make(resolve(value.getString("controller"), "mindustry.ai.type"));
}
//read extra default waves
if(value.has("waves")){
JsonValue waves = value.remove("waves");

View File

@@ -19,7 +19,7 @@ import mindustry.world.blocks.*;
import static mindustry.Vars.*;
public abstract class Weather extends UnlockableContent{
public class Weather extends UnlockableContent{
/** Default duration of this weather event in ticks. */
public float duration = 10f * Time.toMinutes;
public float opacityMultiplier = 1f;

View File

@@ -102,12 +102,16 @@ public class ModsDialog extends BaseDialog{
t.button("@mod.import.github", Icon.github, bstyle, () -> {
dialog.hide();
var modString = Core.settings.getString("lastmod", "");
var suggested = Structs.random(suggestedMods);
ui.showTextInput("@mod.import.github", "", 64, Core.settings.getString("lastmod", "Anuken/ExampleMod"), text -> {
Core.settings.put("lastmod", text);
ui.showTextInput("@mod.import.github", "", 64, modString.isEmpty() ? suggested : modString, text -> {
if(!modString.isEmpty() || !Structs.eq(suggested, text)){
Core.settings.put("lastmod", text);
}
ui.loadfrag.show();
//Try to download the 6.0 branch first, but if it doesn't exist try master.
//Try to download the 6.0 branch first, but if it doesn't exist, try master.
githubImport("6.0", text, e1 -> {
githubImport("master", text, e2 -> {
githubImport("main", text, e3 -> {

View File

@@ -409,6 +409,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
@Override
public void draw(){
planets.orbitAlpha = selectAlpha;
planets.render(PlanetDialog.this);
if(Core.scene.getDialog() == PlanetDialog.this){
Core.scene.setScrollFocus(PlanetDialog.this);
@@ -711,6 +712,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
stable.table(t -> {
t.add("@sectors.resources").padRight(4);
for(UnlockableContent c : sector.info.resources){
if(c == null) continue; //apparently this is possible.
t.image(c.icon(Cicon.small)).padRight(3).size(Cicon.small.size);
}
}).padLeft(10f).fillX().row();

View File

@@ -20,7 +20,7 @@ public class Build{
private static final IntSet tmp = new IntSet();
@Remote(called = Loc.server)
public static void beginBreak(Team team, int x, int y){
public static void beginBreak(@Nullable Unit unit, Team team, int x, int y){
if(!validBreak(team, x, y)){
return;
}
@@ -40,14 +40,14 @@ public class Build{
tile.setBlock(sub, team, rotation);
tile.<ConstructBuild>bc().setDeconstruct(previous);
tile.build.health = tile.build.maxHealth * prevPercent;
if(unit != null && unit.isPlayer()) tile.build.lastAccessed = unit.getPlayer().name;
Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, true)));
Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, unit, true)));
}
/** Places a ConstructBlock at this location. */
@Remote(called = Loc.server)
public static void beginPlace(Block result, Team team, int x, int y, int rotation){
public static void beginPlace(@Nullable Unit unit, Block result, Team team, int x, int y, int rotation){
if(!validPlace(result, team, x, y, rotation)){
return;
}
@@ -57,6 +57,15 @@ public class Build{
//just in case
if(tile == null) return;
//auto-rotate the block to the correct orientation and bail out
if(tile.team() == team && tile.block == result && tile.build != null){
if(unit != null && unit.isPlayer()) tile.build.lastAccessed = unit.getPlayer().name;
tile.build.rotation = Mathf.mod(rotation, 4);
tile.build.updateProximity();
tile.build.noSleep();
return;
}
Block previous = tile.block();
Block sub = ConstructBlock.get(result.size);
Seq<Building> prevBuild = new Seq<>(9);
@@ -76,10 +85,11 @@ public class Build{
build.setConstruct(previous.size == sub.size ? previous : Blocks.air, result);
build.prevBuild = prevBuild;
if(unit != null && unit.isPlayer()) build.lastAccessed = unit.getPlayer().name;
result.placeBegan(tile, previous);
Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, false)));
Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, unit, false)));
}
/** Returns whether a tile can be placed at this location by this team. */

View File

@@ -4,7 +4,7 @@ import arc.graphics.g2d.*;
import arc.math.*;
import mindustry.world.*;
/**A type of floor that is overlaid on top of over floors.*/
/**A type of floor that is overlaid on top of other floors.*/
public class OverlayFloor extends Floor{
public OverlayFloor(String name){

View File

@@ -1,16 +0,0 @@
package mindustry.world.blocks.units;
import mindustry.gen.*;
import mindustry.world.*;
public class ControlCenter extends Block{
public ControlCenter(String name){
super(name);
update = true;
}
public class ControlCenterBuild extends Building{
}
}