Evoke repair weapon
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
BIN
core/assets-raw/sprites/blocks/units/ship-assembler-in.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
core/assets-raw/sprites/blocks/units/ship-assembler-side1.png
Normal file
|
After Width: | Height: | Size: 770 B |
BIN
core/assets-raw/sprites/blocks/units/ship-assembler-side2.png
Normal file
|
After Width: | Height: | Size: 772 B |
BIN
core/assets-raw/sprites/blocks/units/ship-assembler-top.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
core/assets-raw/sprites/blocks/units/ship-assembler.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
@@ -837,7 +837,8 @@ bullet.buildingdamage = [stat]{0}%[lightgray] building damage
|
|||||||
bullet.knockback = [stat]{0}[lightgray] knockback
|
bullet.knockback = [stat]{0}[lightgray] knockback
|
||||||
bullet.pierce = [stat]{0}[lightgray]x pierce
|
bullet.pierce = [stat]{0}[lightgray]x pierce
|
||||||
bullet.infinitepierce = [stat]pierce
|
bullet.infinitepierce = [stat]pierce
|
||||||
bullet.healpercent = [stat]{0}[lightgray]% healing
|
bullet.healpercent = [stat]{0}[lightgray]% repair
|
||||||
|
bullet.healamount = [stat]{0}[lightgray] direct repair
|
||||||
bullet.multiplier = [stat]{0}[lightgray]x ammo multiplier
|
bullet.multiplier = [stat]{0}[lightgray]x ammo multiplier
|
||||||
bullet.reload = [stat]{0}[lightgray]x fire rate
|
bullet.reload = [stat]{0}[lightgray]x fire rate
|
||||||
bullet.range = [stat]{0}[lightgray] tiles range
|
bullet.range = [stat]{0}[lightgray] tiles range
|
||||||
|
|||||||
@@ -492,3 +492,4 @@
|
|||||||
63212=quell|unit-quell-ui
|
63212=quell|unit-quell-ui
|
||||||
63211=breach|block-breach-ui
|
63211=breach|block-breach-ui
|
||||||
63210=eruption-drill|block-eruption-drill-ui
|
63210=eruption-drill|block-eruption-drill-ui
|
||||||
|
63209=ship-assembler|block-ship-assembler-ui
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ public class Blocks{
|
|||||||
|
|
||||||
//unit - erekir
|
//unit - erekir
|
||||||
tankAssembler,
|
tankAssembler,
|
||||||
|
shipAssembler,
|
||||||
basicAssemblerModule,
|
basicAssemblerModule,
|
||||||
|
|
||||||
//payloads
|
//payloads
|
||||||
@@ -3264,15 +3265,25 @@ public class Blocks{
|
|||||||
tankAssembler = new UnitAssembler("tank-assembler"){{
|
tankAssembler = new UnitAssembler("tank-assembler"){{
|
||||||
requirements(Category.units, with(Items.graphite, 10));
|
requirements(Category.units, with(Items.graphite, 10));
|
||||||
size = 5;
|
size = 5;
|
||||||
droneType = UnitTypes.manifold;
|
plans.add(new AssemblerUnitPlan(UnitTypes.vanquish, 60f * 10f, BlockStack.list(Blocks.thoriumWallLarge, 4, Blocks.duct, 2)));
|
||||||
plans.add(new AssemblerUnitPlan(UnitTypes.vanquish, 60f * 5f, BlockStack.list(Blocks.thoriumWallLarge, 4, Blocks.duct, 2)));
|
consumes.power(2f);
|
||||||
|
areaSize = 13;
|
||||||
|
|
||||||
|
//TODO unit production is rarely continuous, can be double
|
||||||
|
consumes.liquid(Liquids.gallium, 1f / 60f);
|
||||||
|
}};
|
||||||
|
|
||||||
|
//TODO requirements
|
||||||
|
shipAssembler = new UnitAssembler("ship-assembler"){{
|
||||||
|
requirements(Category.units, with(Items.graphite, 10));
|
||||||
|
size = 5;
|
||||||
|
plans.add(new AssemblerUnitPlan(UnitTypes.quell, 60f * 4f, BlockStack.list(Blocks.thoriumWallLarge, 4, Blocks.duct, 2)));
|
||||||
consumes.power(2f);
|
consumes.power(2f);
|
||||||
areaSize = 13;
|
areaSize = 13;
|
||||||
|
|
||||||
//TODO unit production is rarely continuous, can be double
|
//TODO unit production is rarely continuous, can be double
|
||||||
consumes.liquid(Liquids.gallium, 1f / 60f);
|
consumes.liquid(Liquids.gallium, 1f / 60f);
|
||||||
|
|
||||||
droneType = UnitTypes.assemblyDrone;
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
basicAssemblerModule = new UnitAssemblerModule("basic-assembler-module"){{
|
basicAssemblerModule = new UnitAssemblerModule("basic-assembler-module"){{
|
||||||
|
|||||||
@@ -752,6 +752,14 @@ public class Fx{
|
|||||||
Drawf.light(e.x, e.y, 23f, Pal.heal, e.fout() * 0.7f);
|
Drawf.light(e.x, e.y, 23f, Pal.heal, e.fout() * 0.7f);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
hitLaserColor = new Effect(8, e -> {
|
||||||
|
color(Color.white, e.color, e.fin());
|
||||||
|
stroke(0.5f + e.fout());
|
||||||
|
Lines.circle(e.x, e.y, e.fin() * 5f);
|
||||||
|
|
||||||
|
Drawf.light(e.x, e.y, 23f, e.color, e.fout() * 0.7f);
|
||||||
|
}),
|
||||||
|
|
||||||
hitYellowLaser = new Effect(8, e -> {
|
hitYellowLaser = new Effect(8, e -> {
|
||||||
color(Color.white, Pal.lightTrail, e.fin());
|
color(Color.white, Pal.lightTrail, e.fin());
|
||||||
stroke(0.5f + e.fout());
|
stroke(0.5f + e.fout());
|
||||||
|
|||||||
@@ -2563,7 +2563,6 @@ public class UnitTypes{
|
|||||||
outlineColor = Pal.darkOutline;
|
outlineColor = Pal.darkOutline;
|
||||||
lowAltitude = false;
|
lowAltitude = false;
|
||||||
flying = true;
|
flying = true;
|
||||||
targetAir = false;
|
|
||||||
mineSpeed = 6.5f;
|
mineSpeed = 6.5f;
|
||||||
mineTier = 1;
|
mineTier = 1;
|
||||||
buildSpeed = 0.8f;
|
buildSpeed = 0.8f;
|
||||||
@@ -2584,32 +2583,31 @@ public class UnitTypes{
|
|||||||
);
|
);
|
||||||
|
|
||||||
weapons.add(new Weapon(){{
|
weapons.add(new Weapon(){{
|
||||||
reload = 55f;
|
reload = 17f;
|
||||||
x = 0f;
|
x = 0f;
|
||||||
y = 1f;
|
y = 1f;
|
||||||
top = false;
|
top = false;
|
||||||
mirror = false;
|
mirror = false;
|
||||||
|
|
||||||
bullet = new ArtilleryBulletType(3f, 11){{
|
bullet = new LaserBoltBulletType(){{
|
||||||
trailLength = 8;
|
speed = 4.2f;
|
||||||
trailWidth = 2.4f;
|
frontColor = Color.white;
|
||||||
collidesTiles = true;
|
backColor = hitColor = trailColor = Pal.accent;
|
||||||
collides = true;
|
|
||||||
trailEffect = Fx.none;
|
|
||||||
trailColor = Pal.bulletYellowBack;
|
|
||||||
homingPower = 0.01f;
|
|
||||||
splashDamage = 10;
|
|
||||||
splashDamageRadius = 20f;
|
|
||||||
weaveMag = 2f;
|
|
||||||
weaveScale = 4f;
|
|
||||||
width = 10f;
|
|
||||||
height = 13f;
|
|
||||||
|
|
||||||
lifetime = 50f;
|
height = 6f;
|
||||||
hitEffect = Fx.blastExplosion;
|
trailLength = 5;
|
||||||
shootEffect = Fx.shootBig;
|
trailWidth = 2f;
|
||||||
smokeEffect = Fx.shootBigSmoke;
|
|
||||||
buildingDamageMultiplier = 0.4f;
|
healColor = Pal.accent;
|
||||||
|
healPercent = 1f;
|
||||||
|
healAmount = 25f;
|
||||||
|
collidesTeam = true;
|
||||||
|
|
||||||
|
lifetime = 35f;
|
||||||
|
shootEffect = Fx.colorSpark;
|
||||||
|
hitEffect = smokeEffect = despawnEffect = Fx.hitLaserColor;
|
||||||
|
|
||||||
|
damage = 10;
|
||||||
}};
|
}};
|
||||||
}});
|
}});
|
||||||
}};
|
}};
|
||||||
|
|||||||
@@ -118,6 +118,8 @@ public class BulletType extends Content implements Cloneable{
|
|||||||
public float rangeChange = 0f;
|
public float rangeChange = 0f;
|
||||||
/** % of block health healed **/
|
/** % of block health healed **/
|
||||||
public float healPercent = 0f;
|
public float healPercent = 0f;
|
||||||
|
/** flat amount of block health healed */
|
||||||
|
public float healAmount = 0f;
|
||||||
/** Whether to make fire on impact */
|
/** Whether to make fire on impact */
|
||||||
public boolean makeFire = false;
|
public boolean makeFire = false;
|
||||||
/** Whether to create hit effects on despawn. Forced to true if this bullet has any special effects like splash damage. */
|
/** Whether to create hit effects on despawn. Forced to true if this bullet has any special effects like splash damage. */
|
||||||
@@ -131,6 +133,7 @@ public class BulletType extends Content implements Cloneable{
|
|||||||
public float fragVelocityMin = 0.2f, fragVelocityMax = 1f, fragLifeMin = 1f, fragLifeMax = 1f;
|
public float fragVelocityMin = 0.2f, fragVelocityMax = 1f, fragLifeMin = 1f, fragLifeMax = 1f;
|
||||||
public @Nullable BulletType fragBullet = null;
|
public @Nullable BulletType fragBullet = null;
|
||||||
public Color hitColor = Color.white;
|
public Color hitColor = Color.white;
|
||||||
|
public Color healColor = Pal.heal;
|
||||||
|
|
||||||
public Color trailColor = Pal.missileYellowBack;
|
public Color trailColor = Pal.missileYellowBack;
|
||||||
public float trailChance = -0.0001f;
|
public float trailChance = -0.0001f;
|
||||||
@@ -218,8 +221,12 @@ public class BulletType extends Content implements Cloneable{
|
|||||||
return -1f;
|
return -1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean heals(){
|
||||||
|
return healPercent > 0 || healAmount > 0;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean testCollision(Bullet bullet, Building tile){
|
public boolean testCollision(Bullet bullet, Building tile){
|
||||||
return healPercent <= 0.001f || tile.team != bullet.team || tile.healthf() < 1f;
|
return !heals() || tile.team != bullet.team || tile.healthf() < 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If direct is false, this is an indirect hit and the tile was already damaged.
|
/** If direct is false, this is an indirect hit and the tile was already damaged.
|
||||||
@@ -229,9 +236,9 @@ public class BulletType extends Content implements Cloneable{
|
|||||||
Fires.create(build.tile);
|
Fires.create(build.tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(healPercent > 0f && build.team == b.team && !(build.block instanceof ConstructBlock)){
|
if(heals()&& build.team == b.team && !(build.block instanceof ConstructBlock)){
|
||||||
Fx.healBlockFull.at(build.x, build.y, build.block.size, Pal.heal);
|
Fx.healBlockFull.at(build.x, build.y, build.block.size, healColor);
|
||||||
build.heal(healPercent / 100f * build.maxHealth);
|
build.heal(healPercent / 100f * build.maxHealth + healAmount);
|
||||||
}else if(build.team != b.team && direct){
|
}else if(build.team != b.team && direct){
|
||||||
hit(b);
|
hit(b);
|
||||||
}
|
}
|
||||||
@@ -291,10 +298,10 @@ public class BulletType extends Content implements Cloneable{
|
|||||||
Damage.status(b.team, x, y, splashDamageRadius, status, statusDuration, collidesAir, collidesGround);
|
Damage.status(b.team, x, y, splashDamageRadius, status, statusDuration, collidesAir, collidesGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(healPercent > 0f){
|
if(heals()){
|
||||||
indexer.eachBlock(b.team, x, y, splashDamageRadius, Building::damaged, other -> {
|
indexer.eachBlock(b.team, x, y, splashDamageRadius, Building::damaged, other -> {
|
||||||
Fx.healBlockFull.at(other.x, other.y, other.block.size, Pal.heal);
|
Fx.healBlockFull.at(other.x, other.y, other.block.size, healColor);
|
||||||
other.heal(healPercent / 100f * other.maxHealth());
|
other.heal(healPercent / 100f * other.maxHealth() + healAmount);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,7 +369,7 @@ public class BulletType extends Content implements Cloneable{
|
|||||||
if(homingPower > 0.0001f && b.time >= homingDelay){
|
if(homingPower > 0.0001f && b.time >= homingDelay){
|
||||||
Teamc target;
|
Teamc target;
|
||||||
//home in on allies if possible
|
//home in on allies if possible
|
||||||
if(healPercent > 0){
|
if(heals()){
|
||||||
target = Units.closestTarget(null, b.x, b.y, homingRange,
|
target = Units.closestTarget(null, b.x, b.y, homingRange,
|
||||||
e -> e.checkTarget(collidesAir, collidesGround) && e.team != b.team && !b.hasCollided(e.id),
|
e -> e.checkTarget(collidesAir, collidesGround) && e.team != b.team && !b.hasCollided(e.id),
|
||||||
t -> collidesGround && (t.team != b.team || t.damaged()) && !b.hasCollided(t.id)
|
t -> collidesGround && (t.team != b.team || t.damaged()) && !b.hasCollided(t.id)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class EmpBulletType extends BasicBulletType{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(other.block.hasPower && other.damaged()){
|
if(other.block.hasPower && other.damaged()){
|
||||||
other.heal(healPercent / 100f * other.maxHealth());
|
other.heal(healPercent / 100f * other.maxHealth() + healAmount);
|
||||||
Fx.healBlockFull.at(other.x, other.y, other.block.size, hitColor);
|
Fx.healBlockFull.at(other.x, other.y, other.block.size, hitColor);
|
||||||
applyEffect.at(other, other.block.size * 7f);
|
applyEffect.at(other, other.block.size * 7f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -454,7 +454,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
}).layer(Layer.debris);
|
}).layer(Layer.debris);
|
||||||
}
|
}
|
||||||
|
|
||||||
canHeal = weapons.contains(w -> w.bullet.healPercent > 0f);
|
canHeal = weapons.contains(w -> w.bullet.heals());
|
||||||
|
|
||||||
//add mirrored weapon variants
|
//add mirrored weapon variants
|
||||||
Seq<Weapon> mapped = new Seq<>();
|
Seq<Weapon> mapped = new Seq<>();
|
||||||
|
|||||||
@@ -412,7 +412,7 @@ public class Turret extends ReloadTurret{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean canHeal(){
|
protected boolean canHeal(){
|
||||||
return targetHealing && hasAmmo() && peekAmmo().collidesTeam && peekAmmo().healPercent > 0;
|
return targetHealing && hasAmmo() && peekAmmo().collidesTeam && peekAmmo().heals();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void findTarget(){
|
protected void findTarget(){
|
||||||
|
|||||||
@@ -329,6 +329,10 @@ public class StatValues{
|
|||||||
sep(bt, Core.bundle.format("bullet.healpercent", Strings.autoFixed(type.healPercent, 2)));
|
sep(bt, Core.bundle.format("bullet.healpercent", Strings.autoFixed(type.healPercent, 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(type.healAmount > 0f){
|
||||||
|
sep(bt, Core.bundle.format("bullet.healamount", Strings.autoFixed(type.healAmount, 2)));
|
||||||
|
}
|
||||||
|
|
||||||
if(type.pierce || type.pierceCap != -1){
|
if(type.pierce || type.pierceCap != -1){
|
||||||
sep(bt, type.pierceCap == -1 ? "@bullet.infinitepierce" : Core.bundle.format("bullet.pierce", type.pierceCap));
|
sep(bt, type.pierceCap == -1 ? "@bullet.infinitepierce" : Core.bundle.format("bullet.pierce", type.pierceCap));
|
||||||
}
|
}
|
||||||
|
|||||||