T4/5 support mechs
@@ -3,6 +3,7 @@
|
|||||||
alpha=0
|
alpha=0
|
||||||
atrax=1
|
atrax=1
|
||||||
block=2
|
block=2
|
||||||
|
corvus=24
|
||||||
flare=3
|
flare=3
|
||||||
mace=4
|
mace=4
|
||||||
mega=5
|
mega=5
|
||||||
@@ -24,3 +25,4 @@ pulsar=19
|
|||||||
quad=23
|
quad=23
|
||||||
risso=20
|
risso=20
|
||||||
spiroct=21
|
spiroct=21
|
||||||
|
vela=25
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:deactivated,type:boolean,size:1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{fields:[{name:ammo,type:float,size:4},{name:armor,type:float,size:4},{name:baseRotation,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:deactivated,type:boolean,size:1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
BIN
core/assets-raw/sprites/units/corvus-cell.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
core/assets-raw/sprites/units/corvus-foot.png
Normal file
|
After Width: | Height: | Size: 720 B |
BIN
core/assets-raw/sprites/units/corvus-joint-base.png
Normal file
|
After Width: | Height: | Size: 617 B |
BIN
core/assets-raw/sprites/units/corvus-joint.png
Normal file
|
After Width: | Height: | Size: 550 B |
BIN
core/assets-raw/sprites/units/corvus-leg-base.png
Normal file
|
After Width: | Height: | Size: 350 B |
BIN
core/assets-raw/sprites/units/corvus-leg.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
core/assets-raw/sprites/units/corvus-weapon-heat.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
core/assets-raw/sprites/units/corvus.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
core/assets-raw/sprites/units/vela-base.png
Normal file
|
After Width: | Height: | Size: 600 B |
BIN
core/assets-raw/sprites/units/vela-cell.png
Normal file
|
After Width: | Height: | Size: 748 B |
BIN
core/assets-raw/sprites/units/vela-leg.png
Normal file
|
After Width: | Height: | Size: 740 B |
BIN
core/assets-raw/sprites/units/vela-weapon-heat.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
core/assets-raw/sprites/units/vela.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
@@ -316,3 +316,5 @@
|
|||||||
63428=sei|unit-sei-medium
|
63428=sei|unit-sei-medium
|
||||||
63427=quad|unit-quad-medium
|
63427=quad|unit-quad-medium
|
||||||
63426=oct|unit-oct-medium
|
63426=oct|unit-oct-medium
|
||||||
|
63425=vela|unit-vela-medium
|
||||||
|
63424=corvus|unit-corvus-medium
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 557 KiB After Width: | Height: | Size: 554 KiB |
|
Before Width: | Height: | Size: 661 KiB After Width: | Height: | Size: 664 KiB |
|
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 942 KiB |
|
Before Width: | Height: | Size: 322 KiB After Width: | Height: | Size: 506 KiB |
|
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 185 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 2.7 MiB After Width: | Height: | Size: 2.8 MiB |
|
Before Width: | Height: | Size: 187 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
@@ -1806,6 +1806,7 @@ public class Blocks implements ContentList{
|
|||||||
{UnitTypes.fortress, UnitTypes.scepter},
|
{UnitTypes.fortress, UnitTypes.scepter},
|
||||||
{UnitTypes.bryde, UnitTypes.sei},
|
{UnitTypes.bryde, UnitTypes.sei},
|
||||||
{UnitTypes.mega, UnitTypes.quad},
|
{UnitTypes.mega, UnitTypes.quad},
|
||||||
|
{UnitTypes.quasar, UnitTypes.vela},
|
||||||
};
|
};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -1825,7 +1826,8 @@ public class Blocks implements ContentList{
|
|||||||
{UnitTypes.arkyid, UnitTypes.toxopid},
|
{UnitTypes.arkyid, UnitTypes.toxopid},
|
||||||
{UnitTypes.scepter, UnitTypes.reign},
|
{UnitTypes.scepter, UnitTypes.reign},
|
||||||
{UnitTypes.sei, UnitTypes.omura},
|
{UnitTypes.sei, UnitTypes.omura},
|
||||||
{UnitTypes.quad, UnitTypes.oct}
|
{UnitTypes.quad, UnitTypes.oct},
|
||||||
|
{UnitTypes.vela, UnitTypes.corvus}
|
||||||
};
|
};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ public class Fx{
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(Vec2 p : lines){
|
for(Vec2 p : lines){
|
||||||
Fill.square(p.x, p.y, (5f - (float)i++ / lines.size * 2f) * e.fout(), 45);
|
Fill.circle(p.x, p.y, Lines.getStroke() / 2f);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@@ -290,7 +290,7 @@ public class Fx{
|
|||||||
Lines.spikes(e.x, e.y, 1f + e.fin() * 6f, e.fout() * 4f, 6);
|
Lines.spikes(e.x, e.y, 1f + e.fin() * 6f, e.fout() * 4f, 6);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
healBomb = new Effect(40f, 100f, e -> {
|
greenBomb = new Effect(40f, 100f, e -> {
|
||||||
color(Pal.heal);
|
color(Pal.heal);
|
||||||
stroke(e.fout() * 2f);
|
stroke(e.fout() * 2f);
|
||||||
Lines.circle(e.x, e.y, 4f + e.finpow() * 65f);
|
Lines.circle(e.x, e.y, 4f + e.finpow() * 65f);
|
||||||
@@ -306,6 +306,28 @@ public class Fx{
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
greenLaserCharge = new Effect(80f, 100f, e -> {
|
||||||
|
color(Pal.heal);
|
||||||
|
stroke(e.fin() * 2f);
|
||||||
|
Lines.circle(e.x, e.y, 4f + e.fout() * 100f);
|
||||||
|
|
||||||
|
Fill.circle(e.x, e.y, e.fin() * 20);
|
||||||
|
|
||||||
|
randLenVectors(e.id, 20, 40f * e.fout(), (x, y) -> {
|
||||||
|
Fill.circle(e.x + x, e.y + y, e.fin() * 5f);
|
||||||
|
});
|
||||||
|
|
||||||
|
color();
|
||||||
|
|
||||||
|
Fill.circle(e.x, e.y, e.fin() * 10);
|
||||||
|
}),
|
||||||
|
|
||||||
|
greenLaserChargeSmall = new Effect(40f, 100f, e -> {
|
||||||
|
color(Pal.heal);
|
||||||
|
stroke(e.fin() * 2f);
|
||||||
|
Lines.circle(e.x, e.y, e.fout() * 50f);
|
||||||
|
}),
|
||||||
|
|
||||||
healWaveDynamic = new Effect(22, e -> {
|
healWaveDynamic = new Effect(22, e -> {
|
||||||
color(Pal.heal);
|
color(Pal.heal);
|
||||||
stroke(e.fout() * 2f);
|
stroke(e.fout() * 2f);
|
||||||
@@ -422,6 +444,17 @@ public class Fx{
|
|||||||
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
hitMeltHeal = new Effect(12, e -> {
|
||||||
|
color(Pal.heal);
|
||||||
|
stroke(e.fout() * 2f);
|
||||||
|
|
||||||
|
randLenVectors(e.id, 6, e.finpow() * 18f, e.rotation, 360f, (x, y) -> {
|
||||||
|
float ang = Mathf.angle(x, y);
|
||||||
|
lineAngle(e.x + x, e.y + y, ang, e.fout() * 4 + 1f);
|
||||||
|
});
|
||||||
|
|
||||||
|
}),
|
||||||
|
|
||||||
hitLaser = new Effect(8, e -> {
|
hitLaser = new Effect(8, e -> {
|
||||||
color(Color.white, Pal.heal, e.fin());
|
color(Color.white, Pal.heal, e.fin());
|
||||||
stroke(0.5f + e.fout());
|
stroke(0.5f + e.fout());
|
||||||
@@ -1252,6 +1285,14 @@ public class Fx{
|
|||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
smokeCloud = new Effect(70, e -> {
|
||||||
|
randLenVectors(e.id, e.fin(), 30, 30f, (x, y, fin, fout) -> {
|
||||||
|
color(Color.gray);
|
||||||
|
alpha((0.5f - Math.abs(fin - 0.5f)) * 2f);
|
||||||
|
Fill.circle(e.x + x, e.y + y, 0.5f + fout * 4f);
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
smeltsmoke = new Effect(15, e -> {
|
smeltsmoke = new Effect(15, e -> {
|
||||||
randLenVectors(e.id, 6, 4f + e.fin() * 5f, (x, y) -> {
|
randLenVectors(e.id, 6, 4f + e.fin() * 5f, (x, y) -> {
|
||||||
color(Color.white, e.color, e.fin());
|
color(Color.white, e.color, e.fin());
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import mindustry.type.StatusEffect;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class StatusEffects implements ContentList{
|
public class StatusEffects implements ContentList{
|
||||||
public static StatusEffect none, burning, freezing, wet, muddy, melting, sapped, tarred, overdrive, overclock, shielded, shocked, blasted, corroded, boss, sporeSlowed;
|
public static StatusEffect none, burning, freezing, unmoving, slow, wet, muddy, melting, sapped, tarred, overdrive, overclock, shielded, shocked, blasted, corroded, boss, sporeSlowed;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
@@ -45,6 +45,14 @@ public class StatusEffects implements ContentList{
|
|||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
unmoving = new StatusEffect("unmoving"){{
|
||||||
|
speedMultiplier = 0.001f;
|
||||||
|
}};
|
||||||
|
|
||||||
|
slow = new StatusEffect("slow"){{
|
||||||
|
speedMultiplier = 0.4f;
|
||||||
|
}};
|
||||||
|
|
||||||
wet = new StatusEffect("wet"){{
|
wet = new StatusEffect("wet"){{
|
||||||
color = Color.royal;
|
color = Color.royal;
|
||||||
speedMultiplier = 0.94f;
|
speedMultiplier = 0.94f;
|
||||||
|
|||||||
@@ -14,12 +14,18 @@ import mindustry.type.*;
|
|||||||
public class UnitTypes implements ContentList{
|
public class UnitTypes implements ContentList{
|
||||||
//region definitions
|
//region definitions
|
||||||
|
|
||||||
//ground
|
//mech
|
||||||
public static @EntityDef({Unitc.class, Mechc.class}) UnitType mace, dagger, crawler, fortress, scepter, reign;
|
public static @EntityDef({Unitc.class, Mechc.class}) UnitType mace, dagger, crawler, fortress, scepter, reign;
|
||||||
|
|
||||||
//ground + builder + miner + commander
|
//mech + builder + miner + commander
|
||||||
public static @EntityDef({Unitc.class, Mechc.class, Builderc.class, Minerc.class, Commanderc.class}) UnitType nova, pulsar, quasar;
|
public static @EntityDef({Unitc.class, Mechc.class, Builderc.class, Minerc.class, Commanderc.class}) UnitType nova, pulsar, quasar;
|
||||||
|
|
||||||
|
//mech + commander
|
||||||
|
public static @EntityDef({Unitc.class, Mechc.class, Commanderc.class}) UnitType vela;
|
||||||
|
|
||||||
|
//legs + commander
|
||||||
|
public static @EntityDef({Unitc.class, Legsc.class, Commanderc.class}) UnitType corvus;
|
||||||
|
|
||||||
//legs
|
//legs
|
||||||
public static @EntityDef({Unitc.class, Legsc.class}) UnitType atrax;
|
public static @EntityDef({Unitc.class, Legsc.class}) UnitType atrax;
|
||||||
|
|
||||||
@@ -365,6 +371,134 @@ public class UnitTypes implements ContentList{
|
|||||||
}});
|
}});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
vela = new UnitType("vela"){{
|
||||||
|
hitsize = 23f;
|
||||||
|
|
||||||
|
rotateSpeed = 1.6f;
|
||||||
|
canDrown = false;
|
||||||
|
mechFrontSway = 1f;
|
||||||
|
|
||||||
|
mechStepParticles = true;
|
||||||
|
mechStepShake = 0.15f;
|
||||||
|
|
||||||
|
speed = 0.35f;
|
||||||
|
boostMultiplier = 1.5f;
|
||||||
|
engineOffset = 12f;
|
||||||
|
engineSize = 6f;
|
||||||
|
|
||||||
|
health = 6000f;
|
||||||
|
armor = 7f;
|
||||||
|
canBoost = true;
|
||||||
|
landShake = 4f;
|
||||||
|
|
||||||
|
commandLimit = 32;
|
||||||
|
|
||||||
|
weapons.add(new Weapon("vela-weapon"){{
|
||||||
|
mirror = false;
|
||||||
|
top = false;
|
||||||
|
shake = 4f;
|
||||||
|
shootY = 13f;
|
||||||
|
x = y = 0f;
|
||||||
|
|
||||||
|
firstShotDelay = Fx.greenLaserChargeSmall.lifetime - 1f;
|
||||||
|
|
||||||
|
reload = 320f;
|
||||||
|
recoil = 0f;
|
||||||
|
shootSound = Sounds.laser;
|
||||||
|
continuous = true;
|
||||||
|
cooldownTime = 200f;
|
||||||
|
|
||||||
|
bullet = new ContinuousLaserBulletType(16){{
|
||||||
|
length = 150f;
|
||||||
|
hitEffect = Fx.hitMeltHeal;
|
||||||
|
drawSize = 420f;
|
||||||
|
lifetime = 160f;
|
||||||
|
shake = 1f;
|
||||||
|
despawnEffect = Fx.smokeCloud;
|
||||||
|
smokeEffect = Fx.none;
|
||||||
|
|
||||||
|
shootEffect = Fx.greenLaserChargeSmall;
|
||||||
|
|
||||||
|
incendChance = 0.02f;
|
||||||
|
incendSpread = 5f;
|
||||||
|
incendAmount = 1;
|
||||||
|
|
||||||
|
colors = new Color[]{Pal.heal.cpy().a(.2f), Pal.heal.cpy().a(.5f), Pal.heal.cpy().mul(1.2f), Color.white};
|
||||||
|
}};
|
||||||
|
|
||||||
|
shootStatus = StatusEffects.slow;
|
||||||
|
shootStatusDuration = bullet.lifetime + firstShotDelay;
|
||||||
|
}});
|
||||||
|
}};
|
||||||
|
|
||||||
|
corvus = new UnitType("corvus"){{
|
||||||
|
mineTier = 1;
|
||||||
|
hitsize = 29f;
|
||||||
|
itemCapacity = 80;
|
||||||
|
health = 19000f;
|
||||||
|
buildSpeed = 1.7f;
|
||||||
|
armor = 9f;
|
||||||
|
landShake = 1.5f;
|
||||||
|
|
||||||
|
commandLimit = 24;
|
||||||
|
|
||||||
|
legCount = 4;
|
||||||
|
legLength = 14f;
|
||||||
|
legBaseOffset = 10f;
|
||||||
|
legMoveSpace = 1.5f;
|
||||||
|
legTrns = 0.58f;
|
||||||
|
hovering = true;
|
||||||
|
visualElevation = 0.2f;
|
||||||
|
allowLegStep = true;
|
||||||
|
|
||||||
|
speed = 0.3f;
|
||||||
|
|
||||||
|
mineTier = 2;
|
||||||
|
mineSpeed = 7f;
|
||||||
|
drawShields = false;
|
||||||
|
|
||||||
|
weapons.add(new Weapon("corvus-weapon"){{
|
||||||
|
top = false;
|
||||||
|
mirror = false;
|
||||||
|
shake = 14f;
|
||||||
|
shootY = 5f;
|
||||||
|
x = y = 0;
|
||||||
|
reload = 350f;
|
||||||
|
recoil = 0f;
|
||||||
|
shootSound = Sounds.laser;
|
||||||
|
|
||||||
|
cooldownTime = 350f;
|
||||||
|
|
||||||
|
shootStatusDuration = 60f * 2f;
|
||||||
|
shootStatus = StatusEffects.unmoving;
|
||||||
|
firstShotDelay = Fx.greenLaserCharge.lifetime;
|
||||||
|
|
||||||
|
bullet = new LaserBulletType(){{
|
||||||
|
length = 500f;
|
||||||
|
damage = 520f;
|
||||||
|
width = 75f;
|
||||||
|
|
||||||
|
lifetime = 65f;
|
||||||
|
|
||||||
|
lightningSpacing = 35f;
|
||||||
|
lightningLength = 5;
|
||||||
|
lightningDelay = 1.1f;
|
||||||
|
lightningLengthRand = 15;
|
||||||
|
lightningDamage = 50;
|
||||||
|
lightningAngleRand = 40f;
|
||||||
|
largeHit = true;
|
||||||
|
lightColor = lightningColor = Pal.heal;
|
||||||
|
|
||||||
|
shootEffect = Fx.greenLaserCharge;
|
||||||
|
|
||||||
|
sideAngle = 15f;
|
||||||
|
sideWidth = 0f;
|
||||||
|
sideLength = 0f;
|
||||||
|
colors = new Color[]{Pal.heal.cpy().a(0.4f), Pal.heal, Color.white};
|
||||||
|
}};
|
||||||
|
}});
|
||||||
|
}};
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
//region ground legs
|
//region ground legs
|
||||||
|
|
||||||
@@ -405,6 +539,7 @@ public class UnitTypes implements ContentList{
|
|||||||
targetAir = false;
|
targetAir = false;
|
||||||
health = 600;
|
health = 600;
|
||||||
immunities = ObjectSet.with(StatusEffects.burning, StatusEffects.melting);
|
immunities = ObjectSet.with(StatusEffects.burning, StatusEffects.melting);
|
||||||
|
|
||||||
legCount = 4;
|
legCount = 4;
|
||||||
legLength = 9f;
|
legLength = 9f;
|
||||||
legTrns = 0.6f;
|
legTrns = 0.6f;
|
||||||
@@ -603,8 +738,8 @@ public class UnitTypes implements ContentList{
|
|||||||
drag = 0.1f;
|
drag = 0.1f;
|
||||||
speed = 0.5f;
|
speed = 0.5f;
|
||||||
hitsize = 21f;
|
hitsize = 21f;
|
||||||
health = 23000;
|
health = 22000;
|
||||||
armor = 14f;
|
armor = 13f;
|
||||||
|
|
||||||
rotateSpeed = 1.9f;
|
rotateSpeed = 1.9f;
|
||||||
|
|
||||||
@@ -1121,7 +1256,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
lifetime = 70f;
|
lifetime = 70f;
|
||||||
|
|
||||||
despawnEffect = Fx.healBomb;
|
despawnEffect = Fx.greenBomb;
|
||||||
hitEffect = Fx.massiveExplosion;
|
hitEffect = Fx.massiveExplosion;
|
||||||
keepVelocity = false;
|
keepVelocity = false;
|
||||||
spin = 2f;
|
spin = 2f;
|
||||||
@@ -1139,7 +1274,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
oct = new UnitType("oct"){{
|
oct = new UnitType("oct"){{
|
||||||
armor = 16f;
|
armor = 16f;
|
||||||
health = 23000;
|
health = 24000;
|
||||||
speed = 0.6f;
|
speed = 0.6f;
|
||||||
rotateSpeed = 1f;
|
rotateSpeed = 1f;
|
||||||
accel = 0.04f;
|
accel = 0.04f;
|
||||||
@@ -1149,10 +1284,11 @@ public class UnitTypes implements ContentList{
|
|||||||
engineSize = 7.8f;
|
engineSize = 7.8f;
|
||||||
rotateShooting = false;
|
rotateShooting = false;
|
||||||
hitsize = 60f;
|
hitsize = 60f;
|
||||||
payloadCapacity = (4.5f * 4.5f) * (8 * 8);
|
payloadCapacity = (5.2f * 5.2f) * (8 * 8);
|
||||||
buildSpeed = 3.5f;
|
buildSpeed = 4f;
|
||||||
|
drawShields = false;
|
||||||
|
|
||||||
abilities.add(new ForceFieldAbility(140f, 4f, 6000f, 60f * 8), new HealFieldAbility(130f, 60f * 2, 140f));
|
abilities.add(new ForceFieldAbility(140f, 4f, 7000f, 60f * 8), new HealFieldAbility(130f, 60f * 2, 140f));
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|||||||
@@ -77,8 +77,7 @@ public class Damage{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Collides a bullet with blocks in a laser, taking into account absorption blocks. Resulting length is stored in the bullet's fdata. */
|
public static float findLaserLength(Bullet b, float length){
|
||||||
public static float collideLaser(Bullet b, float length){
|
|
||||||
Tmp.v1.trns(b.rotation(), length);
|
Tmp.v1.trns(b.rotation(), length);
|
||||||
|
|
||||||
furthest = null;
|
furthest = null;
|
||||||
@@ -86,9 +85,15 @@ public class Damage{
|
|||||||
world.raycast(b.tileX(), b.tileY(), world.toTile(b.x + Tmp.v1.x), world.toTile(b.y + Tmp.v1.y),
|
world.raycast(b.tileX(), b.tileY(), world.toTile(b.x + Tmp.v1.x), world.toTile(b.y + Tmp.v1.y),
|
||||||
(x, y) -> (furthest = world.tile(x, y)) != null && furthest.team() != b.team && furthest.block().absorbLasers);
|
(x, y) -> (furthest = world.tile(x, y)) != null && furthest.team() != b.team && furthest.block().absorbLasers);
|
||||||
|
|
||||||
float resultLength = furthest != null ? Math.max(6f, b.dst(furthest.worldx(), furthest.worldy())) : length;
|
return furthest != null ? Math.max(6f, b.dst(furthest.worldx(), furthest.worldy())) : length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Collides a bullet with blocks in a laser, taking into account absorption blocks. Resulting length is stored in the bullet's fdata. */
|
||||||
|
public static float collideLaser(Bullet b, float length, boolean large){
|
||||||
|
float resultLength = findLaserLength(b, length);
|
||||||
|
|
||||||
|
collideLine(b, b.team, b.type.hitEffect, b.x, b.y, b.rotation(), resultLength, large);
|
||||||
|
|
||||||
Damage.collideLine(b, b.team, b.type.hitEffect, b.x, b.y, b.rotation(), resultLength);
|
|
||||||
b.fdata = furthest != null ? resultLength : length;
|
b.fdata = furthest != null ? resultLength : length;
|
||||||
|
|
||||||
return resultLength;
|
return resultLength;
|
||||||
@@ -103,6 +108,8 @@ public class Damage{
|
|||||||
* Only enemies of the specified team are damaged.
|
* Only enemies of the specified team are damaged.
|
||||||
*/
|
*/
|
||||||
public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length, boolean large){
|
public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length, boolean large){
|
||||||
|
length = findLaserLength(hitter, length);
|
||||||
|
|
||||||
collidedBlocks.clear();
|
collidedBlocks.clear();
|
||||||
tr.trns(angle, length);
|
tr.trns(angle, length);
|
||||||
Intc2 collider = (cx, cy) -> {
|
Intc2 collider = (cx, cy) -> {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public abstract class BulletType extends Content{
|
|||||||
|
|
||||||
public Color lightningColor = Pal.surge;
|
public Color lightningColor = Pal.surge;
|
||||||
public int lightning;
|
public int lightning;
|
||||||
public int lightningLength = 5;
|
public int lightningLength = 5, lightningLengthRand = 0;
|
||||||
/** Use a negative value to use default bullet damage. */
|
/** Use a negative value to use default bullet damage. */
|
||||||
public float lightningDamage = -1;
|
public float lightningDamage = -1;
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ public abstract class BulletType extends Content{
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < lightning; i++){
|
for(int i = 0; i < lightning; i++){
|
||||||
Lightning.create(b, lightningColor, lightningDamage < 0 ? damage : lightningDamage, b.x, b.y, Mathf.random(360f), lightningLength);
|
Lightning.create(b, lightningColor, lightningDamage < 0 ? damage : lightningDamage, b.x, b.y, Mathf.random(360f), lightningLength + Mathf.random(lightningLengthRand));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,13 @@ import mindustry.graphics.*;
|
|||||||
public class ContinuousLaserBulletType extends BulletType{
|
public class ContinuousLaserBulletType extends BulletType{
|
||||||
public float length = 220f;
|
public float length = 220f;
|
||||||
public float shake = 1f;
|
public float shake = 1f;
|
||||||
|
public float fadeTime = 16f;
|
||||||
public Color[] colors = {Color.valueOf("ec745855"), Color.valueOf("ec7458aa"), Color.valueOf("ff9c5a"), Color.white};
|
public Color[] colors = {Color.valueOf("ec745855"), Color.valueOf("ec7458aa"), Color.valueOf("ff9c5a"), Color.white};
|
||||||
public float[] tscales = {1f, 0.7f, 0.5f, 0.2f};
|
public float[] tscales = {1f, 0.7f, 0.5f, 0.2f};
|
||||||
public float[] strokes = {2f, 1.5f, 1f, 0.3f};
|
public float[] strokes = {2f, 1.5f, 1f, 0.3f};
|
||||||
public float[] lenscales = {1f, 1.12f, 1.15f, 1.17f};
|
public float[] lenscales = {1f, 1.12f, 1.15f, 1.17f};
|
||||||
|
public float width = 9f, oscScl = 0.8f, oscMag = 1.5f;
|
||||||
|
public boolean largeHit = true;
|
||||||
|
|
||||||
public ContinuousLaserBulletType(float damage){
|
public ContinuousLaserBulletType(float damage){
|
||||||
super(0.001f, damage);
|
super(0.001f, damage);
|
||||||
@@ -25,6 +28,7 @@ public class ContinuousLaserBulletType extends BulletType{
|
|||||||
hitSize = 4;
|
hitSize = 4;
|
||||||
drawSize = 420f;
|
drawSize = 420f;
|
||||||
lifetime = 16f;
|
lifetime = 16f;
|
||||||
|
keepVelocity = false;
|
||||||
pierce = true;
|
pierce = true;
|
||||||
hittable = false;
|
hittable = false;
|
||||||
hitColor = colors[2];
|
hitColor = colors[2];
|
||||||
@@ -32,6 +36,7 @@ public class ContinuousLaserBulletType extends BulletType{
|
|||||||
incendAmount = 1;
|
incendAmount = 1;
|
||||||
incendSpread = 5;
|
incendSpread = 5;
|
||||||
incendChance = 0.4f;
|
incendChance = 0.4f;
|
||||||
|
lightColor = Color.orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ContinuousLaserBulletType(){
|
protected ContinuousLaserBulletType(){
|
||||||
@@ -43,13 +48,20 @@ public class ContinuousLaserBulletType extends BulletType{
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(){
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
drawSize = Math.max(drawSize, length*2f);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Bullet b){
|
public void update(Bullet b){
|
||||||
//TODO possible laser absorption from blocks
|
//TODO possible laser absorption from blocks
|
||||||
|
|
||||||
//damage every 5 ticks
|
//damage every 5 ticks
|
||||||
if(b.timer(1, 5f)){
|
if(b.timer(1, 5f)){
|
||||||
Damage.collideLine(b, b.team, hitEffect, b.x, b.y, b.rotation(), length, true);
|
Damage.collideLine(b, b.team, hitEffect, b.x, b.y, b.rotation(), length, largeHit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(shake > 0){
|
if(shake > 0){
|
||||||
@@ -59,21 +71,23 @@ public class ContinuousLaserBulletType extends BulletType{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Bullet b){
|
public void draw(Bullet b){
|
||||||
float baseLen = length * b.fout();
|
float realLength = Damage.findLaserLength(b, length);
|
||||||
|
float fout = Mathf.clamp(b.time > b.lifetime - fadeTime ? 1f - (b.time - (lifetime - fadeTime)) / fadeTime : 1f);
|
||||||
|
float baseLen = realLength * fout;
|
||||||
|
|
||||||
Lines.lineAngle(b.x, b.y, b.rotation(), baseLen);
|
Lines.lineAngle(b.x, b.y, b.rotation(), baseLen);
|
||||||
for(int s = 0; s < colors.length; s++){
|
for(int s = 0; s < colors.length; s++){
|
||||||
Draw.color(Tmp.c1.set(colors[s]).mul(1f + Mathf.absin(Time.time(), 1f, 0.1f)));
|
Draw.color(Tmp.c1.set(colors[s]).mul(1f + Mathf.absin(Time.time(), 1f, 0.1f)));
|
||||||
for(int i = 0; i < tscales.length; i++){
|
for(int i = 0; i < tscales.length; i++){
|
||||||
Tmp.v1.trns(b.rotation() + 180f, (lenscales[i] - 1f) * 35f);
|
Tmp.v1.trns(b.rotation() + 180f, (lenscales[i] - 1f) * 35f);
|
||||||
Lines.stroke((9f + Mathf.absin(Time.time(), 0.8f, 1.5f)) * b.fout() * strokes[s] * tscales[i]);
|
Lines.stroke((width + Mathf.absin(Time.time(), oscScl, oscMag)) * fout * strokes[s] * tscales[i]);
|
||||||
Lines.lineAngle(b.x + Tmp.v1.x, b.y + Tmp.v1.y, b.rotation(), baseLen * lenscales[i], false);
|
Lines.lineAngle(b.x + Tmp.v1.x, b.y + Tmp.v1.y, b.rotation(), baseLen * lenscales[i], false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Tmp.v1.trns(b.rotation(), baseLen * 1.1f);
|
Tmp.v1.trns(b.rotation(), baseLen * 1.1f);
|
||||||
|
|
||||||
Drawf.light(b.team, b.x, b.y, b.x + Tmp.v1.x, b.y + Tmp.v1.y, 40, Color.orange, 0.7f);
|
Drawf.light(b.team, b.x, b.y, b.x + Tmp.v1.x, b.y + Tmp.v1.y, 40, lightColor, 0.7f);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,18 +8,17 @@ import mindustry.content.*;
|
|||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.world.*;
|
|
||||||
|
|
||||||
public class LaserBulletType extends BulletType{
|
public class LaserBulletType extends BulletType{
|
||||||
protected static Tile furthest;
|
public Color[] colors = {Pal.lancerLaser.cpy().mul(1f, 1f, 1f, 0.4f), Pal.lancerLaser, Color.white};
|
||||||
|
public Effect laserEffect = Fx.lancerLaserShootSmoke;
|
||||||
protected Color[] colors = {Pal.lancerLaser.cpy().mul(1f, 1f, 1f, 0.4f), Pal.lancerLaser, Color.white};
|
public float length = 160f;
|
||||||
protected Effect laserEffect = Fx.lancerLaserShootSmoke;
|
public float width = 15f;
|
||||||
protected float length = 160f;
|
public float lengthFalloff = 0.5f;
|
||||||
protected float width = 15f;
|
public float sideLength = 29f, sideWidth = 0.7f;
|
||||||
protected float lengthFalloff = 0.5f;
|
public float sideAngle = 90f;
|
||||||
protected float sideLength = 29f, sideWidth = 0.7f;
|
public float lightningSpacing = -1, lightningDelay = 0.1f, lightningAngleRand;
|
||||||
protected float sideAngle = 90f;
|
public boolean largeHit = false;
|
||||||
|
|
||||||
public LaserBulletType(float damage){
|
public LaserBulletType(float damage){
|
||||||
super(0.01f, damage);
|
super(0.01f, damage);
|
||||||
@@ -40,6 +39,13 @@ public class LaserBulletType extends BulletType{
|
|||||||
this(1f);
|
this(1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(){
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
drawSize = Math.max(drawSize, length*2f);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float range(){
|
public float range(){
|
||||||
return length;
|
return length;
|
||||||
@@ -47,8 +53,28 @@ public class LaserBulletType extends BulletType{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Bullet b){
|
public void init(Bullet b){
|
||||||
float resultLength = Damage.collideLaser(b, length);
|
float resultLength = Damage.collideLaser(b, length, largeHit), rot = b.rotation();
|
||||||
laserEffect.at(b.x, b.y, b.rotation(), resultLength * 0.75f);
|
|
||||||
|
laserEffect.at(b.x, b.y, rot, resultLength * 0.75f);
|
||||||
|
|
||||||
|
if(lightningSpacing > 0){
|
||||||
|
int idx = 0;
|
||||||
|
for(float i = 0; i <= resultLength; i += lightningSpacing){
|
||||||
|
float cx = b.x + Angles.trnsx(rot, i),
|
||||||
|
cy = b.y + Angles.trnsy(rot, i);
|
||||||
|
|
||||||
|
int f = idx++;
|
||||||
|
|
||||||
|
for(int s : Mathf.signs){
|
||||||
|
Time.run(f * lightningDelay, () ->
|
||||||
|
Lightning.create(b, lightningColor,
|
||||||
|
lightningDamage < 0 ? damage : lightningDamage,
|
||||||
|
cx, cy, rot + 90*s + Mathf.range(lightningAngleRand),
|
||||||
|
lightningLength + Mathf.random(lightningLengthRand))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public class ShrapnelBulletType extends BulletType{
|
|||||||
public float length = 100f;
|
public float length = 100f;
|
||||||
public float width = 20f;
|
public float width = 20f;
|
||||||
public Color fromColor = Color.white, toColor = Pal.lancerLaser;
|
public Color fromColor = Color.white, toColor = Pal.lancerLaser;
|
||||||
|
public boolean hitLarge = false;
|
||||||
|
|
||||||
public int serrations = 7;
|
public int serrations = 7;
|
||||||
public float serrationLenScl = 10f, serrationWidth = 4f, serrationSpacing = 8f, serrationSpaceOffset = 80f, serrationFadeOffset = 0.5f;
|
public float serrationLenScl = 10f, serrationWidth = 4f, serrationSpacing = 8f, serrationSpaceOffset = 80f, serrationFadeOffset = 0.5f;
|
||||||
@@ -30,7 +31,14 @@ public class ShrapnelBulletType extends BulletType{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Bullet b){
|
public void init(Bullet b){
|
||||||
Damage.collideLaser(b, length);
|
Damage.collideLaser(b, length, hitLarge);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(){
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
drawSize = Math.max(drawSize, length*2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void lookAt(float angle){
|
public void lookAt(float angle){
|
||||||
rotation = Angles.moveToward(rotation, angle, type.rotateSpeed * Time.delta);
|
rotation = Angles.moveToward(rotation, angle, type.rotateSpeed * Time.delta * speedMultiplier());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void lookAt(Position pos){
|
public void lookAt(Position pos){
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import mindustry.type.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc{
|
abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
||||||
@Import float x, y, rotation, reloadMultiplier;
|
@Import float x, y, rotation, reloadMultiplier;
|
||||||
@Import Vec2 vel;
|
@Import Vec2 vel;
|
||||||
@Import UnitType type;
|
@Import UnitType type;
|
||||||
@@ -93,7 +93,27 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc{
|
|||||||
for(WeaponMount mount : mounts){
|
for(WeaponMount mount : mounts){
|
||||||
Weapon weapon = mount.weapon;
|
Weapon weapon = mount.weapon;
|
||||||
mount.reload = Math.max(mount.reload - Time.delta * reloadMultiplier, 0);
|
mount.reload = Math.max(mount.reload - Time.delta * reloadMultiplier, 0);
|
||||||
mount.heat = Math.max(mount.heat - Time.delta * reloadMultiplier / mount.weapon.cooldownTime, 0);
|
|
||||||
|
float weaponRotation = this.rotation - 90 + (weapon.rotate ? mount.rotation : 0);
|
||||||
|
float mountX = this.x + Angles.trnsx(this.rotation - 90, weapon.x, weapon.y),
|
||||||
|
mountY = this.y + Angles.trnsy(this.rotation - 90, weapon.x, weapon.y);
|
||||||
|
float shootX = mountX + Angles.trnsx(weaponRotation, weapon.shootX, weapon.shootY),
|
||||||
|
shootY = mountY + Angles.trnsy(weaponRotation, weapon.shootX, weapon.shootY);
|
||||||
|
float shootAngle = weapon.rotate ? weaponRotation + 90 : Angles.angle(shootX, shootY, mount.aimX, mount.aimY) + (this.rotation - angleTo(mount.aimX, mount.aimY));
|
||||||
|
|
||||||
|
//update continuous state
|
||||||
|
if(weapon.continuous && mount.bullet != null){
|
||||||
|
if(!mount.bullet.isAdded() || mount.bullet.time >= mount.bullet.lifetime){
|
||||||
|
mount.bullet = null;
|
||||||
|
}else{
|
||||||
|
mount.bullet.rotation(shootAngle);
|
||||||
|
mount.bullet.set(shootX, shootY);
|
||||||
|
vel.add(Tmp.v1.trns(rotation + 180f, mount.bullet.type.recoil));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//heat decreases when not firing
|
||||||
|
mount.heat = Math.max(mount.heat - Time.delta * reloadMultiplier / mount.weapon.cooldownTime, 0);
|
||||||
|
}
|
||||||
|
|
||||||
//flip weapon shoot side for alternating weapons at half reload
|
//flip weapon shoot side for alternating weapons at half reload
|
||||||
if(weapon.otherSide != -1 && weapon.alternate && mount.side == weapon.flipSprite &&
|
if(weapon.otherSide != -1 && weapon.alternate && mount.side == weapon.flipSprite &&
|
||||||
@@ -104,10 +124,10 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc{
|
|||||||
|
|
||||||
//rotate if applicable
|
//rotate if applicable
|
||||||
if(weapon.rotate && (mount.rotate || mount.shoot) && can){
|
if(weapon.rotate && (mount.rotate || mount.shoot) && can){
|
||||||
float axisX = this.x + Angles.trnsx(rotation - 90, weapon.x, weapon.y),
|
float axisX = this.x + Angles.trnsx(this.rotation - 90, weapon.x, weapon.y),
|
||||||
axisY = this.y + Angles.trnsy(rotation - 90, weapon.x, weapon.y);
|
axisY = this.y + Angles.trnsy(this.rotation - 90, weapon.x, weapon.y);
|
||||||
|
|
||||||
mount.targetRotation = Angles.angle(axisX, axisY, mount.aimX, mount.aimY) - rotation;
|
mount.targetRotation = Angles.angle(axisX, axisY, mount.aimX, mount.aimY) - this.rotation;
|
||||||
mount.rotation = Angles.moveToward(mount.rotation, mount.targetRotation, weapon.rotateSpeed * Time.delta);
|
mount.rotation = Angles.moveToward(mount.rotation, mount.targetRotation, weapon.rotateSpeed * Time.delta);
|
||||||
}else if(!weapon.rotate){
|
}else if(!weapon.rotate){
|
||||||
mount.rotation = 0;
|
mount.rotation = 0;
|
||||||
@@ -124,21 +144,9 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc{
|
|||||||
mount.reload <= 0.0001f && //reload has to be 0
|
mount.reload <= 0.0001f && //reload has to be 0
|
||||||
Angles.within(weapon.rotate ? mount.rotation : this.rotation, mount.targetRotation, mount.weapon.shootCone) //has to be within the cone
|
Angles.within(weapon.rotate ? mount.rotation : this.rotation, mount.targetRotation, mount.weapon.shootCone) //has to be within the cone
|
||||||
){
|
){
|
||||||
|
shoot(mount, shootX, shootY, mount.aimX, mount.aimY, shootAngle, Mathf.sign(weapon.x));
|
||||||
float rotation = this.rotation - 90;
|
|
||||||
float weaponRotation = rotation + (weapon.rotate ? mount.rotation : 0);
|
|
||||||
|
|
||||||
|
|
||||||
float mountX = this.x + Angles.trnsx(rotation, weapon.x, weapon.y),
|
|
||||||
mountY = this.y + Angles.trnsy(rotation, weapon.x, weapon.y);
|
|
||||||
float shootX = mountX + Angles.trnsx(weaponRotation, weapon.shootX, weapon.shootY),
|
|
||||||
shootY = mountY + Angles.trnsy(weaponRotation, weapon.shootX, weapon.shootY);
|
|
||||||
float shootAngle = weapon.rotate ? weaponRotation + 90 : Angles.angle(shootX, shootY, mount.aimX, mount.aimY) + (this.rotation - angleTo(mount.aimX, mount.aimY));
|
|
||||||
|
|
||||||
shoot(weapon, shootX, shootY, mount.aimX, mount.aimY, shootAngle, Mathf.sign(weapon.x));
|
|
||||||
|
|
||||||
mount.reload = weapon.reload;
|
mount.reload = weapon.reload;
|
||||||
mount.heat = 1f;
|
|
||||||
|
|
||||||
ammo--;
|
ammo--;
|
||||||
if(ammo < 0) ammo = 0;
|
if(ammo < 0) ammo = 0;
|
||||||
@@ -146,7 +154,8 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void shoot(Weapon weapon, float x, float y, float aimX, float aimY, float rotation, int side){
|
private void shoot(WeaponMount mount, float x, float y, float aimX, float aimY, float rotation, int side){
|
||||||
|
Weapon weapon = mount.weapon;
|
||||||
|
|
||||||
float baseX = this.x, baseY = this.y;
|
float baseX = this.x, baseY = this.y;
|
||||||
|
|
||||||
@@ -156,29 +165,39 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc{
|
|||||||
float lifeScl = ammo.scaleVelocity ? Mathf.clamp(Mathf.dst(x, y, aimX, aimY) / ammo.range()) : 1f;
|
float lifeScl = ammo.scaleVelocity ? Mathf.clamp(Mathf.dst(x, y, aimX, aimY) / ammo.range()) : 1f;
|
||||||
|
|
||||||
sequenceNum = 0;
|
sequenceNum = 0;
|
||||||
if(weapon.shotDelay > 0.01f){
|
if(weapon.shotDelay + weapon.firstShotDelay > 0.01f){
|
||||||
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> {
|
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> {
|
||||||
Time.run(sequenceNum * weapon.shotDelay, () -> bullet(weapon, x + this.x - baseX, y + this.y - baseY, f + Mathf.range(weapon.inaccuracy), lifeScl));
|
Time.run(sequenceNum * weapon.shotDelay + weapon.firstShotDelay, () -> mount.bullet = bullet(weapon, x + this.x - baseX, y + this.y - baseY, f + Mathf.range(weapon.inaccuracy), lifeScl));
|
||||||
sequenceNum++;
|
sequenceNum++;
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> bullet(weapon, x, y, f + Mathf.range(weapon.inaccuracy), lifeScl));
|
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> mount.bullet = bullet(weapon, x, y, f + Mathf.range(weapon.inaccuracy), lifeScl));
|
||||||
}
|
}
|
||||||
|
|
||||||
vel().add(Tmp.v1.trns(rotation + 180f, ammo.recoil));
|
|
||||||
|
|
||||||
boolean parentize = ammo.keepVelocity;
|
boolean parentize = ammo.keepVelocity;
|
||||||
|
|
||||||
Effect.shake(weapon.shake, weapon.shake, x, y);
|
if(weapon.firstShotDelay > 0){
|
||||||
|
Time.run(weapon.firstShotDelay, () -> {
|
||||||
|
vel.add(Tmp.v1.trns(rotation + 180f, ammo.recoil));
|
||||||
|
Effect.shake(weapon.shake, weapon.shake, x, y);
|
||||||
|
mount.heat = 1f;
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
vel.add(Tmp.v1.trns(rotation + 180f, ammo.recoil));
|
||||||
|
Effect.shake(weapon.shake, weapon.shake, x, y);
|
||||||
|
mount.heat = 1f;
|
||||||
|
}
|
||||||
|
|
||||||
weapon.ejectEffect.at(x, y, rotation * side);
|
weapon.ejectEffect.at(x, y, rotation * side);
|
||||||
ammo.shootEffect.at(x, y, rotation, parentize ? this : null);
|
ammo.shootEffect.at(x, y, rotation, parentize ? this : null);
|
||||||
ammo.smokeEffect.at(x, y, rotation, parentize ? this : null);
|
ammo.smokeEffect.at(x, y, rotation, parentize ? this : null);
|
||||||
|
apply(weapon.shootStatus, weapon.shootStatusDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bullet(Weapon weapon, float x, float y, float angle, float lifescl){
|
private Bullet bullet(Weapon weapon, float x, float y, float angle, float lifescl){
|
||||||
float xr = Mathf.range(weapon.xRand);
|
float xr = Mathf.range(weapon.xRand);
|
||||||
|
|
||||||
weapon.bullet.create(this, team(),
|
return weapon.bullet.create(this, team(),
|
||||||
x + Angles.trnsx(angle, 0, xr),
|
x + Angles.trnsx(angle, 0, xr),
|
||||||
y + Angles.trnsy(angle, 0, xr),
|
y + Angles.trnsy(angle, 0, xr),
|
||||||
angle, (1f - weapon.velocityRnd) + Mathf.random(weapon.velocityRnd), lifescl);
|
angle, (1f - weapon.velocityRnd) + Mathf.random(weapon.velocityRnd), lifescl);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package mindustry.entities.units;
|
package mindustry.entities.units;
|
||||||
|
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
|
||||||
public class WeaponMount{
|
public class WeaponMount{
|
||||||
@@ -21,6 +23,8 @@ public class WeaponMount{
|
|||||||
public boolean rotate = false;
|
public boolean rotate = false;
|
||||||
/** extra state for alternating weapons */
|
/** extra state for alternating weapons */
|
||||||
public boolean side;
|
public boolean side;
|
||||||
|
/** current bullet for continuous weapons */
|
||||||
|
public @Nullable Bullet bullet;
|
||||||
|
|
||||||
public WeaponMount(Weapon weapon){
|
public WeaponMount(Weapon weapon){
|
||||||
this.weapon = weapon;
|
this.weapon = weapon;
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
|
|
||||||
public void update(Unit unit){
|
public void update(Unit unit){
|
||||||
|
|
||||||
if(unit instanceof Mechc){
|
if(unit instanceof Mechc && !unit.isFlying()){
|
||||||
updateMechEffects(unit);
|
updateMechEffects(unit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -526,7 +526,6 @@ public class UnitType extends UnlockableContent{
|
|||||||
|
|
||||||
float rotation = unit.rotation - 90;
|
float rotation = unit.rotation - 90;
|
||||||
float weaponRotation = rotation + (weapon.rotate ? mount.rotation : 0);
|
float weaponRotation = rotation + (weapon.rotate ? mount.rotation : 0);
|
||||||
float width = weapon.region.width;
|
|
||||||
float recoil = -((mount.reload) / weapon.reload * weapon.recoil);
|
float recoil = -((mount.reload) / weapon.reload * weapon.recoil);
|
||||||
float wx = unit.x + Angles.trnsx(rotation, weapon.x, weapon.y) + Angles.trnsx(weaponRotation, 0, recoil),
|
float wx = unit.x + Angles.trnsx(rotation, weapon.x, weapon.y) + Angles.trnsx(weaponRotation, 0, recoil),
|
||||||
wy = unit.y + Angles.trnsy(rotation, weapon.x, weapon.y) + Angles.trnsy(weaponRotation, 0, recoil);
|
wy = unit.y + Angles.trnsy(rotation, weapon.x, weapon.y) + Angles.trnsy(weaponRotation, 0, recoil);
|
||||||
@@ -541,17 +540,16 @@ public class UnitType extends UnlockableContent{
|
|||||||
|
|
||||||
Draw.rect(weapon.outlineRegion,
|
Draw.rect(weapon.outlineRegion,
|
||||||
wx, wy,
|
wx, wy,
|
||||||
width * Draw.scl * -Mathf.sign(weapon.flipSprite),
|
weapon.outlineRegion.width * Draw.scl * -Mathf.sign(weapon.flipSprite),
|
||||||
weapon.region.height * Draw.scl,
|
weapon.region.height * Draw.scl,
|
||||||
weaponRotation);
|
weaponRotation);
|
||||||
|
|
||||||
|
|
||||||
Draw.z(z);
|
Draw.z(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw.rect(weapon.region,
|
Draw.rect(weapon.region,
|
||||||
wx, wy,
|
wx, wy,
|
||||||
width * Draw.scl * -Mathf.sign(weapon.flipSprite),
|
weapon.region.width * Draw.scl * -Mathf.sign(weapon.flipSprite),
|
||||||
weapon.region.height * Draw.scl,
|
weapon.region.height * Draw.scl,
|
||||||
weaponRotation);
|
weaponRotation);
|
||||||
|
|
||||||
@@ -560,8 +558,8 @@ public class UnitType extends UnlockableContent{
|
|||||||
Draw.blend(Blending.additive);
|
Draw.blend(Blending.additive);
|
||||||
Draw.rect(weapon.heatRegion,
|
Draw.rect(weapon.heatRegion,
|
||||||
wx, wy,
|
wx, wy,
|
||||||
width * Draw.scl * -Mathf.sign(weapon.flipSprite),
|
weapon.heatRegion.width * Draw.scl * -Mathf.sign(weapon.flipSprite),
|
||||||
weapon.region.height * Draw.scl,
|
weapon.heatRegion.height * Draw.scl,
|
||||||
weaponRotation);
|
weaponRotation);
|
||||||
Draw.blend();
|
Draw.blend();
|
||||||
Draw.color();
|
Draw.color();
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ public class Weapon{
|
|||||||
public boolean rotate = false;
|
public boolean rotate = false;
|
||||||
/** whether to draw the outline on top. */
|
/** whether to draw the outline on top. */
|
||||||
public boolean top = true;
|
public boolean top = true;
|
||||||
|
/** whether to hold the bullet in place while firing */
|
||||||
|
public boolean continuous;
|
||||||
/** rotation speed of weapon when rotation is enabled, in degrees/t*/
|
/** rotation speed of weapon when rotation is enabled, in degrees/t*/
|
||||||
public float rotateSpeed = 20f;
|
public float rotateSpeed = 20f;
|
||||||
/** weapon reload in frames */
|
/** weapon reload in frames */
|
||||||
@@ -54,6 +56,8 @@ public class Weapon{
|
|||||||
/** fraction of velocity that is random */
|
/** fraction of velocity that is random */
|
||||||
public float velocityRnd = 0f;
|
public float velocityRnd = 0f;
|
||||||
/** delay in ticks between shots */
|
/** delay in ticks between shots */
|
||||||
|
public float firstShotDelay = 0;
|
||||||
|
/** delay in ticks between shots */
|
||||||
public float shotDelay = 0;
|
public float shotDelay = 0;
|
||||||
/** The half-radius of the cone in which shooting will start. */
|
/** The half-radius of the cone in which shooting will start. */
|
||||||
public float shootCone = 5f;
|
public float shootCone = 5f;
|
||||||
@@ -77,6 +81,10 @@ public class Weapon{
|
|||||||
public TextureRegion outlineRegion;
|
public TextureRegion outlineRegion;
|
||||||
/** heat region tint */
|
/** heat region tint */
|
||||||
public Color heatColor = Pal.turretHeat;
|
public Color heatColor = Pal.turretHeat;
|
||||||
|
/** status effect applied when shooting */
|
||||||
|
public StatusEffect shootStatus = StatusEffects.none;
|
||||||
|
/** status effect duration when shot */
|
||||||
|
public float shootStatusDuration = 60f * 5f;
|
||||||
|
|
||||||
public Weapon(String name){
|
public Weapon(String name){
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class DatabaseDialog extends BaseDialog{
|
|||||||
for(int i = 0; i < array.size; i++){
|
for(int i = 0; i < array.size; i++){
|
||||||
UnlockableContent unlock = (UnlockableContent)array.get(i);
|
UnlockableContent unlock = (UnlockableContent)array.get(i);
|
||||||
|
|
||||||
Image image = unlocked(unlock) ? new Image(unlock.icon(Cicon.medium)).setScaling(Scaling.bounded) : new Image(Icon.lock, Pal.gray);
|
Image image = unlocked(unlock) ? new Image(unlock.icon(Cicon.medium)).setScaling(Scaling.fit) : new Image(Icon.lock, Pal.gray);
|
||||||
list.add(image).size(8*4).pad(3);
|
list.add(image).size(8*4).pad(3);
|
||||||
ClickListener listener = new ClickListener();
|
ClickListener listener = new ClickListener();
|
||||||
image.addListener(listener);
|
image.addListener(listener);
|
||||||
|
|||||||