Weapon refactor / New units with edgy names / Spritesheet cleanup

This commit is contained in:
Anuken
2019-02-03 21:11:26 -05:00
parent 62d8cb0b25
commit a8c645f00d
50 changed files with 1969 additions and 2504 deletions

View File

@@ -806,7 +806,7 @@ public class Blocks implements ContentList{
}};
surgeTower = new PowerNode("surge-tower"){{
requirements(Category.power, ItemStack.with(Items.titanium, 15, Items.lead, 20, Items.silicon, 30, Items.surgealloy, 10));
requirements(Category.power, ItemStack.with(Items.titanium, 15, Items.lead, 20, Items.silicon, 30, Items.surgealloy, 30));
size = 2;
maxNodes = 2;
laserRange = 30f;
@@ -1101,7 +1101,7 @@ public class Blocks implements ContentList{
lancer = new ChargeTurret("lancer"){{
requirements(Category.turret, ItemStack.with(Items.copper, 50, Items.lead, 100, Items.silicon, 90));
range = 90f;
range = 120f;
chargeTime = 60f;
chargeMaxDelay = 30f;
chargeEffects = 7;

View File

@@ -33,7 +33,7 @@ public class Bullets implements ContentList{
flakPlastic, flakExplosive, flakSurge,
//missiles
missileExplosive, missileIncendiary, missileSurge, missileJavelin, missileSwarm,
missileExplosive, missileIncendiary, missileSurge, missileJavelin, missileSwarm, missileRevenant,
//standard
standardCopper, standardDense, standardThorium, standardHoming, standardIncendiary, standardMechSmall,
@@ -238,6 +238,25 @@ public class Bullets implements ContentList{
weaveMag = 2f;
}};
missileRevenant = new MissileBulletType(2.7f, 12, "missile"){{
bulletWidth = 8f;
bulletHeight = 8f;
bulletShrink = 0f;
drag = -0.003f;
homingRange = 60f;
keepVelocity = false;
splashDamageRadius = 25f;
splashDamage = 10f;
lifetime = 80f;
trailColor = Palette.unitBack;
backColor = Palette.unitBack;
frontColor = Palette.unitFront;
hitEffect = Fx.blastExplosion;
despawnEffect = Fx.blastExplosion;
weaveScale = 6f;
weaveMag = 1f;
}};
standardCopper = new BasicBulletType(2.5f, 7, "bullet"){{
bulletWidth = 7f;
bulletHeight = 9f;
@@ -304,12 +323,14 @@ public class Bullets implements ContentList{
bulletWidth = 15f;
bulletHeight = 21f;
armorPierce = 0.2f;
shootEffect = Fx.shootBig;
}};
standardThoriumBig = new BasicBulletType(8f, 65, "bullet"){{
bulletWidth = 16f;
bulletHeight = 23f;
armorPierce = 0.5f;
shootEffect = Fx.shootBig;
}};
standardIncendiaryBig = new BasicBulletType(7f, 38, "bullet"){{
@@ -320,6 +341,7 @@ public class Bullets implements ContentList{
incendSpread = 3f;
incendAmount = 2;
incendChance = 0.3f;
shootEffect = Fx.shootBig;
}};
damageLightning = new BulletType(0.0001f, 0f){{
@@ -440,6 +462,11 @@ public class Bullets implements ContentList{
pierce = true;
}
@Override
public float range(){
return length;
}
@Override
public void init(Bullet b){
Damage.collideLine(b, b.getTeam(), hitEffect, b.x, b.y, b.rot(), length);

View File

@@ -1,7 +1,6 @@
package io.anuke.mindustry.content;
import io.anuke.arc.Core;
import io.anuke.mindustry.entities.Effects;
import io.anuke.arc.graphics.Blending;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
@@ -9,13 +8,15 @@ import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Rectangle;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.entities.type.Player;
import io.anuke.mindustry.entities.Effects;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.effect.Lightning;
import io.anuke.mindustry.entities.type.Player;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.type.Mech;
import io.anuke.mindustry.type.Weapon;
public class Mechs implements ContentList{
public static Mech alpha, delta, tau, omega, dart, javelin, trident, glaive;
@@ -34,9 +35,16 @@ public class Mechs implements ContentList{
mass = 1.2f;
speed = 0.5f;
boostSpeed = 0.85f;
weapon = Weapons.blaster;
trailColorTo = Color.valueOf("ffd37f");
health = 250f;
weapon = new Weapon("blaster"){{
length = 1.5f;
reload = 14f;
roundrobin = true;
ejectEffect = Fx.shellEjectSmall;
bullet = Bullets.standardMechSmall;
}};
}
@Override
@@ -57,8 +65,18 @@ public class Mechs implements ContentList{
health = 220f;
weaponOffsetX = -1;
weaponOffsetY = -1;
weapon = Weapons.shockgun;
trailColorTo = Color.valueOf("d3ddff");
weapon = new Weapon("shockgun"){{
length = 1f;
reload = 40f;
roundrobin = true;
shots = 1;
inaccuracy = 0f;
velocityRnd = 0.2f;
ejectEffect = Fx.none;
bullet = Bullets.lightning;
}};
}
@Override
@@ -91,9 +109,17 @@ public class Mechs implements ContentList{
drag = 0.35f;
boostSpeed = 0.8f;
canHeal = true;
weapon = Weapons.healBlaster;
health = 200f;
trailColorTo = Palette.heal;
weapon = new Weapon("heal-blaster"){{
length = 1.5f;
reload = 24f;
roundrobin = false;
ejectEffect = Fx.none;
recoil = 2f;
bullet = Bullets.healBullet;
}};
}
@Override
@@ -133,9 +159,20 @@ public class Mechs implements ContentList{
shake = 4f;
weaponOffsetX = 1;
weaponOffsetY = 0;
weapon = Weapons.swarmer;
trailColorTo = Color.valueOf("feb380");
health = 300f;
weapon = new Weapon("swarmer"){{
length = 1.5f;
recoil = 4f;
reload = 60f;
shots = 4;
spacing = 8f;
inaccuracy = 8f;
roundrobin = true;
ejectEffect = Fx.none;
shake = 3f;
bullet = Bullets.missileSwarm;
}};
}
@Override
@@ -189,11 +226,17 @@ public class Mechs implements ContentList{
speed = 0.4f;
drag = 0.1f;
health = 180f;
weapon = Weapons.blasterSmall;
weaponOffsetX = -1;
weaponOffsetY = -1;
trailColor = Palette.lightTrail;
cellTrnsY = 1f;
weapon = new Weapon("blaster"){{
length = 1.5f;
reload = 20f;
roundrobin = true;
ejectEffect = Fx.shellEjectSmall;
bullet = Bullets.standardCopper;
}};
}
@Override
@@ -212,9 +255,19 @@ public class Mechs implements ContentList{
drag = 0.01f;
mass = 2f;
health = 170f;
weapon = Weapons.missiles;
trailColor = Color.valueOf("d3ddff");
cellTrnsY = 1f;
weapon = new Weapon("missiles"){{
length = 1.5f;
reload = 70f;
shots = 4;
inaccuracy = 2f;
roundrobin = true;
ejectEffect = Fx.none;
velocityRnd = 0.2f;
spacing = 1f;
bullet = Bullets.missileJavelin;
}};
}
@Override
@@ -269,8 +322,19 @@ public class Mechs implements ContentList{
health = 220f;
itemCapacity = 30;
trailColor = Color.valueOf("84f491");
weapon = Weapons.bomberTrident;
cellTrnsY = 1f;
weapon = new Weapon("bomber"){{
length = 0f;
width = 2f;
reload = 8f;
shots = 2;
roundrobin = true;
ejectEffect = Fx.none;
velocityRnd = 1f;
inaccuracy = 40f;
ignoreRotation = true;
bullet = Bullets.bombExplosive;
}};
}
@Override
@@ -281,7 +345,6 @@ public class Mechs implements ContentList{
glaive = new Mech("glaive-ship", true){
{
weapon = Weapons.glaiveBlaster;
drillPower = 4;
mineSpeed = 1.3f;
speed = 0.32f;
@@ -291,6 +354,14 @@ public class Mechs implements ContentList{
itemCapacity = 60;
trailColor = Color.valueOf("feb380");
cellTrnsY = 1f;
weapon = new Weapon("bomber"){{
length = 1.5f;
reload = 13f;
roundrobin = true;
ejectEffect = Fx.shellEjectSmall;
bullet = Bullets.standardGlaive;
}};
}
};

View File

@@ -4,23 +4,34 @@ import io.anuke.arc.collection.ObjectSet;
import io.anuke.mindustry.entities.type.base.*;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.type.UnitType;
import io.anuke.mindustry.type.Weapon;
public class UnitTypes implements ContentList{
public static UnitType
spirit, phantom,
wraith, ghoul, revenant,
dagger, crawler, titan, fortress, eruptor;
wraith, ghoul, revenant, lich, reaper,
dagger, crawler, titan, fortress, eruptor, chaosArray, eradicator;
@Override
public void load(){
spirit = new UnitType("spirit", Spirit.class, Spirit::new){{
weapon = Weapons.healBlasterDrone;
isFlying = true;
drag = 0.01f;
speed = 0.2f;
maxVelocity = 0.8f;
range = 50f;
health = 60;
engineSize = 1.8f;
engineOffset = 5.7f;
weapon = new Weapon("heal-blaster"){{
length = 1.5f;
reload = 40f;
width = 0.5f;
roundrobin = true;
ejectEffect = Fx.none;
recoil = 2f;
bullet = Bullets.healBullet;
}};
}};
dagger = new UnitType("dagger", Dagger.class, Dagger::new){{
@@ -29,8 +40,14 @@ public class UnitTypes implements ContentList{
drag = 0.4f;
hitsize = 8f;
mass = 1.75f;
weapon = Weapons.chainBlaster;
health = 130;
weapon = new Weapon("chain-blaster"){{
length = 1.5f;
reload = 28f;
roundrobin = true;
ejectEffect = Fx.shellEjectSmall;
bullet = Bullets.standardCopper;
}};
}};
crawler = new UnitType("crawler", Crawler.class, Crawler::new){{
@@ -39,8 +56,12 @@ public class UnitTypes implements ContentList{
drag = 0.4f;
hitsize = 8f;
mass = 1.75f;
weapon = Weapons.suicideBomb;
health = 100;
weapon = new Weapon("bomber"){{
reload = 12f;
ejectEffect = Fx.none;
bullet = Bullets.explode;
}};
}};
titan = new UnitType("titan", Titan.class, Titan::new){{
@@ -50,9 +71,16 @@ public class UnitTypes implements ContentList{
mass = 3.5f;
hitsize = 9f;
rotatespeed = 0.1f;
weapon = Weapons.flamethrower;
health = 440;
immunities.add(StatusEffects.burning);
weapon = new Weapon("flamethrower"){{
length = 1f;
reload = 14f;
roundrobin = true;
recoil = 1f;
ejectEffect = Fx.none;
bullet = Bullets.basicFlame;
}};
}};
fortress = new UnitType("fortress", Fortress.class, Fortress::new){{
@@ -62,10 +90,17 @@ public class UnitTypes implements ContentList{
mass = 5f;
hitsize = 10f;
rotatespeed = 0.06f;
weaponOffsetX = 1;
targetAir = false;
weapon = Weapons.artillery;
health = 800;
weapon = new Weapon("artillery"){{
length = 1f;
reload = 60f;
roundrobin = true;
recoil = 5f;
shake = 2f;
ejectEffect = Fx.shellEjectMedium;
bullet = Bullets.artilleryUnit;
}};
}};
eruptor = new UnitType("eruptor", Eruptor.class, Eruptor::new){{
@@ -75,11 +110,18 @@ public class UnitTypes implements ContentList{
mass = 5f;
hitsize = 9f;
rotatespeed = 0.05f;
weaponOffsetX = 3;
targetAir = false;
weapon = Weapons.eruption;
health = 600;
immunities = ObjectSet.with(StatusEffects.burning, StatusEffects.melting);
weapon = new Weapon("eruption"){{
length = 3f;
reload = 10f;
roundrobin = true;
ejectEffect = Fx.none;
bullet = Bullets.eruptorShot;
recoil = 1f;
width = 9f;
}};
}};
wraith = new UnitType("wraith", Wraith.class, Wraith::new){{
@@ -87,9 +129,16 @@ public class UnitTypes implements ContentList{
maxVelocity = 1.9f;
drag = 0.01f;
mass = 1.5f;
weapon = Weapons.chainBlaster;
isFlying = true;
health = 70;
engineOffset = 5.5f;
weapon = new Weapon("chain-blaster"){{
length = 1.5f;
reload = 28f;
roundrobin = true;
ejectEffect = Fx.shellEjectSmall;
bullet = Bullets.standardCopper;
}};
}};
ghoul = new UnitType("ghoul", Ghoul.class, Ghoul::new){{
@@ -100,23 +149,21 @@ public class UnitTypes implements ContentList{
drag = 0.01f;
isFlying = true;
targetAir = false;
weapon = Weapons.bomber;
}};
revenant = new UnitType("revenant", Revenant.class, Revenant::new){{
health = 250;
mass = 5f;
hitsize = 12f;
speed = 0.14f;
maxVelocity = 1.3f;
drag = 0.01f;
range = 80f;
isFlying = true;
weapon = Weapons.laserBurster;
engineOffset = 7.8f;
weapon = new Weapon("bomber"){{
length = 0f;
width = 2f;
reload = 12f;
roundrobin = true;
ejectEffect = Fx.none;
velocityRnd = 1f;
inaccuracy = 40f;
ignoreRotation = true;
bullet = Bullets.bombExplosive;
}};
}};
phantom = new UnitType("phantom", Phantom.class, Phantom::new){{
weapon = Weapons.healBlasterDrone2;
isFlying = true;
drag = 0.01f;
mass = 2f;
@@ -127,7 +174,108 @@ public class UnitTypes implements ContentList{
health = 220;
buildPower = 0.9f;
minePower = 1.1f;
engineOffset = 6.5f;
toMine = ObjectSet.with(Items.lead, Items.copper, Items.titanium);
weapon = new Weapon("heal-blaster"){{
length = 1.5f;
reload = 20f;
width = 0.5f;
roundrobin = true;
ejectEffect = Fx.none;
recoil = 2f;
bullet = Bullets.healBullet;
}};
}};
revenant = new UnitType("revenant", Revenant.class, Revenant::new){{
health = 400;
mass = 5f;
hitsize = 20f;
speed = 0.1f;
maxVelocity = 1f;
drag = 0.01f;
range = 80f;
shootCone = 40f;
isFlying = true;
rotateWeapon = true;
engineOffset = 12f;
engineSize = 3f;
rotatespeed = 0.01f;
attackLength = 90f;
baseRotateSpeed = 0.06f;
weapon = new Weapon("revenant-missiles"){{
length = 3f;
reload = 70f;
width = 10f;
shots = 2;
inaccuracy = 2f;
roundrobin = true;
ejectEffect = Fx.none;
velocityRnd = 0.2f;
spacing = 1f;
bullet = Bullets.missileRevenant;
}};
}};
lich = new UnitType("lich", Revenant.class, Revenant::new){{
health = 1500;
mass = 20f;
hitsize = 40f;
speed = 0.01f;
maxVelocity = 0.6f;
drag = 0.02f;
range = 80f;
shootCone = 20f;
isFlying = true;
rotateWeapon = true;
engineOffset = 22;
engineSize = 4f;
rotatespeed = 0.01f;
attackLength = 90f;
baseRotateSpeed = 0.04f;
weapon = new Weapon("lich-missiles"){{
length = 4f;
reload = 180f;
width = 22f;
shots = 20;
shotDelay = 2;
inaccuracy = 10f;
roundrobin = true;
ejectEffect = Fx.none;
velocityRnd = 0.2f;
spacing = 1f;
bullet = Bullets.missileRevenant;
}};
}};
reaper = new UnitType("reaper", Revenant.class, Revenant::new){{
health = 3000;
mass = 30f;
hitsize = 56f;
speed = 0.01f;
maxVelocity = 0.6f;
drag = 0.02f;
range = 80f;
shootCone = 30f;
isFlying = true;
rotateWeapon = true;
engineOffset = 40;
engineSize = 6f;
rotatespeed = 0.01f;
baseRotateSpeed = 0.04f;
weapon = new Weapon("reaper-gun"){{
length = 3f;
reload = 10f;
width = 32f;
shots = 1;
shake = 1f;
inaccuracy = 3f;
roundrobin = true;
ejectEffect = Fx.none;
bullet = Bullets.standardDenseBig;
}};
}};
}
}

View File

@@ -1,198 +0,0 @@
package io.anuke.mindustry.content;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.type.Weapon;
public class Weapons implements ContentList{
public static Weapon blaster, blasterSmall, glaiveBlaster, droneBlaster, healBlaster, healBlasterDrone, chainBlaster, shockgun,
swarmer, bomber, bomberTrident, flakgun, flamethrower, missiles, artillery, laserBurster, healBlasterDrone2, suicideBomb,
eruption;
@Override
public void load(){
eruption = new Weapon("eruption"){{
length = 3f;
reload = 10f;
roundrobin = true;
ejectEffect = Fx.none;
ammo = Bullets.eruptorShot;
recoil = 1f;
width = 9f;
}};
blaster = new Weapon("blaster"){{
length = 1.5f;
reload = 14f;
roundrobin = true;
ejectEffect = Fx.shellEjectSmall;
ammo = Bullets.standardMechSmall;
}};
blasterSmall = new Weapon("blaster"){{
length = 1.5f;
reload = 20f;
roundrobin = true;
ejectEffect = Fx.shellEjectSmall;
ammo = Bullets.standardCopper;
}};
glaiveBlaster = new Weapon("bomber"){{
length = 1.5f;
reload = 13f;
roundrobin = true;
ejectEffect = Fx.shellEjectSmall;
ammo = Bullets.standardGlaive;
}};
droneBlaster = new Weapon("blaster"){{
length = 2f;
reload = 25f;
width = 1f;
roundrobin = true;
ejectEffect = Fx.shellEjectSmall;
ammo = Bullets.standardCopper;
}};
healBlaster = new Weapon("heal-blaster"){{
length = 1.5f;
reload = 24f;
roundrobin = false;
ejectEffect = Fx.none;
recoil = 2f;
ammo = Bullets.healBullet;
}};
missiles = new Weapon("missiles"){{
length = 1.5f;
reload = 70f;
shots = 4;
inaccuracy = 2f;
roundrobin = true;
ejectEffect = Fx.none;
velocityRnd = 0.2f;
spacing = 1f;
ammo = Bullets.missileJavelin;
}};
swarmer = new Weapon("swarmer"){{
length = 1.5f;
recoil = 4f;
reload = 60f;
shots = 4;
spacing = 8f;
inaccuracy = 8f;
roundrobin = true;
ejectEffect = Fx.none;
shake = 3f;
ammo = Bullets.missileSwarm;
}};
chainBlaster = new Weapon("chain-blaster"){{
length = 1.5f;
reload = 28f;
roundrobin = true;
ejectEffect = Fx.shellEjectSmall;
ammo = Bullets.standardCopper;
}};
shockgun = new Weapon("shockgun"){{
length = 1f;
reload = 40f;
roundrobin = true;
shots = 1;
inaccuracy = 0f;
velocityRnd = 0.2f;
ejectEffect = Fx.none;
ammo = Bullets.lightning;
}};
flakgun = new Weapon("flakgun"){{
length = 1f;
reload = 70f;
roundrobin = true;
shots = 1;
inaccuracy = 3f;
recoil = 3f;
velocityRnd = 0.1f;
ejectEffect = Fx.shellEjectMedium;
ammo = Bullets.artilleryDense;
}};
flamethrower = new Weapon("flamethrower"){{
length = 1f;
reload = 14f;
roundrobin = true;
recoil = 1f;
ejectEffect = Fx.none;
ammo = Bullets.basicFlame;
}};
artillery = new Weapon("artillery"){{
length = 1f;
reload = 60f;
roundrobin = true;
recoil = 5f;
shake = 2f;
ejectEffect = Fx.shellEjectMedium;
ammo = Bullets.artilleryUnit;
}};
suicideBomb = new Weapon("bomber"){{
reload = 12f;
ejectEffect = Fx.none;
ammo = Bullets.explode;
}};
bomber = new Weapon("bomber"){{
length = 0f;
width = 2f;
reload = 12f;
roundrobin = true;
ejectEffect = Fx.none;
velocityRnd = 1f;
inaccuracy = 40f;
ammo = Bullets.bombExplosive;
}};
bomberTrident = new Weapon("bomber"){{
length = 0f;
width = 2f;
reload = 8f;
shots = 2;
roundrobin = true;
ejectEffect = Fx.none;
velocityRnd = 1f;
inaccuracy = 40f;
ammo = Bullets.bombExplosive;
}};
laserBurster = new Weapon("bomber"){{
reload = 80f;
shake = 3f;
width = 0f;
roundrobin = true;
ejectEffect = Fx.none;
ammo = Bullets.lancerLaser;
}};
healBlasterDrone = new Weapon("heal-blaster"){{
length = 1.5f;
reload = 40f;
width = 0.5f;
roundrobin = true;
ejectEffect = Fx.none;
recoil = 2f;
ammo = Bullets.healBullet;
}};
healBlasterDrone2 = new Weapon("heal-blaster"){{
length = 1.5f;
reload = 20f;
width = 0.5f;
roundrobin = true;
ejectEffect = Fx.none;
recoil = 2f;
ammo = Bullets.healBullet;
}};
}
}

View File

@@ -46,7 +46,6 @@ public class ContentLoader{
new StatusEffects(),
new Liquids(),
new Bullets(),
new Weapons(),
new Mechs(),
new UnitTypes(),
new Blocks(),

View File

@@ -165,7 +165,7 @@ public class Damage{
entity.damage(amount);
//TODO better velocity displacement
float dst = tr.set(entity.x - x, entity.y - y).len();
entity.velocity().add(tr.setLength((1f - dst / radius) * 2f));
entity.velocity().add(tr.setLength((1f - dst / radius) * 2f / entity.mass()));
};
rect.setSize(radius * 2).setCenter(x, y);

View File

@@ -48,7 +48,7 @@ public class Units{
/**See {@link #invalidateTarget(TargetTrait, Team, float, float, float)}*/
public static boolean invalidateTarget(TargetTrait target, Unit targeter){
return invalidateTarget(target, targeter.getTeam(), targeter.x, targeter.y, targeter.getWeapon().getAmmo().range());
return invalidateTarget(target, targeter.getTeam(), targeter.x, targeter.y, targeter.getWeapon().bullet.range());
}
/**Returns whether there are any entities on this tile.*/

View File

@@ -1,14 +1,13 @@
package io.anuke.mindustry.entities.bullet;
import io.anuke.arc.Core;
import io.anuke.mindustry.entities.Effects;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.entities.Damage;
import io.anuke.mindustry.entities.Effects;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.effect.Lightning;
import io.anuke.mindustry.entities.traits.TargetTrait;
@@ -72,7 +71,7 @@ public class BasicBulletType extends BulletType{
if(homingPower > 0.0001f){
TargetTrait target = Units.getClosestTarget(b.getTeam(), b.x, b.y, homingRange);
if(target != null){
b.velocity().setAngle(Angles.moveToward(b.velocity().angle(), b.angleTo(target), homingPower * Time.delta()));
b.velocity().setAngle(Mathf.slerpDelta(b.velocity().angle(), b.angleTo(target), 0.08f));
}
}
}

View File

@@ -131,7 +131,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
}
public void targetClosest(){
target = Units.getClosestTarget(team, x, y, Math.max(getWeapon().getAmmo().range(), type.range), u -> type.targetAir || !u.isFlying());
target = Units.getClosestTarget(team, x, y, Math.max(getWeapon().bullet.range(), type.range), u -> type.targetAir || !u.isFlying());
}
public TileEntity getClosestEnemyCore(){
@@ -284,7 +284,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
@Override
public float drawSize(){
return 14;
return type.hitsize * 10;
}
@Override

View File

@@ -1,15 +1,19 @@
package io.anuke.mindustry.entities.type;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.Tmp;
import io.anuke.mindustry.entities.Predict;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.bullet.BulletType;
import io.anuke.mindustry.entities.units.UnitState;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.world.Tile;
@@ -18,7 +22,7 @@ import io.anuke.mindustry.world.meta.BlockFlag;
import static io.anuke.mindustry.Vars.world;
public abstract class FlyingUnit extends BaseUnit{
protected static Vector2 vec = new Vector2();
protected float[] weaponAngles = {0, 0};
protected final UnitState
@@ -52,6 +56,7 @@ public abstract class FlyingUnit extends BaseUnit{
}
if(target == null){
retarget(() -> {
targetClosest();
@@ -69,15 +74,27 @@ public abstract class FlyingUnit extends BaseUnit{
}
});
}else{
attack(150f);
attack(type.attackLength);
if((Angles.near(angleTo(target), rotation, 15f) || !getWeapon().getAmmo().keepVelocity) //bombers don't care about rotation
&& dst(target) < Math.max(getWeapon().getAmmo().range(), type.range)){
BulletType ammo = getWeapon().getAmmo();
if((Angles.near(angleTo(target), rotation, type.shootCone) || getWeapon().ignoreRotation) //bombers and such don't care about rotation
&& dst(target) < Math.max(getWeapon().bullet.range(), type.range)){
BulletType ammo = getWeapon().bullet;
Vector2 to = Predict.intercept(FlyingUnit.this, target, ammo.speed);
if(type.rotateWeapon){
for(boolean left : Mathf.booleans){
int wi = Mathf.num(left);
float wx = x + Angles.trnsx(rotation - 90, getWeapon().width * Mathf.sign(left));
float wy = y + Angles.trnsy(rotation - 90, getWeapon().width * Mathf.sign(left));
getWeapon().update(FlyingUnit.this, to.x, to.y);
weaponAngles[wi] = Mathf.slerpDelta(weaponAngles[wi], Angles.angle(wx, wy, target.getX(), target.getY()), 0.1f);
Tmp.v2.trns(weaponAngles[wi], getWeapon().length);
getWeapon().update(FlyingUnit.this, wx + Tmp.v2.x, wy + Tmp.v2.y, weaponAngles[wi], left);
}
}else{
Vector2 to = Predict.intercept(FlyingUnit.this, target, ammo.speed);
getWeapon().update(FlyingUnit.this, to.x, to.y);
}
}
}
}
@@ -133,19 +150,46 @@ public abstract class FlyingUnit extends BaseUnit{
}
}
@Override
public void drawUnder(){
drawEngine();
}
@Override
public void draw(){
Draw.alpha(Draw.getShader() != Shaders.mix ? 1f : hitTime / hitDuration);
Draw.rect(type.region, x, y, rotation - 90);
Draw.rect(type.name, x, y, rotation - 90);
drawWeapons();
drawItems();
Draw.alpha(1f);
}
public void drawWeapons(){
}
public void drawEngine(){
Draw.color(Palette.engine);
Fill.circle(x + Angles.trnsx(rotation + 180, type.engineOffset), y + Angles.trnsy(rotation + 180, type.engineOffset),
type.engineSize + Mathf.absin(Time.time(), 2f, type.engineSize/4f));
Draw.color(Color.WHITE);
Fill.circle(x + Angles.trnsx(rotation + 180, type.engineOffset-1f), y + Angles.trnsy(rotation + 180, type.engineOffset-1f),
(type.engineSize + Mathf.absin(Time.time(), 2f, type.engineSize/4f)) / 2f);
Draw.color();
}
@Override
public void behavior(){
if(Units.invalidateTarget(target, this)){
for(boolean left : Mathf.booleans){
int wi = Mathf.num(left);
weaponAngles[wi] = Mathf.slerpDelta(weaponAngles[wi],rotation, 0.1f);
}
}
if(health <= health * type.retreatPercent &&
Geometry.findClosest(x, y, world.indexer.getAllied(team, BlockFlag.repair)) != null){
setState(retreat);
@@ -157,19 +201,14 @@ public abstract class FlyingUnit extends BaseUnit{
return attack;
}
@Override
public float drawSize(){
return 60;
}
protected void wobble(){
if(Net.client()) return;
x += Mathf.sin(Time.time() + id * 999, 25f, 0.08f)*Time.delta();
y += Mathf.cos(Time.time() + id * 999, 25f, 0.08f)*Time.delta();
x += Mathf.sin(Time.time() + id * 999, 25f, 0.05f)*Time.delta();
y += Mathf.cos(Time.time() + id * 999, 25f, 0.05f)*Time.delta();
if(velocity.len() <= 0.05f){
rotation += Mathf.sin(Time.time() + id * 99, 10f, 2.5f)*Time.delta();
//rotation += Mathf.sin(Time.time() + id * 99, 10f, 2f * type.speed)*Time.delta();
}
}
@@ -184,44 +223,48 @@ public abstract class FlyingUnit extends BaseUnit{
protected void circle(float circleLength, float speed){
if(target == null) return;
vec.set(target.getX() - x, target.getY() - y);
Tmp.v1.set(target.getX() - x, target.getY() - y);
if(vec.len() < circleLength){
vec.rotate((circleLength - vec.len()) / circleLength * 180f);
if(Tmp.v1.len() < circleLength){
Tmp.v1.rotate((circleLength - Tmp.v1.len()) / circleLength * 180f);
}
vec.setLength(speed * Time.delta());
Tmp.v1.setLength(speed * Time.delta());
velocity.add(vec);
velocity.add(Tmp.v1);
}
protected void moveTo(float circleLength){
if(target == null) return;
vec.set(target.getX() - x, target.getY() - y);
Tmp.v1.set(target.getX() - x, target.getY() - y);
float length = circleLength <= 0.001f ? 1f : Mathf.clamp((dst(target) - circleLength) / 100f, -1f, 1f);
vec.setLength(type.speed * Time.delta() * length);
if(length < 0) vec.rotate(180f);
Tmp.v1.setLength(type.speed * Time.delta() * length);
if(length < -0.5f){
Tmp.v1.rotate(180f);
}else if(length < 0){
Tmp.v1.setZero();
}
velocity.add(vec);
velocity.add(Tmp.v1);
}
protected void attack(float circleLength){
vec.set(target.getX() - x, target.getY() - y);
Tmp.v1.set(target.getX() - x, target.getY() - y);
float ang = angleTo(target);
float diff = Angles.angleDist(ang, rotation);
if(diff > 100f && vec.len() < circleLength){
vec.setAngle(velocity.angle());
if(diff > 100f && Tmp.v1.len() < circleLength){
Tmp.v1.setAngle(velocity.angle());
}else{
vec.setAngle(Mathf.slerpDelta(velocity.angle(), vec.angle(), 0.44f));
Tmp.v1.setAngle(Mathf.slerpDelta(velocity.angle(), Tmp.v1.angle(), 0.44f));
}
vec.setLength(type.speed * Time.delta());
Tmp.v1.setLength(type.speed * Time.delta());
velocity.add(vec);
velocity.add(Tmp.v1);
}
}

View File

@@ -11,19 +11,12 @@ import io.anuke.mindustry.entities.Predict;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.bullet.BulletType;
import io.anuke.mindustry.entities.units.UnitState;
import io.anuke.mindustry.type.UnitType;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import static io.anuke.mindustry.Vars.content;
import static io.anuke.mindustry.Vars.world;
public abstract class GroundUnit extends BaseUnit{
@@ -32,7 +25,6 @@ public abstract class GroundUnit extends BaseUnit{
protected float walkTime;
protected float stuckTime;
protected float baseRotation;
protected Weapon weapon;
public final UnitState
@@ -45,11 +37,11 @@ public abstract class GroundUnit extends BaseUnit{
TileEntity core = getClosestEnemyCore();
float dst = core == null ? 0 : dst(core);
if(core != null && dst < getWeapon().getAmmo().range() / 1.1f){
if(core != null && dst < getWeapon().bullet.range() / 1.1f){
target = core;
}
if(dst > getWeapon().getAmmo().range() * 0.5f){
if(dst > getWeapon().bullet.range() * 0.5f){
moveToCore();
}
}
@@ -80,12 +72,6 @@ public abstract class GroundUnit extends BaseUnit{
}
};
@Override
public void init(UnitType type, Team team){
super.init(type, team);
this.weapon = type.weapon;
}
@Override
public void interpolate(){
super.interpolate();
@@ -125,11 +111,7 @@ public abstract class GroundUnit extends BaseUnit{
@Override
public Weapon getWeapon(){
return weapon;
}
public void setWeapon(Weapon weapon){
this.weapon = weapon;
return type.weapon;
}
@Override
@@ -162,11 +144,11 @@ public abstract class GroundUnit extends BaseUnit{
Draw.rect(type.region, x, y, rotation - 90);
for(int i : Mathf.signs){
float tra = rotation - 90, trY = -weapon.getRecoil(this, i > 0) + type.weaponOffsetY;
float tra = rotation - 90, trY = -type.weapon.getRecoil(this, i > 0) + type.weaponOffsetY;
float w = i > 0 ? -12 : 12;
Draw.rect(weapon.equipRegion,
x + Angles.trnsx(tra, type.weaponOffsetX * i, trY),
y + Angles.trnsy(tra, type.weaponOffsetX * i, trY), w, 12, rotation - 90);
Draw.rect(type.weapon.equipRegion,
x + Angles.trnsx(tra, getWeapon().width * i, trY),
y + Angles.trnsy(tra, getWeapon().width * i, trY), w, 12, rotation - 90);
}
drawItems();
@@ -181,11 +163,11 @@ public abstract class GroundUnit extends BaseUnit{
}
if(!Units.invalidateTarget(target, this)){
if(dst(target) < getWeapon().getAmmo().range()){
if(dst(target) < getWeapon().bullet.range()){
rotate(angleTo(target));
if(Angles.near(angleTo(target), rotation, 13f)){
BulletType ammo = getWeapon().getAmmo();
BulletType ammo = getWeapon().bullet;
Vector2 to = Predict.intercept(GroundUnit.this, target, ammo.speed);
@@ -206,30 +188,6 @@ public abstract class GroundUnit extends BaseUnit{
retarget(this::targetClosest);
}
@Override
public void write(DataOutput data) throws IOException{
super.write(data);
data.writeByte(weapon.id);
}
@Override
public void read(DataInput data) throws IOException{
super.read(data);
weapon = content.getByID(ContentType.weapon, data.readByte());
}
@Override
public void writeSave(DataOutput stream) throws IOException{
stream.writeByte(weapon.id);
super.writeSave(stream);
}
@Override
public void readSave(DataInput stream) throws IOException{
weapon = content.getByID(ContentType.weapon, stream.readByte());
super.readSave(stream);
}
protected void patrol(){
vec.trns(baseRotation, type.speed * Time.delta());
velocity.add(vec.x, vec.y);

View File

@@ -370,6 +370,20 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
drawBuilding();
}
@Override
public void drawUnder(){
float size = mech.engineSize * (mech.flying ? 1f : boostHeat);
Draw.color(mech.trailColorTo);
Fill.circle(x + Angles.trnsx(rotation + 180, mech.engineOffset), y + Angles.trnsy(rotation + 180, mech.engineOffset),
size + Mathf.absin(Time.time(), 2f, size/4f));
Draw.color(Color.WHITE);
Fill.circle(x + Angles.trnsx(rotation + 180, mech.engineOffset-1f), y + Angles.trnsy(rotation + 180, mech.engineOffset-1f),
(size + Mathf.absin(Time.time(), 2f, size/4f)) / 2f);
Draw.color();
}
public void drawName(){
BitmapFont font = Core.scene.skin.getFont("default-font");
GlyphLayout layout = Pools.obtain(GlyphLayout.class, GlyphLayout::new);
@@ -603,7 +617,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
protected void updateFlying(){
if(Units.invalidateTarget(target, this) && !(target instanceof TileEntity && ((TileEntity) target).damaged() && target.getTeam() == team &&
mech.canHeal && dst(target) < getWeapon().getAmmo().range())){
mech.canHeal && dst(target) < getWeapon().bullet.range())){
target = null;
}
@@ -675,11 +689,11 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
if(target == null){
isShooting = false;
if(Core.settings.getBool("autotarget")){
target = Units.getClosestTarget(team, x, y, getWeapon().getAmmo().range());
target = Units.getClosestTarget(team, x, y, getWeapon().bullet.range());
if(mech.canHeal && target == null){
target = Geometry.findClosest(x, y, world.indexer.getDamaged(Team.blue));
if(target != null && dst(target) > getWeapon().getAmmo().range()){
if(target != null && dst(target) > getWeapon().bullet.range()){
target = null;
}else if(target != null){
target = ((Tile) target).entity;
@@ -691,14 +705,14 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
}
}
}else if(target.isValid() || (target instanceof TileEntity && ((TileEntity) target).damaged() && target.getTeam() == team &&
mech.canHeal && dst(target) < getWeapon().getAmmo().range())){
mech.canHeal && dst(target) < getWeapon().bullet.range())){
//rotate toward and shoot the target
if(mech.turnCursor){
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f);
}
Vector2 intercept =
Predict.intercept(x, y, target.getX(), target.getY(), target.velocity().x - velocity.x, target.velocity().y - velocity.y, getWeapon().getAmmo().speed);
Predict.intercept(x, y, target.getX(), target.getY(), target.velocity().x - velocity.x, target.velocity().y - velocity.y, getWeapon().bullet.speed);
pointerX = intercept.x;
pointerY = intercept.y;

View File

@@ -1,7 +1,35 @@
package io.anuke.mindustry.entities.type.base;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.type.FlyingUnit;
public class Revenant extends FlyingUnit{
@Override
public void drawWeapons(){
for(int i : Mathf.signs){
float tra = rotation - 90, trY = -getWeapon().getRecoil(this, i > 0) + type.weaponOffsetY;
float w = i > 0 ? -12 : 12;
float wx = x + Angles.trnsx(tra, getWeapon().width * i, trY), wy = y + Angles.trnsy(tra, getWeapon().width * i, trY);
int wi = (i + 1)/2;
Draw.rect(getWeapon().equipRegion, wx, wy, w, 12, weaponAngles[wi] - 90);
}
}
@Override
protected void attack(float circleLength){
moveTo(circleLength);
}
@Override
protected void updateRotation(){
if(!Units.invalidateTarget(target, this)){
rotation = Mathf.slerpDelta(rotation, angleTo(target), type.rotatespeed);
}else{
rotation = Mathf.slerpDelta(rotation, velocity.angle(), type.baseRotateSpeed);
}
}
}

View File

@@ -1,11 +1,9 @@
package io.anuke.mindustry.game;
import io.anuke.mindustry.entities.type.BaseUnit;
import io.anuke.mindustry.entities.type.GroundUnit;
import io.anuke.mindustry.type.UnitType;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.StatusEffect;
import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.type.UnitType;
/**
* A spawn group defines spawn information for a specific type of unit, with optional extra information like
@@ -27,8 +25,6 @@ public class SpawnGroup{
protected float unitScaling = 9999f;
/**Amount of enemies spawned initially, with no scaling*/
protected int unitAmount = 1;
/**Weapon used by the spawned unit. Null to disable. Only applicable to ground units.*/
protected Weapon weapon;
/**Status effect applied to the spawned unit. Null to disable.*/
protected StatusEffect effect;
/**Items this unit spawns with. Null to disable.*/
@@ -57,10 +53,6 @@ public class SpawnGroup{
public BaseUnit createUnit(Team team){
BaseUnit unit = type.create(team);
if(unit instanceof GroundUnit && weapon != null){
((GroundUnit) unit).setWeapon(weapon);
}
if(effect != null){
unit.applyEffect(effect, 999999f);
}
@@ -82,7 +74,6 @@ public class SpawnGroup{
", max=" + max +
", unitScaling=" + unitScaling +
", unitAmount=" + unitAmount +
", weapon=" + weapon +
", effect=" + effect +
", items=" + items +
'}';

View File

@@ -4,7 +4,6 @@ import io.anuke.arc.collection.Array;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.content.UnitTypes;
import io.anuke.mindustry.content.Weapons;
import io.anuke.mindustry.type.ItemStack;
public class Waves{
@@ -50,7 +49,6 @@ public class Waves{
begin = 28;
spacing = 3;
unitScaling = 2;
weapon = Weapons.flamethrower;
end = 40;
}},
@@ -58,7 +56,6 @@ public class Waves{
begin = 45;
spacing = 3;
unitScaling = 2;
weapon = Weapons.flamethrower;
effect = StatusEffects.overdrive;
}},
@@ -67,7 +64,6 @@ public class Waves{
spacing = 2;
unitScaling = 3;
unitAmount = 5;
weapon = Weapons.flakgun;
effect = StatusEffects.overdrive;
}},
@@ -181,10 +177,6 @@ public class Waves{
if(a > 0){
System.out.print(a + "x" + spawn.type.name);
if(spawn.weapon != null){
System.out.print(":" + spawn.weapon.name);
}
System.out.print(" ");
}
}

View File

@@ -37,6 +37,7 @@ public class Palette{
lancerLaser = Color.valueOf("a9d8ff"),
stoneGray = Color.valueOf("8f8f8f"),
engine = Color.valueOf("ffbb64"),
health = Color.valueOf("ff341c"),
heal = Color.valueOf("98ffa9"),
@@ -54,6 +55,9 @@ public class Palette{
powerLight = Color.valueOf("fbd367"),
placing = accent,
unitFront = Color.valueOf("ffa665"),
unitBack = Color.valueOf("d06b53"),
lightTrail = Color.valueOf("ffe2a9"),
surge = Color.valueOf("f3e979"),

View File

@@ -209,16 +209,6 @@ public class TypeIO{
return new Color(buffer.getInt());
}
@WriteClass(Weapon.class)
public static void writeWeapon(ByteBuffer buffer, Weapon weapon){
buffer.put(weapon.id);
}
@ReadClass(Weapon.class)
public static Weapon readWeapon(ByteBuffer buffer){
return content.getByID(ContentType.weapon, buffer.get());
}
@WriteClass(Mech.class)
public static void writeMech(ByteBuffer buffer, Mech mech){
buffer.put(mech.id);

View File

@@ -7,7 +7,6 @@ public enum ContentType {
mech,
bullet,
liquid,
weapon,
status,
unit,
weather,

View File

@@ -4,7 +4,6 @@ import io.anuke.arc.Core;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.mindustry.content.Weapons;
import io.anuke.mindustry.entities.type.Player;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.graphics.Palette;
@@ -34,8 +33,8 @@ public class Mech extends UnlockableContent{
public boolean turnCursor = true;
public boolean canHeal = false;
public float weaponOffsetX, weaponOffsetY;
public Weapon weapon = Weapons.blaster;
public float weaponOffsetX, weaponOffsetY, engineOffset = 6f, engineSize = 2f;
public Weapon weapon;
public TextureRegion baseRegion, legRegion, region, iconRegion;
@@ -91,6 +90,7 @@ public class Mech extends UnlockableContent{
@Override
public void load(){
weapon.load();
if(!flying){
legRegion = Core.atlas.find(name + "-leg");
baseRegion = Core.atlas.find(name + "-base");

View File

@@ -8,7 +8,6 @@ import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.util.Log;
import io.anuke.arc.util.Strings;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.Weapons;
import io.anuke.mindustry.entities.traits.TypeTrait;
import io.anuke.mindustry.entities.type.BaseUnit;
import io.anuke.mindustry.game.Team;
@@ -24,20 +23,22 @@ public class UnitType extends UnlockableContent{
public float hitsize = 7f;
public float hitsizeTile = 4f;
public float speed = 0.4f;
public float range = 0;
public float range = 0, attackLength = 150f;
public float rotatespeed = 0.2f;
public float baseRotateSpeed = 0.1f;
public float shootCone = 15f;
public float mass = 1f;
public boolean isFlying;
public boolean targetAir = true;
public boolean rotateWeapon = false;
public float drag = 0.1f;
public float maxVelocity = 5f;
public float retreatPercent = 0.2f;
public int itemCapacity = 30;
public ObjectSet<Item> toMine = ObjectSet.with(Items.lead, Items.copper);
public float buildPower = 0.3f, minePower = 0.7f;
public Weapon weapon = Weapons.blaster;
public float weaponOffsetX, weaponOffsetY;
public Weapon weapon;
public float weaponOffsetY, engineOffset = 6f, engineSize = 2f;
public ObjectSet<StatusEffect> immunities = new ObjectSet<>();
public TextureRegion iconRegion, legRegion, baseRegion, region;
@@ -72,7 +73,8 @@ public class UnitType extends UnlockableContent{
@Override
public void load(){
iconRegion = Core.atlas.find("unit-icon-" + name);
weapon.load();
iconRegion = Core.atlas.find("unit-icon-" + name, Core.atlas.find(name));
region = Core.atlas.find(name);
if(!isFlying){

View File

@@ -3,60 +3,70 @@ package io.anuke.mindustry.type;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.Core;
import io.anuke.mindustry.entities.Effects;
import io.anuke.mindustry.entities.Effects.Effect;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.Tmp;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.entities.type.Player;
import io.anuke.mindustry.entities.Effects;
import io.anuke.mindustry.entities.Effects.Effect;
import io.anuke.mindustry.entities.bullet.Bullet;
import io.anuke.mindustry.entities.bullet.BulletType;
import io.anuke.mindustry.entities.traits.ShooterTrait;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.entities.type.Player;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.net.Net;
public class Weapon extends Content{
public class Weapon{
public final String name;
/**minimum cursor distance from player, fixes 'cross-eyed' shooting.*/
protected static float minPlayerDist = 20f;
/**ammo type map. set with setAmmo()*/
protected BulletType ammo;
protected static int sequenceNum = 0;
/**bullet shot*/
public BulletType bullet;
/**shell ejection effect*/
protected Effect ejectEffect = Fx.none;
public Effect ejectEffect = Fx.none;
/**weapon reload in frames*/
protected float reload;
public float reload;
/**amount of shots per fire*/
protected int shots = 1;
public int shots = 1;
/**spacing in degrees between multiple shots, if applicable*/
protected float spacing = 12f;
public float spacing = 12f;
/**inaccuracy of degrees of each shot*/
protected float inaccuracy = 0f;
public float inaccuracy = 0f;
/**intensity and duration of each shot's screen shake*/
protected float shake = 0f;
public float shake = 0f;
/**visual weapon knockback.*/
protected float recoil = 1.5f;
public float recoil = 1.5f;
/**shoot barrel y offset*/
protected float length = 3f;
public float length = 3f;
/**shoot barrel x offset.*/
protected float width = 4f;
public float width = 4f;
/**fraction of velocity that is random*/
protected float velocityRnd = 0f;
public float velocityRnd = 0f;
/**whether to shoot the weapons in different arms one after another, rather than all at once*/
protected boolean roundrobin = false;
/**vector for vector calulations*/
protected Vector2 tr = new Vector2();
public boolean roundrobin = false;
/**randomization of shot length*/
public float lengthRand = 0f;
/**delay in ticks between shots*/
public float shotDelay = 0;
/**whether shooter rotation is ignored when shooting.*/
public boolean ignoreRotation = false;
public TextureRegion equipRegion, region;
public TextureRegion equipRegion;
protected Weapon(String name){
this.name = name;
}
protected Weapon(){
//no region
this.name = "";
}
@Remote(targets = Loc.server, called = Loc.both, unreliable = true)
public static void onPlayerShootWeapon(Player player, float x, float y, float rotation, boolean left){
if(player == null) return;
@@ -81,59 +91,58 @@ public class Weapon extends Content{
Weapon weapon = shooter.getWeapon();
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> weapon.bullet(shooter, x, y, f + Mathf.range(weapon.inaccuracy)));
BulletType ammo = weapon.ammo;
sequenceNum = 0;
if(weapon.shotDelay > 0.01f){
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> {
Time.run(sequenceNum * weapon.shotDelay, () -> weapon.bullet(shooter, x, y, f + Mathf.range(weapon.inaccuracy)));
sequenceNum ++;
});
}else{
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> weapon.bullet(shooter, x, y, f + Mathf.range(weapon.inaccuracy)));
}
weapon.tr.trns(rotation + 180f, ammo.recoil);
BulletType ammo = weapon.bullet;
shooter.velocity().add(weapon.tr);
Tmp.v1.trns(rotation + 180f, ammo.recoil);
weapon.tr.trns(rotation, 3f);
shooter.velocity().add(Tmp.v1);
Tmp.v1.trns(rotation, 3f);
Effects.shake(weapon.shake, weapon.shake, x, y);
Effects.effect(weapon.ejectEffect, x, y, rotation * -Mathf.sign(left));
Effects.effect(ammo.shootEffect, x + weapon.tr.x, y + weapon.tr.y, rotation, shooter);
Effects.effect(ammo.smokeEffect, x + weapon.tr.x, y + weapon.tr.y, rotation, shooter);
Effects.effect(ammo.shootEffect, x + Tmp.v1.x, y + Tmp.v1.y, rotation, shooter);
Effects.effect(ammo.smokeEffect, x + Tmp.v1.x, y + Tmp.v1.y, rotation, shooter);
//reset timer for remote players
shooter.getTimer().get(shooter.getShootTimer(left), weapon.reload);
}
@Override
public void load(){
equipRegion = Core.atlas.find(name + "-equip");
region = Core.atlas.find(name);
}
@Override
public ContentType getContentType(){
return ContentType.weapon;
}
public BulletType getAmmo(){
return ammo;
equipRegion = Core.atlas.find(name + "-equip", Core.atlas.find("clear"));
}
public void update(ShooterTrait shooter, float pointerX, float pointerY){
update(shooter, true, pointerX, pointerY);
update(shooter, false, pointerX, pointerY);
for(boolean left : Mathf.booleans){
Tmp.v1.set(pointerX, pointerY).sub(shooter.getX(), shooter.getY());
if(Tmp.v1.len() < minPlayerDist) Tmp.v1.setLength(minPlayerDist);
float cx = Tmp.v1.x + shooter.getX(), cy = Tmp.v1.y + shooter.getY();
float ang = Tmp.v1.angle();
Tmp.v1.trns(ang - 90, width * Mathf.sign(left), length + Mathf.range(lengthRand));
update(shooter, shooter.getX() + Tmp.v1.x, shooter.getY() + Tmp.v1.y, Angles.angle(shooter.getX() + Tmp.v1.x, shooter.getY() + Tmp.v1.y, cx, cy), left);
}
}
private void update(ShooterTrait shooter, boolean left, float pointerX, float pointerY){
public void update(ShooterTrait shooter, float mountX, float mountY, float angle, boolean left){
if(shooter.getTimer().get(shooter.getShootTimer(left), reload)){
if(roundrobin){
shooter.getTimer().reset(shooter.getShootTimer(!left), reload / 2f);
}
tr.set(pointerX, pointerY).sub(shooter.getX(), shooter.getY());
if(tr.len() < minPlayerDist) tr.setLength(minPlayerDist);
float cx = tr.x + shooter.getX(), cy = tr.y + shooter.getY();
float ang = tr.angle();
tr.trns(ang - 90, width * Mathf.sign(left), length);
shoot(shooter, tr.x, tr.y, Angles.angle(shooter.getX() + tr.x, shooter.getY() + tr.y, cx, cy), left);
shoot(shooter, mountX - shooter.getX(), mountY - shooter.getY(), angle, left);
}
}
@@ -141,14 +150,6 @@ public class Weapon extends Content{
return (1f - Mathf.clamp(player.getTimer().getTime(player.getShootTimer(left)) / reload)) * recoil;
}
public float getRecoil(){
return recoil;
}
public float getReload(){
return reload;
}
public void shoot(ShooterTrait p, float x, float y, float angle, boolean left){
if(Net.client()){
//call it directly, don't invoke on server
@@ -165,8 +166,8 @@ public class Weapon extends Content{
void bullet(ShooterTrait owner, float x, float y, float angle){
if(owner == null) return;
tr.trns(angle, 3f);
Bullet.create(ammo,
owner, owner.getTeam(), x + tr.x, y + tr.y, angle, (1f - velocityRnd) + Mathf.random(velocityRnd));
Tmp.v1.trns(angle, 3f);
Bullet.create(bullet,
owner, owner.getTeam(), x + Tmp.v1.x, y + Tmp.v1.y, angle, (1f - velocityRnd) + Mathf.random(velocityRnd));
}
}

View File

@@ -508,7 +508,7 @@ public class Block extends BlockStorage{
public TextureRegion icon(Icon icon){
if(icons[icon.ordinal()] == null){
icons[icon.ordinal()] = Core.atlas.find(name + "-icon-" + icon.name(), icon == Icon.full ? getGeneratedIcons()[0] : Core.atlas.find("__error"));
icons[icon.ordinal()] = Core.atlas.find(name + "-icon-" + icon.name(), icon == Icon.full ? getGeneratedIcons()[0] : Core.atlas.find(name + "-icon-full"));
}
return icons[icon.ordinal()];
}

View File

@@ -33,9 +33,9 @@ public abstract class BlockStorage extends UnlockableContent{
public float liquidCapacity = 10f;
public float liquidFlowFactor = 4.9f;
public BlockStats stats = new BlockStats();
public Consumers consumes = new Consumers();
public Producers produces = new Producers();
public final BlockStats stats = new BlockStats();
public final Consumers consumes = new Consumers();
public final Producers produces = new Producers();
public boolean shouldConsume(Tile tile){
return true;

View File

@@ -64,7 +64,6 @@ public abstract class Turret extends Block{
protected TextureRegion baseRegion;
protected TextureRegion heatRegion;
protected TextureRegion baseTopRegion;
protected BiConsumer<Tile, TurretEntity> drawer = (tile, entity) ->
Draw.rect(region, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90);
@@ -97,7 +96,6 @@ public abstract class Turret extends Block{
super.load();
baseRegion = Core.atlas.find("block-" + size);
baseTopRegion = Core.atlas.find("block-" + size + "-top");
heatRegion = Core.atlas.find(name + "-heat");
}