Too many things to list

This commit is contained in:
Anuken
2022-04-10 21:02:51 -04:00
parent 89af2c8033
commit 2145e31bac
18 changed files with 318 additions and 24 deletions

View File

@@ -152,6 +152,7 @@ public class Blocks{
//logic
message, switchBlock, microProcessor, logicProcessor, hyperProcessor, largeLogicDisplay, logicDisplay, memoryCell, memoryBank,
canvas,
worldProcessor, worldCell,
//campaign
@@ -1588,7 +1589,6 @@ public class Blocks{
requirements(Category.defense, with(Items.beryllium, 6));
health = 130 * wallHealthMultiplier;
armor = 2f;
buildCostMultiplier = 4f;
}};
berylliumWallLarge = new Wall("beryllium-wall-large"){{
@@ -1596,14 +1596,12 @@ public class Blocks{
health = 130 * wallHealthMultiplier * 4;
armor = 2f;
size = 2;
buildCostMultiplier = 4f;
}};
tungstenWall = new Wall("tungsten-wall"){{
requirements(Category.defense, with(Items.tungsten, 6));
health = 180 * wallHealthMultiplier;
armor = 14f;
buildCostMultiplier = 4f;
}};
tungstenWallLarge = new Wall("tungsten-wall-large"){{
@@ -1611,7 +1609,6 @@ public class Blocks{
health = 180 * wallHealthMultiplier * 4;
armor = 14f;
size = 2;
buildCostMultiplier = 4f;
}};
blastDoor = new AutoDoor("blast-door"){{
@@ -1619,14 +1616,12 @@ public class Blocks{
health = 175 * wallHealthMultiplier * 4;
armor = 14f;
size = 2;
buildCostMultiplier = 4f;
}};
carbideWall = new Wall("carbide-wall"){{
requirements(Category.defense, with(Items.thorium, 6, Items.carbide, 6));
health = 240 * wallHealthMultiplier;
armor = 16f;
buildCostMultiplier = 4f;
}};
carbideWallLarge = new Wall("carbide-wall-large"){{
@@ -1634,7 +1629,6 @@ public class Blocks{
health = 240 * wallHealthMultiplier * 4;
armor = 16f;
size = 2;
buildCostMultiplier = 4f;
}};
mender = new MendProjector("mender"){{
@@ -2987,7 +2981,7 @@ public class Blocks{
//TODO these may work in space, but what's the point?
lancer = new PowerTurret("lancer"){{
requirements(Category.turret, with(Items.copper, 70, Items.lead, 70, Items.silicon, 70));
requirements(Category.turret, with(Items.copper, 60, Items.lead, 70, Items.silicon, 60, Items.titanium, 30));
range = 165f;
shoot.firstShotDelay = 40f;
@@ -3003,6 +2997,7 @@ public class Blocks{
scaledHealth = 280;
targetAir = false;
moveWhileCharging = false;
accurateDelay = false;
shootSound = Sounds.laser;
coolant = consume(new ConsumeCoolant(0.2f));
@@ -3683,7 +3678,7 @@ public class Blocks{
coolantMultiplier = 6f;
shootShake = 1f;
ammoPerShot = 4;
ammoPerShot = 2;
drawer = new DrawTurret("reinforced-");
shootY = -2;
outlineColor = Pal.darkOutline;
@@ -4484,6 +4479,15 @@ public class Blocks{
size = 6;
}};
canvas = new CanvasBlock("canvas"){{
requirements(Category.logic, with(Items.silicon, 40));
canvasSize = 12;
padding = 7f / 4f * 2f;
size = 2;
}};
worldProcessor = new LogicBlock("world-processor"){{
requirements(Category.logic, BuildVisibility.editorOnly, with());

View File

@@ -225,7 +225,7 @@ public class ErekirTechTree{
});
});
node(radar, Seq.with(new Research(beamNode), new Research(turbineCondenser), new Research(fabricator)), () -> {
node(radar, Seq.with(new Research(beamNode), new Research(turbineCondenser), new Research(fabricator), new OnSector(SectorPresets.two)), () -> {
node(breach, Seq.with(new Research(siliconArcFurnace), new OnSector(two)), () -> {
node(berylliumWall, () -> {
node(berylliumWallLarge, () -> {

View File

@@ -74,6 +74,7 @@ public class Planets{
r.fog = true;
r.staticFog = true; //TODO decide, is this a good idea?
r.lighting = false;
r.onlyDepositCore = true;
};
unlockedOnLand.add(Blocks.coreBastion);

View File

@@ -3450,6 +3450,7 @@ public class UnitTypes{
fogRadius = 0f;
targetable = false;
hittable = false;
setEnginesMirror(
new UnitEngine(21 / 4f, 19 / 4f, 2.2f, 45f),
@@ -3509,6 +3510,7 @@ public class UnitTypes{
fogRadius = 0f;
targetable = false;
hittable = false;
engineOffset = 7.2f;
engineSize = 3.1f;
@@ -3583,6 +3585,7 @@ public class UnitTypes{
fogRadius = 0f;
targetable = false;
hittable = false;
engineOffset = 7.5f;
engineSize = 3.4f;

View File

@@ -160,7 +160,7 @@ public class Logic implements ApplicationListener{
//makes cores go derelict in RTS mode, helps clean things up
if(e.tile.build instanceof CoreBuild core && core.team.isAI() && core.team.rules().rtsAi){
Core.app.post(() -> {
core.team.data().makeDerelict(core.x, core.y, state.rules.enemyCoreBuildRadius);
core.team.data().timeDestroy(core.x, core.y, state.rules.enemyCoreBuildRadius);
});
}
});

View File

@@ -171,7 +171,7 @@ public class Damage{
});
Units.nearbyEnemies(b.team, rect, u -> {
if(u.checkTarget(b.type.collidesAir, b.type.collidesGround)){
if(u.checkTarget(b.type.collidesAir, b.type.collidesGround) && u.type.hittable){
distances.add(u.dst(b));
}
});
@@ -272,6 +272,7 @@ public class Damage{
float x2 = vec.x + x, y2 = vec.y + y;
Cons<Unit> cons = e -> {
if(!e.type.hittable) return;
//the peirce cap works for units, but really terribly, I'm just disabling it for now.
//if(pierceCap > 0 && pierceCount > pierceCap) return;
@@ -373,7 +374,7 @@ public class Damage{
/** Damages all entities and blocks in a radius that are enemies of the team. */
public static void damageUnits(Team team, float x, float y, float size, float damage, Boolf<Unit> predicate, Cons<Unit> acceptor){
Cons<Unit> cons = entity -> {
if(!predicate.get(entity)) return;
if(!predicate.get(entity) || !entity.type.hittable) return;
entity.hitbox(hitrect);
if(!hitrect.overlaps(rect)){
@@ -437,7 +438,7 @@ public class Damage{
/** Damages all entities and blocks in a radius that are enemies of the team. */
public static void damage(Team team, float x, float y, float radius, float damage, boolean complete, boolean air, boolean ground, boolean scaled, Bullet source){
Cons<Unit> cons = entity -> {
if(entity.team == team || !entity.within(x, y, radius + (scaled ? entity.hitSize / 2f : 0f)) || (entity.isFlying() && !air) || (entity.isGrounded() && !ground)){
if(entity.team == team || !entity.type.hittable || !entity.within(x, y, radius + (scaled ? entity.hitSize / 2f : 0f)) || (entity.isFlying() && !air) || (entity.isGrounded() && !ground)){
return;
}

View File

@@ -159,7 +159,7 @@ public class EntityCollisions{
float vbx = b.getX() - b.lastX();
float vby = b.getY() - b.lastY();
if(a != b && a.collides(b)){
if(a != b && a.collides(b) && b.collides(a)){
l1.set(a.getX(), a.getY());
boolean collide = r1.overlaps(r2) || collide(r1.x, r1.y, r1.width, r1.height, vax, vay,
r2.x, r2.y, r2.width, r2.height, vbx, vby, l1);

View File

@@ -257,6 +257,12 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
return type.isCounted;
}
@Override
@Replace
public boolean collides(Hitboxc other){
return type.hittable;
}
@Override
public int itemCapacity(){
return type.itemCapacity;

View File

@@ -79,6 +79,8 @@ public class Rules{
public boolean placeRangeCheck = false;
/** If true, dead teams in PvP automatically have their blocks & units converted to derelict upon death. */
public boolean cleanupDeadTeams = true;
/** If true, items can only be deposited in the core. */
public boolean onlyDepositCore = false;
/** Radius around enemy wave drop zones.*/
public float dropZoneRadius = 300f;
/** Time between waves in ticks. */

View File

@@ -305,6 +305,20 @@ public class Teams{
}
}
/** Make all buildings within this range explode. */
public void timeDestroy(float x, float y, float range){
var builds = new Seq<Building>();
if(buildings != null){
buildings.intersect(x - range, y - range, range * 2f, range * 2f, builds);
}
for(var build : builds){
if(build.within(x, y, range)){
Time.run(Mathf.random(0f, 60f * 6f), build::kill);
}
}
}
private void scheduleDerelict(Building build){
//TODO this may cause a lot of packet spam, optimize?
Call.setTeam(build, Team.derelict);

View File

@@ -238,14 +238,19 @@ public class OverlayRenderer{
Lines.circle(v.x, v.y, 6 + Mathf.absin(Time.time, 5f, 1f));
Draw.reset();
Building tile = world.buildWorld(v.x, v.y);
if(input.canDropItem() && tile != null && tile.interactable(player.team()) && tile.acceptStack(player.unit().item(), player.unit().stack.amount, player.unit()) > 0 && player.within(tile, itemTransferRange)){
Building build = world.buildWorld(v.x, v.y);
if(input.canDropItem() && build != null && build.interactable(player.team()) && build.acceptStack(player.unit().item(), player.unit().stack.amount, player.unit()) > 0 && player.within(build, itemTransferRange)){
boolean invalid = (state.rules.onlyDepositCore && !(build instanceof CoreBuild));
Lines.stroke(3f, Pal.gray);
Lines.square(tile.x, tile.y, tile.block.size * tilesize / 2f + 3 + Mathf.absin(Time.time, 5f, 1f));
Lines.stroke(1f, Pal.place);
Lines.square(tile.x, tile.y, tile.block.size * tilesize / 2f + 2 + Mathf.absin(Time.time, 5f, 1f));
Lines.square(build.x, build.y, build.block.size * tilesize / 2f + 3 + Mathf.absin(Time.time, 5f, 1f));
Lines.stroke(1f, invalid ? Pal.remove : Pal.place);
Lines.square(build.x, build.y, build.block.size * tilesize / 2f + 2 + Mathf.absin(Time.time, 5f, 1f));
Draw.reset();
if(invalid){
build.block.drawPlaceText(Core.bundle.get("bar.onlycoredeposit"), build.tileX(), build.tileY(), false);
}
}
}
}

View File

@@ -36,6 +36,7 @@ import mindustry.world.blocks.*;
import mindustry.world.blocks.distribution.*;
import mindustry.world.blocks.payloads.*;
import mindustry.world.blocks.storage.*;
import mindustry.world.blocks.storage.CoreBlock.*;
import mindustry.world.meta.*;
import java.util.*;
@@ -270,7 +271,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
@Remote(targets = Loc.both, forward = true, called = Loc.server)
public static void transferInventory(Player player, Building build){
if(player == null || build == null || !player.within(build, itemTransferRange) || build.items == null || player.dead()) return;
if(player == null || build == null || !player.within(build, itemTransferRange) || build.items == null || player.dead() || (state.rules.onlyDepositCore && !(build instanceof CoreBuild))) return;
if(net.server() && (player.unit().stack.amount <= 0 || !Units.canInteract(player, build) ||
!netServer.admins.allowAction(player, ActionType.depositItem, build.tile, action -> {
@@ -1390,8 +1391,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
ItemStack stack = player.unit().stack;
if(build != null && build.acceptStack(stack.item, stack.amount, player.unit()) > 0 && build.interactable(player.team()) && build.block.hasItems && player.unit().stack().amount > 0 && build.interactable(player.team())){
Call.transferInventory(player, build);
if(build != null && build.acceptStack(stack.item, stack.amount, player.unit()) > 0 && build.interactable(player.team()) &&
build.block.hasItems && player.unit().stack().amount > 0 && build.interactable(player.team())){
if(!(state.rules.onlyDepositCore && !(build instanceof CoreBuild))){
Call.transferInventory(player, build);
}
}else{
Call.dropItem(player.angleTo(x, y));
}

View File

@@ -85,6 +85,8 @@ public class UnitType extends UnlockableContent{
public float targetPriority = 0f;
/** If false, this unit is not targeted by anything. */
public boolean targetable = true;
/** If true, this unit can be hit with bullets/splash damage. */
public boolean hittable = true;
public boolean drawBuildBeam = true;
public boolean rotateToBuilding = true;
public float commandRadius = 150f;

View File

@@ -0,0 +1,250 @@
package mindustry.world.blocks.logic;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.input.*;
import arc.math.*;
import arc.math.geom.*;
import arc.scene.*;
import arc.scene.event.*;
import arc.scene.ui.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.gen.*;
import mindustry.ui.*;
import mindustry.world.*;
import static mindustry.Vars.*;
public class CanvasBlock extends Block{
public float padding = 0f;
public int canvasSize = 8;
public int[] palette = {0x000000ff, 0x55415f_ff, 0x646964_ff, 0xd77355_ff, 0x508cd7_ff, 0x64b964_ff, 0xe6c86e_ff, 0xdcf5ff_ff};
public int bitsPerPixel;
public IntIntMap colorToIndex = new IntIntMap();
public CanvasBlock(String name){
super(name);
configurable = true;
destructible = true;
solid = true;
config(byte[].class, (CanvasBuild build, byte[] bytes) -> {
if(build.data.length == bytes.length){
build.data = bytes;
build.updateTexture();
}
});
}
@Override
public void init(){
super.init();
for(int i = 0; i < palette.length; i++){
colorToIndex.put(palette[i], i);
}
bitsPerPixel = Mathf.log2(Mathf.nextPowerOfTwo(palette.length));
}
public class CanvasBuild extends Building{
public @Nullable Texture texture;
public byte[] data = new byte[Mathf.ceil(canvasSize * canvasSize * bitsPerPixel / 8f)];
public void updateTexture(){
Pixmap pix = makePixmap();
if(texture != null){
texture.draw(pix);
}else{
texture = new Texture(pix);
}
pix.dispose();
}
public Pixmap makePixmap(){
Pixmap pix = new Pixmap(canvasSize, canvasSize);
int bpp = bitsPerPixel;
int pixels = canvasSize * canvasSize;
for(int i = 0; i < pixels; i++){
int bitOffset = i * bpp;
int pal = getByte(bitOffset);
pix.set(i % canvasSize, i / canvasSize, palette[pal]);
}
return pix;
}
public byte[] packPixmap(Pixmap pixmap){
byte[] bytes = new byte[data.length];
int pixels = canvasSize * canvasSize;
for(int i = 0; i < pixels; i++){
int color = pixmap.get(i % canvasSize, i / canvasSize);
int palIndex = colorToIndex.get(color);
setByte(bytes, i * bitsPerPixel, palIndex);
}
return bytes;
}
protected int getByte(int bitOffset){
int result = 0, bpp = bitsPerPixel;
for(int i = 0; i < bpp; i++){
int word = i + bitOffset >>> 3;
result |= (((data[word] & (1 << (i + bitOffset & 7))) == 0 ? 0 : 1) << i);
}
return result;
}
protected void setByte(byte[] bytes, int bitOffset, int value){
int bpp = bitsPerPixel;
for(int i = 0; i < bpp; i++){
int word = i + bitOffset >>> 3;
if(((value >>> i) & 1) == 0){
bytes[word] &= ~(1 << (i + bitOffset & 7));
}else{
bytes[word] |= (1 << (i + bitOffset & 7));
}
}
}
@Override
public void draw(){
super.draw();
if(texture == null){
updateTexture();
}
Tmp.tr1.set(texture);
Draw.rect(Tmp.tr1, x, y, size * tilesize - padding, size * tilesize - padding);
}
@Override
public void remove(){
super.remove();
if(texture != null){
texture.dispose();
texture = null;
}
}
@Override
public void buildConfiguration(Table table){
table.button(Icon.pencil, Styles.clearTransi, () -> {
Dialog dialog = new Dialog();
Pixmap pix = makePixmap();
Texture texture = new Texture(pix);
int[] curColor = {palette[0]};
boolean[] modified = {false};
dialog.cont.table(Tex.pane, body -> {
body.stack(new Element(){
int lastX, lastY;
{
addListener(new InputListener(){
int convertX(float ex){
return (int)((ex - x) / width * canvasSize);
}
int convertY(float ey){
return pix.height - 1 - (int)((ey - y) / height * canvasSize);
}
@Override
public boolean touchDown(InputEvent event, float ex, float ey, int pointer, KeyCode button){
int cx = convertX(ex), cy = convertY(ey);
draw(cx, cy);
lastX = cx;
lastY = cy;
return true;
}
@Override
public void touchDragged(InputEvent event, float ex, float ey, int pointer){
int cx = convertX(ex), cy = convertY(ey);
Bresenham2.line(lastX, lastY, cx, cy, (x, y) -> draw(x, y));
lastX = cx;
lastY = cy;
}
});
}
void draw(int x, int y){
if(pix.get(x, y) != curColor[0]){
pix.set(x, y, curColor[0]);
Pixmaps.drawPixel(texture, x, y, curColor[0]);
modified[0] = true;
}
}
@Override
public void draw(){
Tmp.tr1.set(texture);
Draw.alpha(parentAlpha);
Draw.rect(Tmp.tr1, x + width/2f, y + height/2f, width, height);
}
}, new GridImage(canvasSize, canvasSize){{
touchable = Touchable.disabled;
}}).size(500f);
});
dialog.cont.row();
dialog.cont.table(Tex.button, p -> {
for(int i = 0; i < palette.length; i++){
int fi = i;
var button = p.button(Tex.whiteui, Styles.clearTogglei, 30, () -> {
curColor[0] = palette[fi];
}).size(44).checked(b -> curColor[0] == palette[fi]).get();
button.getStyle().imageUpColor = new Color(palette[i]);
}
});
dialog.closeOnBack();
dialog.buttons.defaults().size(150f, 64f);
dialog.buttons.button("@cancel", Icon.cancel, dialog::hide);
dialog.buttons.button("@ok", Icon.ok, () -> {
if(modified[0]){
configure(packPixmap(pix));
pix.dispose();
texture.dispose();
}
dialog.hide();
});
dialog.show();
}).size(40f);
}
@Override
public byte[] config(){
return data;
}
@Override
public void write(Writes write){
super.write(write);
//for future canvas resizing events
write.i(data.length);
write.b(data);
}
@Override
public void read(Reads read, byte revision){
super.read(read, revision);
int len = read.i();
if(data.length == len){
read.b(data);
}else{
read.skip(len);
}
}
}
}

View File

@@ -87,7 +87,7 @@ public class MessageBlock extends Block{
@Override
public void buildConfiguration(Table table){
table.button(Icon.pencil, () -> {
table.button(Icon.pencil, Styles.clearTransi, () -> {
if(mobile){
Core.input.getTextInput(new TextInput(){{
text = message.toString();