Skip to content

Commit

Permalink
New block! Beam Mender
Browse files Browse the repository at this point in the history
  • Loading branch information
Slotterleet committed Jun 2, 2024
1 parent 134a210 commit 6cd059d
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 24 deletions.
2 changes: 1 addition & 1 deletion mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "fos",
"displayName": "Fictional Octo System",
"author": "Team Oct",
"repo": "TeamOct/fictional-octo-system",
"repo": "TeamOct/FOS",
"subtitle": "See you later!",
"description": "FOS is a large-scale mod with a campaign that contains a brand-new solar system and unique mechanics.",
"version": "1.1 beta build-2.2",
Expand Down
15 changes: 9 additions & 6 deletions res/bundles/bundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ ability.unitresistance = Damage Resistance
bar.units = Units: {0}/{1}
bar.detectorreq = Ore Detector Required

stat.hackchance = Hack Chance
stat.attacksbosses = [accent]may hack guardians[]
stat.lifetime = Lifetime
stat.unitdamageres = Resistance per Unit
stat.hackchancemultiplier = Hack Chance Multiplier
stat.hackhpthreshold = Health Thresholds
stat.fos-hackchance = Hack Chance
stat.fos-attacksbosses = [accent]may hack guardians[]
stat.fos-lifetime = Lifetime
stat.fos-unitdamageres = Resistance per Unit
stat.fos-hackchancemultiplier = Hack Chance Multiplier
stat.fos-hackhpthreshold = Health Thresholds
stat.fos-maxbeams = Maximum Beams

unittype = [gray]Type: []
unittype.infantry = [accent]Infantry[]
Expand Down Expand Up @@ -226,6 +227,8 @@ block.fos-judge2.description = One of the testing prototypes of a death ray turr
block.fos-judge2.charge-bar = Charge
block.fos-matrix-shield-projector.name = Matrix Shield Projector
block.fos-matrix-shield-projector.description = Creates a rectangular force field around itself, protecting buildings and units inside from damage.\nOverheats when too much damage is sustained, releasing a shockwave that destroys nearby enemy projectiles.\nCan be placed horizontally or vertically.
block.fos-beam-mender.name = Beam Mender
block.fos-beam-mender.description = Periodically repairs blocks orthogonally in 4 directions. Conducts power.
block.fos-land-mine.name = Land Mine
block.fos-land-mine.description = Explodes violently when an enemy steps on it. Camouflaged.
block.fos-cyanium.name = Cyanium
Expand Down
15 changes: 9 additions & 6 deletions res/bundles/bundle_ru.properties
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ ability.unitresistance = Устойчивость к урону
bar.units = Боевые единицы: {0}/{1}
bar.detectorreq = Требуется детектор руды

stat.hackchance = Шанс взлома
stat.attacksbosses = [accent]может взломать стражей[]
stat.lifetime = Время жизни
stat.unitdamageres = Устойчивость на боевую единицу
stat.hackchancemultiplier = Множитель шанса взлома
stat.hackhpthreshold = Пороги прочности
stat.fos-hackchance = Шанс взлома
stat.fos-attacksbosses = [accent]может взломать стражей[]
stat.fos-lifetime = Время жизни
stat.fos-unitdamageres = Устойчивость на боевую единицу
stat.fos-hackchancemultiplier = Множитель шанса взлома
stat.fos-hackhpthreshold = Пороги прочности
stat.fos-maxbeams = Максимум лучей

unittype = [gray]Тип: []
unittype.infantry = [accent]Пехота[]
Expand Down Expand Up @@ -226,6 +227,8 @@ block.fos-judge2.description = Один из тестовых прототипо
block.fos-judge2.charge-bar = Заряд
block.fos-matrix-shield-projector.name = Матричный силовой проектор
block.fos-matrix-shield-projector.description = Создает вокруг себя прямоугольное силовое поле, защищая здания и боевые единицы внутри от повреждений.\nПерегревается, если нанесено слишком большое количество повреждений, создавая шоковую волну, уничтожающую вражеские снаряды.\nМожно поставить горизонтально или вертикально.
block.fos-beam-mender.name = Лучевой регенератор
block.fos-beam-mender.description = Периодически ремонтирует блоки ортогонально по 4 направлениям. Проводит энергию.
block.fos-land-mine.name = Наземная мина
block.fos-land-mine.description = Мощно взрывается при контакте с врагом. Камуфлированная.
block.fos-cyanium.name = Цианий
Expand Down
Binary file added res/sprites/effects/mend-laser-center.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added res/sprites/effects/mend-laser-end.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added res/sprites/effects/mend-laser.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 19 additions & 2 deletions src/fos/content/FOSBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.Block;
import mindustry.world.*;
import mindustry.world.blocks.defense.Wall;
import mindustry.world.blocks.defense.turrets.*;
import mindustry.world.blocks.distribution.*;
Expand Down Expand Up @@ -72,7 +72,7 @@ public class FOSBlocks {
// DEFENSE
tinWall, tinWallLarge, diamondWall, diamondWallLarge, vanadiumWall, vanadiumWallLarge, cuberiumWall, cuberiumWallLarge,
helix, sticker, dot, particulator, firefly, pulse, breakdown, rupture, thunder, cluster, judge, newJudge,
matrixShieldProj,
matrixShieldProj, beamMender, beamMendProjector,
landMine,

// ENVIRONMENT & ORES
Expand Down Expand Up @@ -1224,6 +1224,23 @@ diamond, new MissileBulletType(5f, 5){{
consumePower(4f);
requirements(Category.effect, with(diamond, 150, silicon, 200, vanadium, 125));
}};
beamMender = new MendBeamProjector("beam-mender"){{
scaledHealth = 180;
size = 2;
range = 7;
healPercent = 2.5f;
reload = 60f;
consumePowerDynamic((MendBeamBuild b) -> {
int beams = 0;
for (Tile[] arr : b.facing) {
for (Tile other : arr) {
if (other != null) beams++;
}
}
return beamPowerConsumption * beams;
});
requirements(Category.effect, with(tin, 50, silicon, 75, vanadium, 50));
}};

landMine = new CamoMine("land-mine"){{
tileDamage = health; //this is a one-time use mine.
Expand Down
6 changes: 4 additions & 2 deletions src/fos/content/LumoniTechTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@ public static void load() {
node(brassWirePole);
});
});
}
);
});
node(copperBattery, () ->
node(brassBattery)
);
node(beamMender, () -> {
soontm();
});
soontm();
});

Expand Down
193 changes: 193 additions & 0 deletions src/fos/type/blocks/defense/MendBeamProjector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package fos.type.blocks.defense;

import arc.Core;
import arc.graphics.Color;
import arc.graphics.g2d.*;
import arc.math.Mathf;
import arc.math.geom.*;
import arc.util.*;
import fos.type.draw.FOSStats;
import mindustry.content.Fx;
import mindustry.gen.Building;
import mindustry.graphics.*;
import mindustry.world.*;
import mindustry.world.meta.*;

import static mindustry.Vars.*;

public class MendBeamProjector extends Block {
public float beamPowerConsumption = 0.25f;
public int range = 5;
public float healPercent = 5f;
public float reload = 90f;

public float laserWidth = 0.65f;
public Color glowColor = Pal.heal;
public float glowIntensity = 0.2f, pulseIntensity = 0.07f;
public float glowScl = 3f;

public TextureRegion laser, laserEnd, laserCenter;

public MendBeamProjector(String name) {
super(name);
hasPower = true;
update = true;
conductivePower = true;
}

@Override
public void setStats() {
super.setStats();
stats.add(Stat.powerUse, beamPowerConsumption * 60f, StatUnit.powerSecond);
stats.add(FOSStats.maxBeams, size * 4);

stats.add(Stat.repairTime, (int)(100f / healPercent * reload / 60f), StatUnit.seconds);
stats.add(Stat.range, range, StatUnit.blocks);
}

@Override
public void drawPlace(int x, int y, int rotation, boolean valid) {
super.drawPlace(x, y, rotation, valid);

for (int side = 0; side < 4; side++) {
for (int i = 0; i < size; i++) {
nearbySide(x, y, side, i, Tmp.p1);

int dx = (Tmp.p1.x + Geometry.d4x(side) * (range - 1)) * tilesize, dy = (Tmp.p1.y + Geometry.d4y(side) * (range - 1)) * tilesize;
Drawf.dashLine(Pal.heal, Tmp.p1.x * tilesize, Tmp.p1.y * tilesize, dx, dy);
}
}
}

@Override
public void load() {
super.load();

laser = Core.atlas.find(name + "-beam", "fos-mend-laser");
laserEnd = Core.atlas.find(name + "-beam-end", "fos-mend-laser-end");
laserCenter = Core.atlas.find(name + "-beam-center", "fos-mend-laser-center");
}

@SuppressWarnings("unused")
public class MendBeamBuild extends Building {
public float charge = 0;
public Point2[][] lasers = new Point2[4][size];
public Tile[][] facing = new Tile[4][size];

@Override
public void draw() {
super.draw();

if (isPayload()) return;

for (int side = 0; side < 4; side++) {
Point2 dir = Geometry.d4(side);
int ddx = Geometry.d4x(side + 1), ddy = Geometry.d4y(side + 1);

for (int i = 0; i < size; i++) {
Tile face = facing[side][i];
if (face == null) continue;

Point2 p = lasers[side][i];
float lx = face.worldx() - (dir.x / 2f) * tilesize, ly = face.worldy() - (dir.y / 2f) * tilesize;

float width = (laserWidth + Mathf.absin(Time.time + i * 5 + (id % 9) * 9, glowScl, pulseIntensity)) * efficiency;

Draw.z(Layer.power - 1);
Draw.mixcol(glowColor, Mathf.absin(Time.time + i * 5 + id * 9, glowScl, glowIntensity));
if (Math.abs(p.x - face.x) + Math.abs(p.y - face.y) == 0) {
Draw.scl(width);

Draw.alpha(efficiency);
Draw.rect(laserCenter, lx, ly);

Draw.scl();
} else {
float lsx = (p.x - dir.x / 2f) * tilesize, lsy = (p.y - dir.y / 2f) * tilesize;
Draw.alpha(efficiency);
Drawf.laser(laser, laserEnd, lsx, lsy, lx, ly, width);
}

Draw.reset();
}
}
}

@Override
public void created() {
super.created();
updateLasers();
updateFacing();
}

@Override
public void onProximityUpdate() {
super.onProximityUpdate();
updateLasers();
updateFacing();
}

@Override
public void updateTile() {
boolean canHeal = !checkSuppression();

charge += edelta();

if (charge >= reload && canHeal) {
charge = 0;

updateLasers();
updateFacing();
healFacing();
}
}

@Override
public void consume() {
super.consume();
}

protected void updateLasers() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < size; j++) {
if (lasers[i][j] == null) lasers[i][j] = new Point2();
nearbySide(tileX(), tileY(), i, j, lasers[i][j]);
}
}
}

protected void updateFacing() {
for (int side = 0; side < 4; side++) {
int dx = Geometry.d4x(side), dy = Geometry.d4y(side);

for (int p = 0; p < size; p++) {
Point2 l = lasers[side][p];
Tile dest = null;
for (int i = 0; i < range; i++) {
int rx = l.x + dx * i, ry = l.y + dy * i;
Tile other = world.tile(rx, ry);
if (other != null && other.build != null && other.build.damaged()) {
dest = other;
break;
}
}

facing[side][p] = dest;
}
}
}

protected void healFacing() {
for (Tile[] arr : facing) {
for (Tile t : arr) {
if (t == null) continue;
Building other = t.build;
if (other == null || other.checkSuppression()) continue;

other.heal(t.block().health * (healPercent / 100));
Fx.healBlockFull.at(other.x, other.y, other.block.size, Pal.heal, other.block);
}
}
}
}
}
11 changes: 7 additions & 4 deletions src/fos/type/draw/FOSStats.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package fos.type.draw;

import mindustry.world.meta.Stat;
import mindustry.world.meta.*;

public class FOSStats {
public static final Stat
lifetime = new Stat("lifetime"),
unitDamageRes = new Stat("unitdamageres"),
hackChanceMultiplier = new Stat("hackchancemultiplier");
lifetime = new Stat("fos-lifetime"),
hackChanceMultiplier = new Stat("fos-hackchancemultiplier"),

unitDamageRes = new Stat("fos-unitdamageres"),

maxBeams = new Stat("fos-maxbeams", StatCat.power);
}
6 changes: 3 additions & 3 deletions src/fos/type/units/weapons/InjectorWeapon.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ public void addStats(UnitType u, Table t) {

if (bullet instanceof InjectorBulletType b) {
t.row();
t.add("[lightgray]" + Core.bundle.get("stat.hackchance") + ": [][white]" + (b.minChance() == b.maxChance() ? (Mathf.round(b.minChance() * 100) + "%")
t.add("[lightgray]" + Core.bundle.get("stat.fos-hackchance") + ": [][white]" + (b.minChance() == b.maxChance() ? (Mathf.round(b.minChance() * 100) + "%")
: (Mathf.round(b.minChance() * 100) + "~" + Mathf.round(b.maxChance() * 100) + "%")));
t.row();
t.add("[lightgray]" + Core.bundle.get("stat.hackhpthreshold") + ": [][white]" + Mathf.round(b.maxHP()) + "~" + Mathf.round(b.minHP()));
t.add("[lightgray]" + Core.bundle.get("stat.fos-hackhpthreshold") + ": [][white]" + Mathf.round(b.maxHP()) + "~" + Mathf.round(b.minHP()));

if (b.attacksGuardians()) {
t.row();
t.add("@stat.attacksbosses");
t.add("@stat.fos-attacksbosses");
}
}
}
Expand Down

0 comments on commit 6cd059d

Please sign in to comment.