Gradual component conversion
@@ -8,8 +8,9 @@ public class Annotations{
|
|||||||
/** Indicates multiple inheritance on a component type. */
|
/** Indicates multiple inheritance on a component type. */
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface Depends{
|
public @interface Component{
|
||||||
Class[] value();
|
/** Dependencies. */
|
||||||
|
Class[] value() default {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Indicates that a component def is present on all entities. */
|
/** Indicates that a component def is present on all entities. */
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//add all components w/ dependencies
|
//add all components w/ dependencies
|
||||||
allComponents.addAll(types(Depends.class).map(s -> Array.withArrays(getDependencies(s), s)).flatten());
|
allComponents.addAll(types(Component.class).map(s -> Array.withArrays(getDependencies(s), s)).flatten());
|
||||||
|
|
||||||
//add component imports
|
//add component imports
|
||||||
for(Stype comp : allComponents){
|
for(Stype comp : allComponents){
|
||||||
@@ -77,6 +77,9 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
|
|
||||||
//add utility methods to interface
|
//add utility methods to interface
|
||||||
for(Smethod method : component.methods()){
|
for(Smethod method : component.methods()){
|
||||||
|
//skip private methods, those are for internal use.
|
||||||
|
if(method.is(Modifier.PRIVATE)) continue;
|
||||||
|
|
||||||
inter.addMethod(MethodSpec.methodBuilder(method.name())
|
inter.addMethod(MethodSpec.methodBuilder(method.name())
|
||||||
.addExceptions(method.thrownt())
|
.addExceptions(method.thrownt())
|
||||||
.addTypeVariables(method.typeVariables().map(TypeVariableName::get))
|
.addTypeVariables(method.typeVariables().map(TypeVariableName::get))
|
||||||
@@ -107,6 +110,11 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
for(Svar f : fields){
|
for(Svar f : fields){
|
||||||
VariableTree tree = f.tree();
|
VariableTree tree = f.tree();
|
||||||
FieldSpec.Builder fbuilder = FieldSpec.builder(f.tname(), f.name());
|
FieldSpec.Builder fbuilder = FieldSpec.builder(f.tname(), f.name());
|
||||||
|
//keep statics/finals
|
||||||
|
if(f.is(Modifier.STATIC)){
|
||||||
|
fbuilder.addModifiers(Modifier.STATIC);
|
||||||
|
if(f.is(Modifier.FINAL)) fbuilder.addModifiers(Modifier.FINAL);
|
||||||
|
}
|
||||||
//add initializer if it exists
|
//add initializer if it exists
|
||||||
if(tree.getInitializer() != null){
|
if(tree.getInitializer() != null){
|
||||||
fbuilder.initializer(tree.getInitializer().toString());
|
fbuilder.initializer(tree.getInitializer().toString());
|
||||||
@@ -125,7 +133,7 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
//representative method
|
//representative method
|
||||||
Smethod first = entry.value.first();
|
Smethod first = entry.value.first();
|
||||||
//build method using same params/returns
|
//build method using same params/returns
|
||||||
MethodSpec.Builder mbuilder = MethodSpec.methodBuilder(first.name()).addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
MethodSpec.Builder mbuilder = MethodSpec.methodBuilder(first.name()).addModifiers(first.is(Modifier.PRIVATE) ? Modifier.PRIVATE : Modifier.PUBLIC, Modifier.FINAL);
|
||||||
mbuilder.addTypeVariables(first.typeVariables().map(TypeVariableName::get));
|
mbuilder.addTypeVariables(first.typeVariables().map(TypeVariableName::get));
|
||||||
mbuilder.returns(first.retn());
|
mbuilder.returns(first.retn());
|
||||||
mbuilder.addExceptions(first.thrownt());
|
mbuilder.addExceptions(first.thrownt());
|
||||||
@@ -191,6 +199,11 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
for(Stype comp : components){
|
for(Stype comp : components){
|
||||||
//implement the interface
|
//implement the interface
|
||||||
Stype inter = interfaces.find(i -> i.name().equals(interfaceName(comp)));
|
Stype inter = interfaces.find(i -> i.name().equals(interfaceName(comp)));
|
||||||
|
if(inter == null){
|
||||||
|
err("Failed to generate interface for component. Interfaces are " + interfaces + "\nComponent", comp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
def.builder.addSuperinterface(inter.tname());
|
def.builder.addSuperinterface(inter.tname());
|
||||||
|
|
||||||
//generate getter/setter for each method
|
//generate getter/setter for each method
|
||||||
@@ -251,9 +264,9 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
out.addAll(component.superclasses());
|
out.addAll(component.superclasses());
|
||||||
|
|
||||||
//get dependency classes
|
//get dependency classes
|
||||||
if(component.annotation(Depends.class) != null){
|
if(component.annotation(Component.class) != null){
|
||||||
try{
|
try{
|
||||||
component.annotation(Depends.class).value();
|
component.annotation(Component.class).value();
|
||||||
}catch(MirroredTypesException e){
|
}catch(MirroredTypesException e){
|
||||||
out.addAll(Array.with(e.getTypeMirrors()).map(Stype::of));
|
out.addAll(Array.with(e.getTypeMirrors()).map(Stype::of));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,8 +146,12 @@ public class RemoteWriteGenerator{
|
|||||||
|
|
||||||
VariableElement var = elem.getParameters().get(i);
|
VariableElement var = elem.getParameters().get(i);
|
||||||
|
|
||||||
//add parameter to method
|
try{
|
||||||
method.addParameter(TypeName.get(var.asType()), var.getSimpleName().toString());
|
//add parameter to method
|
||||||
|
method.addParameter(TypeName.get(var.asType()), var.getSimpleName().toString());
|
||||||
|
}catch(Throwable t){
|
||||||
|
throw new RuntimeException("Error parsing method " + methodEntry.targetMethod);
|
||||||
|
}
|
||||||
|
|
||||||
//name of parameter
|
//name of parameter
|
||||||
String varName = var.getSimpleName().toString();
|
String varName = var.getSimpleName().toString();
|
||||||
|
|||||||
BIN
core/assets-raw/sprites/blocks/mechs/alpha-mech-pad.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 180 B After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 164 B After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
BIN
core/assets-raw/sprites/mechs/ships/vanguard-ship.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 6.8 KiB |
BIN
core/assets-raw/sprites/weapons/vanguard-blaster-equip.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
@@ -974,7 +974,8 @@ block.pneumatic-drill.name = Pneumatic Drill
|
|||||||
block.laser-drill.name = Laser Drill
|
block.laser-drill.name = Laser Drill
|
||||||
block.water-extractor.name = Water Extractor
|
block.water-extractor.name = Water Extractor
|
||||||
block.cultivator.name = Cultivator
|
block.cultivator.name = Cultivator
|
||||||
block.dart-mech-pad.name = Alpha Mech Pad
|
block.dart-ship-pad.name = Dart Ship Pad
|
||||||
|
block.alpha-mech-pad.name = Alpha Mech Pad
|
||||||
block.delta-mech-pad.name = Delta Mech Pad
|
block.delta-mech-pad.name = Delta Mech Pad
|
||||||
block.javelin-ship-pad.name = Javelin Ship Pad
|
block.javelin-ship-pad.name = Javelin Ship Pad
|
||||||
block.trident-ship-pad.name = Trident Ship Pad
|
block.trident-ship-pad.name = Trident Ship Pad
|
||||||
@@ -1249,7 +1250,6 @@ block.crawler-factory.description = Produces fast self-destructing swarm units.
|
|||||||
block.titan-factory.description = Produces advanced, armored ground units.
|
block.titan-factory.description = Produces advanced, armored ground units.
|
||||||
block.fortress-factory.description = Produces heavy artillery ground units.
|
block.fortress-factory.description = Produces heavy artillery ground units.
|
||||||
block.repair-point.description = Continuously heals the closest damaged unit in its vicinity.
|
block.repair-point.description = Continuously heals the closest damaged unit in its vicinity.
|
||||||
block.dart-mech-pad.description = Provides transformation into a basic attack mech.\nUse by tapping while standing on it.
|
|
||||||
block.delta-mech-pad.description = Provides transformation into a lightly armored hit-and-run attack mech.\nUse by tapping while standing on it.
|
block.delta-mech-pad.description = Provides transformation into a lightly armored hit-and-run attack mech.\nUse by tapping while standing on it.
|
||||||
block.tau-mech-pad.description = Provides transformation into an advanced support mech.\nUse by tapping while standing on it.
|
block.tau-mech-pad.description = Provides transformation into an advanced support mech.\nUse by tapping while standing on it.
|
||||||
block.omega-mech-pad.description = Provides transformation into a heavily-armored missile mech.\nUse by tapping while standing on it.
|
block.omega-mech-pad.description = Provides transformation into a heavily-armored missile mech.\nUse by tapping while standing on it.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import arc.math.geom.*;
|
|||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
|
import mindustry.entities.traits.*;
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
@@ -25,6 +26,7 @@ public class BlockIndexer{
|
|||||||
|
|
||||||
/** Set of all ores that are being scanned. */
|
/** Set of all ores that are being scanned. */
|
||||||
private final ObjectSet<Item> scanOres = new ObjectSet<>();
|
private final ObjectSet<Item> scanOres = new ObjectSet<>();
|
||||||
|
private final IntSet intSet = new IntSet();
|
||||||
private final ObjectSet<Item> itemSet = new ObjectSet<>();
|
private final ObjectSet<Item> itemSet = new ObjectSet<>();
|
||||||
/** Stores all ore quadtrants on the map. */
|
/** Stores all ore quadtrants on the map. */
|
||||||
private ObjectMap<Item, ObjectSet<Tile>> ores = new ObjectMap<>();
|
private ObjectMap<Item, ObjectSet<Tile>> ores = new ObjectMap<>();
|
||||||
@@ -162,6 +164,39 @@ public class BlockIndexer{
|
|||||||
return flagMap[team.id][type.ordinal()];
|
return flagMap[team.id][type.ordinal()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean eachBlock(TeamTrait trait, float range, Boolf<Tile> pred, Cons<Tile> cons){
|
||||||
|
return eachBlock(trait.getTeam(), trait.getX(), trait.getY(), range, pred, cons);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean eachBlock(Team team, float wx, float wy, float range, Boolf<Tile> pred, Cons<Tile> cons){
|
||||||
|
intSet.clear();
|
||||||
|
|
||||||
|
int tx = world.toTile(wx);
|
||||||
|
int ty = world.toTile(wy);
|
||||||
|
|
||||||
|
int tileRange = (int)(range / tilesize + 1);
|
||||||
|
intSet.clear();
|
||||||
|
boolean any = false;
|
||||||
|
|
||||||
|
for(int x = -tileRange + tx; x <= tileRange + tx; x++){
|
||||||
|
for(int y = -tileRange + ty; y <= tileRange + ty; y++){
|
||||||
|
if(!Mathf.within(x * tilesize, y * tilesize, wx, wy, range)) continue;
|
||||||
|
|
||||||
|
Tile other = world.ltile(x, y);
|
||||||
|
|
||||||
|
if(other == null) continue;
|
||||||
|
|
||||||
|
if(other.getTeam() == team && !intSet.contains(other.pos()) && other.entity != null && pred.get(other)){
|
||||||
|
cons.get(other);
|
||||||
|
any = true;
|
||||||
|
intSet.add(other.pos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return any;
|
||||||
|
}
|
||||||
|
|
||||||
/** Get all enemy blocks with a flag. */
|
/** Get all enemy blocks with a flag. */
|
||||||
public Array<Tile> getEnemy(Team team, BlockFlag type){
|
public Array<Tile> getEnemy(Team team, BlockFlag type){
|
||||||
returnArray.clear();
|
returnArray.clear();
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ public class Blocks implements ContentList{
|
|||||||
fortressFactory, repairPoint,
|
fortressFactory, repairPoint,
|
||||||
|
|
||||||
//upgrades
|
//upgrades
|
||||||
dartPad, deltaPad, tauPad, omegaPad, javelinPad, tridentPad, glaivePad;
|
dartPad, alphaPad, deltaPad, tauPad, omegaPad, javelinPad, tridentPad, glaivePad;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
@@ -258,9 +258,7 @@ public class Blocks implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
ice = new Floor("ice"){{
|
ice = new Floor("ice"){{
|
||||||
//TODO fix drag/speed
|
dragMultiplier = 0.6f;
|
||||||
dragMultiplier = 1f;
|
|
||||||
speedMultiplier = 1f;
|
|
||||||
attributes.set(Attribute.water, 0.4f);
|
attributes.set(Attribute.water, 0.4f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -1273,6 +1271,7 @@ public class Blocks implements ContentList{
|
|||||||
health = 1100;
|
health = 1100;
|
||||||
itemCapacity = 4000;
|
itemCapacity = 4000;
|
||||||
size = 3;
|
size = 3;
|
||||||
|
mech = Mechs.vanguard;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
coreFoundation = new CoreBlock("core-foundation"){{
|
coreFoundation = new CoreBlock("core-foundation"){{
|
||||||
@@ -1281,6 +1280,7 @@ public class Blocks implements ContentList{
|
|||||||
health = 2000;
|
health = 2000;
|
||||||
itemCapacity = 9000;
|
itemCapacity = 9000;
|
||||||
size = 4;
|
size = 4;
|
||||||
|
mech = Mechs.vanguard;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
coreNucleus = new CoreBlock("core-nucleus"){{
|
coreNucleus = new CoreBlock("core-nucleus"){{
|
||||||
@@ -1289,6 +1289,7 @@ public class Blocks implements ContentList{
|
|||||||
health = 4000;
|
health = 4000;
|
||||||
itemCapacity = 13000;
|
itemCapacity = 13000;
|
||||||
size = 5;
|
size = 5;
|
||||||
|
mech = Mechs.vanguard;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
vault = new Vault("vault"){{
|
vault = new Vault("vault"){{
|
||||||
@@ -1707,6 +1708,7 @@ public class Blocks implements ContentList{
|
|||||||
unitType = UnitTypes.ghoul;
|
unitType = UnitTypes.ghoul;
|
||||||
produceTime = 1150;
|
produceTime = 1150;
|
||||||
size = 3;
|
size = 3;
|
||||||
|
maxSpawn = 2;
|
||||||
consumes.power(1.2f);
|
consumes.power(1.2f);
|
||||||
consumes.items(new ItemStack(Items.silicon, 15), new ItemStack(Items.titanium, 10));
|
consumes.items(new ItemStack(Items.silicon, 15), new ItemStack(Items.titanium, 10));
|
||||||
}};
|
}};
|
||||||
@@ -1716,6 +1718,7 @@ public class Blocks implements ContentList{
|
|||||||
unitType = UnitTypes.revenant;
|
unitType = UnitTypes.revenant;
|
||||||
produceTime = 2000;
|
produceTime = 2000;
|
||||||
size = 4;
|
size = 4;
|
||||||
|
maxSpawn = 2;
|
||||||
consumes.power(3f);
|
consumes.power(3f);
|
||||||
consumes.items(new ItemStack(Items.silicon, 40), new ItemStack(Items.titanium, 30));
|
consumes.items(new ItemStack(Items.silicon, 40), new ItemStack(Items.titanium, 30));
|
||||||
}};
|
}};
|
||||||
@@ -1768,7 +1771,14 @@ public class Blocks implements ContentList{
|
|||||||
//endregion
|
//endregion
|
||||||
//region upgrades
|
//region upgrades
|
||||||
|
|
||||||
dartPad = new MechPad("dart-mech-pad"){{
|
dartPad = new MechPad("dart-ship-pad"){{
|
||||||
|
requirements(Category.upgrade, ItemStack.with(Items.lead, 100, Items.graphite, 50, Items.copper, 75));
|
||||||
|
mech = Mechs.dart;
|
||||||
|
size = 2;
|
||||||
|
consumes.power(0.5f);
|
||||||
|
}};
|
||||||
|
|
||||||
|
alphaPad = new MechPad("alpha-mech-pad"){{
|
||||||
requirements(Category.upgrade, ItemStack.with(Items.lead, 100, Items.graphite, 50, Items.copper, 75));
|
requirements(Category.upgrade, ItemStack.with(Items.lead, 100, Items.graphite, 50, Items.copper, 75));
|
||||||
mech = Mechs.alpha;
|
mech = Mechs.alpha;
|
||||||
size = 2;
|
size = 2;
|
||||||
|
|||||||
@@ -452,6 +452,7 @@ public class Bullets implements ContentList{
|
|||||||
hitEffect = Fx.hitFlameSmall;
|
hitEffect = Fx.hitFlameSmall;
|
||||||
despawnEffect = Fx.none;
|
despawnEffect = Fx.none;
|
||||||
status = StatusEffects.burning;
|
status = StatusEffects.burning;
|
||||||
|
keepVelocity = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -483,46 +484,13 @@ public class Bullets implements ContentList{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
lancerLaser = new BulletType(0.001f, 140){
|
lancerLaser = new LaserBulletType(140){{
|
||||||
Color[] colors = {Pal.lancerLaser.cpy().mul(1f, 1f, 1f, 0.4f), Pal.lancerLaser, Color.white};
|
colors = new Color[]{Pal.lancerLaser.cpy().mul(1f, 1f, 1f, 0.4f), Pal.lancerLaser, Color.white};
|
||||||
float[] tscales = {1f, 0.7f, 0.5f, 0.2f};
|
hitEffect = Fx.hitLancer;
|
||||||
float[] lenscales = {1f, 1.1f, 1.13f, 1.14f};
|
despawnEffect = Fx.none;
|
||||||
float length = 160f;
|
hitSize = 4;
|
||||||
|
lifetime = 16f;
|
||||||
{
|
}};
|
||||||
hitEffect = Fx.hitLancer;
|
|
||||||
despawnEffect = Fx.none;
|
|
||||||
hitSize = 4;
|
|
||||||
lifetime = 16f;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(Bullet b){
|
|
||||||
float f = Mathf.curve(b.fin(), 0f, 0.2f);
|
|
||||||
float baseLen = length * f;
|
|
||||||
|
|
||||||
Lines.lineAngle(b.x, b.y, b.rot(), baseLen);
|
|
||||||
for(int s = 0; s < 3; s++){
|
|
||||||
Draw.color(colors[s]);
|
|
||||||
for(int i = 0; i < tscales.length; i++){
|
|
||||||
Lines.stroke(7f * b.fout() * (s == 0 ? 1.5f : s == 1 ? 1f : 0.3f) * tscales[i]);
|
|
||||||
Lines.lineAngle(b.x, b.y, b.rot(), baseLen * lenscales[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Draw.reset();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
meltdownLaser = new BulletType(0.001f, 70){
|
meltdownLaser = new BulletType(0.001f, 70){
|
||||||
Color tmpColor = new Color();
|
Color tmpColor = new Color();
|
||||||
@@ -622,22 +590,10 @@ public class Bullets implements ContentList{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
arc = new BulletType(0.001f, 21){
|
arc = new LightningBulletType(){{
|
||||||
{
|
damage = 21;
|
||||||
lifetime = 1;
|
lightningLength = 25;
|
||||||
despawnEffect = Fx.none;
|
}};
|
||||||
hitEffect = Fx.hitLancer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(Bullet b){
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Bullet b){
|
|
||||||
Lightning.create(b.getTeam(), Pal.lancerLaser, damage, b.x, b.y, b.rot(), 25);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
driverBolt = new MassDriverBolt();
|
driverBolt = new MassDriverBolt();
|
||||||
|
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ public class Fx implements ContentList{
|
|||||||
producesmoke, smeltsmoke, formsmoke, blastsmoke, lava, doorclose, dooropen, dooropenlarge, doorcloselarge, purify, purifyoil, purifystone, generate,
|
producesmoke, smeltsmoke, formsmoke, blastsmoke, lava, doorclose, dooropen, dooropenlarge, doorcloselarge, purify, purifyoil, purifystone, generate,
|
||||||
mine, mineBig, mineHuge, smelt, teleportActivate, teleport, teleportOut, ripple, bubble, launch,
|
mine, mineBig, mineHuge, smelt, teleportActivate, teleport, teleportOut, ripple, bubble, launch,
|
||||||
healBlock, healBlockFull, healWaveMend, overdriveWave, overdriveBlockFull, shieldBreak, hitBulletSmall, hitFuse,
|
healBlock, healBlockFull, healWaveMend, overdriveWave, overdriveBlockFull, shieldBreak, hitBulletSmall, hitFuse,
|
||||||
hitBulletBig, hitFlameSmall, hitLiquid, hitLaser, hitLancer, hitMeltdown, despawn, flakExplosion, blastExplosion,
|
hitBulletBig, hitFlameSmall, hitLiquid, hitLaser, hitYellowLaser, hitLancer, hitMeltdown, despawn, flakExplosion, blastExplosion,
|
||||||
plasticExplosion, artilleryTrail, incendTrail, missileTrail, absorb, flakExplosionBig, plasticExplosionFlak, burning, fire,
|
plasticExplosion, artilleryTrail, incendTrail, missileTrail, absorb, flakExplosionBig, plasticExplosionFlak, burning, fire,
|
||||||
fireSmoke, steam, fireballsmoke, ballfire, freezing, melting, wet, oily, overdriven, dropItem, shockwave,
|
fireSmoke, steam, fireballsmoke, ballfire, freezing, melting, wet, oily, overdriven, dropItem, shockwave,
|
||||||
bigShockwave, nuclearShockwave, explosion, blockExplosion, blockExplosionSmoke, shootSmall, shootHeal, shootSmallSmoke, shootBig, shootBig2, shootBigSmoke,
|
bigShockwave, nuclearShockwave, explosion, blockExplosion, blockExplosionSmoke, shootSmall, shootHeal, shootHealYellow, shootSmallSmoke, shootBig, shootBig2, shootBigSmoke,
|
||||||
shootBigSmoke2, shootSmallFlame, shootPyraFlame, shootLiquid, shellEjectSmall, shellEjectMedium,
|
shootBigSmoke2, shootSmallFlame, shootPyraFlame, shootLiquid, shellEjectSmall, shellEjectMedium,
|
||||||
shellEjectBig, lancerLaserShoot, lancerLaserShootSmoke, lancerLaserCharge, lancerLaserChargeBegin, lightningCharge, lightningShoot,
|
shellEjectBig, lancerLaserShoot, lancerLaserShootSmoke, lancerLaserCharge, lancerLaserChargeBegin, lightningCharge, lightningShoot,
|
||||||
unitSpawn, spawnShockwave, magmasmoke, impactShockwave, impactcloud, impactsmoke, dynamicExplosion, padlaunch, commandSend, coreLand;
|
unitSpawn, spawnShockwave, magmasmoke, impactShockwave, impactcloud, impactsmoke, dynamicExplosion, padlaunch, commandSend, coreLand;
|
||||||
@@ -158,7 +158,6 @@ public class Fx implements ContentList{
|
|||||||
Lines.circle(e.x, e.y, 2f + e.finpow() * 7f);
|
Lines.circle(e.x, e.y, 2f + e.finpow() * 7f);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
hitBulletSmall = new Effect(14, e -> {
|
hitBulletSmall = new Effect(14, e -> {
|
||||||
Draw.color(Color.white, Pal.lightOrange, e.fin());
|
Draw.color(Color.white, Pal.lightOrange, e.fin());
|
||||||
|
|
||||||
@@ -254,6 +253,13 @@ public class Fx implements ContentList{
|
|||||||
Lines.circle(e.x, e.y, e.fin() * 5f);
|
Lines.circle(e.x, e.y, e.fin() * 5f);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
hitYellowLaser = new Effect(8, e -> {
|
||||||
|
Draw.color(Color.white, Pal.lightTrail, e.fin());
|
||||||
|
Lines.stroke(0.5f + e.fout());
|
||||||
|
Lines.circle(e.x, e.y, e.fin() * 5f);
|
||||||
|
Draw.reset();
|
||||||
|
});
|
||||||
|
|
||||||
despawn = new Effect(12, e -> {
|
despawn = new Effect(12, e -> {
|
||||||
Draw.color(Pal.lighterOrange, Color.gray, e.fin());
|
Draw.color(Pal.lighterOrange, Color.gray, e.fin());
|
||||||
Lines.stroke(e.fout());
|
Lines.stroke(e.fout());
|
||||||
@@ -635,6 +641,14 @@ public class Fx implements ContentList{
|
|||||||
Drawf.tri(e.x, e.y, w, 4f * e.fout(), e.rotation + 180f);
|
Drawf.tri(e.x, e.y, w, 4f * e.fout(), e.rotation + 180f);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
shootHealYellow = new Effect(8, e -> {
|
||||||
|
Draw.color(Pal.lightTrail);
|
||||||
|
float w = 1f + 5 * e.fout();
|
||||||
|
Drawf.tri(e.x, e.y, w, 17f * e.fout(), e.rotation);
|
||||||
|
Drawf.tri(e.x, e.y, w, 4f * e.fout(), e.rotation + 180f);
|
||||||
|
Draw.reset();
|
||||||
|
});
|
||||||
|
|
||||||
shootSmallSmoke = new Effect(20f, e -> {
|
shootSmallSmoke = new Effect(20f, e -> {
|
||||||
Draw.color(Pal.lighterOrange, Color.lightGray, Color.gray, e.fin());
|
Draw.color(Pal.lighterOrange, Color.lightGray, Color.gray, e.fin());
|
||||||
|
|
||||||
@@ -774,9 +788,9 @@ public class Fx implements ContentList{
|
|||||||
});
|
});
|
||||||
|
|
||||||
lancerLaserShootSmoke = new Effect(26f, e -> {
|
lancerLaserShootSmoke = new Effect(26f, e -> {
|
||||||
Draw.color(Pal.lancerLaser);
|
Draw.color(Color.white);
|
||||||
|
|
||||||
Angles.randLenVectors(e.id, 7, 80f, e.rotation, 0f, (x, y) -> {
|
Angles.randLenVectors(e.id, 7, 70f, e.rotation, 0f, (x, y) -> {
|
||||||
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fout() * 9f);
|
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fout() * 9f);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -791,7 +805,7 @@ public class Fx implements ContentList{
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
lancerLaserChargeBegin = new Effect(71f, e -> {
|
lancerLaserChargeBegin = new Effect(60f, e -> {
|
||||||
Draw.color(Pal.lancerLaser);
|
Draw.color(Pal.lancerLaser);
|
||||||
Fill.circle(e.x, e.y, e.fin() * 3f);
|
Fill.circle(e.x, e.y, e.fin() * 3f);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import arc.graphics.g2d.*;
|
|||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.ctype.ContentList;
|
import mindustry.ctype.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.bullet.*;
|
import mindustry.entities.bullet.*;
|
||||||
import mindustry.entities.effect.*;
|
import mindustry.entities.effect.*;
|
||||||
@@ -15,15 +15,115 @@ import mindustry.gen.*;
|
|||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
|
||||||
public class Mechs implements ContentList{
|
import static mindustry.Vars.indexer;
|
||||||
public static Mech alpha, delta, tau, omega, dart, javelin, trident, glaive;
|
|
||||||
|
|
||||||
public static Mech starter;
|
public class Mechs implements ContentList{
|
||||||
|
public static UnitDef vanguard, alpha, delta, tau, omega, dart, javelin, trident, glaive;
|
||||||
|
|
||||||
|
public static UnitDef starter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
|
|
||||||
alpha = new Mech("alpha-mech", false){
|
vanguard = new UnitDef("vanguard-ship"){
|
||||||
|
float healRange = 60f;
|
||||||
|
float healReload = 200f;
|
||||||
|
float healPercent = 10f;
|
||||||
|
|
||||||
|
{
|
||||||
|
flying = true;
|
||||||
|
drillTier = 1;
|
||||||
|
minePower = 4f;
|
||||||
|
speed = 0.49f;
|
||||||
|
drag = 0.09f;
|
||||||
|
health = 200f;
|
||||||
|
weaponOffsetX = -1;
|
||||||
|
engineSize = 2.3f;
|
||||||
|
weaponOffsetY = -1;
|
||||||
|
engineColor = Pal.lightTrail;
|
||||||
|
cellTrnsY = 1f;
|
||||||
|
buildPower = 1.2f;
|
||||||
|
weapon = new Weapon("vanguard-blaster"){{
|
||||||
|
length = 1.5f;
|
||||||
|
reload = 30f;
|
||||||
|
alternate = true;
|
||||||
|
inaccuracy = 6f;
|
||||||
|
velocityRnd = 0.1f;
|
||||||
|
ejectEffect = Fx.none;
|
||||||
|
bullet = new HealBulletType(){{
|
||||||
|
healPercent = 3f;
|
||||||
|
backColor = engineColor;
|
||||||
|
homingPower = 20f;
|
||||||
|
bulletHeight = 4f;
|
||||||
|
bulletWidth = 1.5f;
|
||||||
|
damage = 3f;
|
||||||
|
speed = 4f;
|
||||||
|
lifetime = 40f;
|
||||||
|
shootEffect = Fx.shootHealYellow;
|
||||||
|
smokeEffect = hitEffect = despawnEffect = Fx.hitYellowLaser;
|
||||||
|
}};
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean alwaysUnlocked(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Player player){
|
||||||
|
if(player.timer.get(Player.timerAbility, healReload)){
|
||||||
|
if(indexer.eachBlock(player, healRange, other -> other.entity.damaged(), other -> {
|
||||||
|
other.entity.healBy(other.entity.maxHealth() * healPercent / 100f);
|
||||||
|
Effects.effect(Fx.healBlockFull, Pal.heal, other.drawx(), other.drawy(), other.block().size);
|
||||||
|
})){
|
||||||
|
Effects.effect(Fx.healWave, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
alpha = new UnitDef("alpha-mech", false){
|
||||||
|
{
|
||||||
|
drillTier = -1;
|
||||||
|
speed = 0.5f;
|
||||||
|
boostSpeed = 0.95f;
|
||||||
|
itemCapacity = 15;
|
||||||
|
mass = 0.9f;
|
||||||
|
health = 150f;
|
||||||
|
buildPower = 0.9f;
|
||||||
|
weaponOffsetX = 1;
|
||||||
|
weaponOffsetY = -1;
|
||||||
|
engineColor = Pal.heal;
|
||||||
|
|
||||||
|
weapon = new Weapon("shockgun"){{
|
||||||
|
shake = 2f;
|
||||||
|
length = 0.5f;
|
||||||
|
reload = 70f;
|
||||||
|
alternate = true;
|
||||||
|
recoil = 4f;
|
||||||
|
width = 5f;
|
||||||
|
shootSound = Sounds.laser;
|
||||||
|
|
||||||
|
bullet = new LaserBulletType(){{
|
||||||
|
damage = 20f;
|
||||||
|
recoil = 1f;
|
||||||
|
sideAngle = 45f;
|
||||||
|
sideWidth = 1f;
|
||||||
|
sideLength = 70f;
|
||||||
|
colors = new Color[]{Pal.heal.cpy().a(0.4f), Pal.heal, Color.white};
|
||||||
|
}};
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Player player){
|
||||||
|
player.healBy(Time.delta() * 0.09f);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
delta = new UnitDef("delta-mech", false){
|
||||||
{
|
{
|
||||||
drillPower = 1;
|
drillPower = 1;
|
||||||
mineSpeed = 1.5f;
|
mineSpeed = 1.5f;
|
||||||
@@ -34,65 +134,26 @@ public class Mechs implements ContentList{
|
|||||||
buildPower = 1.2f;
|
buildPower = 1.2f;
|
||||||
engineColor = Color.valueOf("ffd37f");
|
engineColor = Color.valueOf("ffd37f");
|
||||||
health = 250f;
|
health = 250f;
|
||||||
|
weaponOffsetX = 4f;
|
||||||
|
|
||||||
weapon = new Weapon("blaster"){{
|
weapon = new Weapon("flamethrower"){{
|
||||||
length = 1.5f;
|
length = 1.5f;
|
||||||
reload = 14f;
|
reload = 30f;
|
||||||
|
width = 4f;
|
||||||
alternate = true;
|
alternate = true;
|
||||||
ejectEffect = Fx.shellEjectSmall;
|
shots = 3;
|
||||||
bullet = Bullets.standardMechSmall;
|
inaccuracy = 40f;
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateAlt(Player player){
|
|
||||||
player.healBy(Time.delta() * 0.09f);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
delta = new Mech("delta-mech", false){
|
|
||||||
float cooldown = 120;
|
|
||||||
|
|
||||||
{
|
|
||||||
drillPower = -1;
|
|
||||||
speed = 0.75f;
|
|
||||||
boostSpeed = 0.95f;
|
|
||||||
itemCapacity = 15;
|
|
||||||
mass = 0.9f;
|
|
||||||
health = 150f;
|
|
||||||
buildPower = 0.9f;
|
|
||||||
weaponOffsetX = -1;
|
|
||||||
weaponOffsetY = -1;
|
|
||||||
engineColor = Color.valueOf("d3ddff");
|
|
||||||
|
|
||||||
weapon = new Weapon("shockgun"){{
|
|
||||||
shake = 2f;
|
|
||||||
length = 1f;
|
|
||||||
reload = 55f;
|
|
||||||
shotDelay = 3f;
|
|
||||||
alternate = true;
|
|
||||||
shots = 2;
|
|
||||||
inaccuracy = 0f;
|
|
||||||
ejectEffect = Fx.none;
|
|
||||||
bullet = Bullets.lightning;
|
|
||||||
shootSound = Sounds.spark;
|
shootSound = Sounds.spark;
|
||||||
|
bullet = new LightningBulletType(){{
|
||||||
|
damage = 5;
|
||||||
|
lightningLength = 10;
|
||||||
|
lightningColor = Pal.lightFlame;
|
||||||
|
}};
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLand(Player player){
|
|
||||||
if(player.timer.get(Player.timerAbility, cooldown)){
|
|
||||||
Effects.shake(1f, 1f, player);
|
|
||||||
Effects.effect(Fx.landShock, player);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
Time.run(Mathf.random(8f), () -> Lightning.create(player.getTeam(), Pal.lancerLaser, 17f * Vars.state.rules.playerDamageMultiplier, player.x, player.y, Mathf.random(360f), 14));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tau = new Mech("tau-mech", false){
|
tau = new UnitDef("tau-mech", false){
|
||||||
float healRange = 60f;
|
float healRange = 60f;
|
||||||
float healAmount = 10f;
|
float healAmount = 10f;
|
||||||
float healReload = 160f;
|
float healReload = 160f;
|
||||||
@@ -125,7 +186,7 @@ public class Mechs implements ContentList{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateAlt(Player player){
|
public void update(Player player){
|
||||||
|
|
||||||
if(player.timer.get(Player.timerAbility, healReload)){
|
if(player.timer.get(Player.timerAbility, healReload)){
|
||||||
wasHealed = false;
|
wasHealed = false;
|
||||||
@@ -145,7 +206,7 @@ public class Mechs implements ContentList{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
omega = new Mech("omega-mech", false){
|
omega = new UnitDef("omega-mech", false){
|
||||||
protected TextureRegion armorRegion;
|
protected TextureRegion armorRegion;
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -193,7 +254,7 @@ public class Mechs implements ContentList{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateAlt(Player player){
|
public void update(Player player){
|
||||||
float scl = 1f - player.shootHeat / 2f*Time.delta();
|
float scl = 1f - player.shootHeat / 2f*Time.delta();
|
||||||
player.velocity().scl(scl);
|
player.velocity().scl(scl);
|
||||||
}
|
}
|
||||||
@@ -217,10 +278,15 @@ public class Mechs implements ContentList{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
dart = new Mech("dart-ship", true){
|
dart = new UnitDef("dart-ship"){
|
||||||
|
float effectRange = 60f;
|
||||||
|
float effectReload = 60f * 5;
|
||||||
|
float effectDuration = 60f * 10f;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
flying = true;
|
||||||
drillPower = 1;
|
drillPower = 1;
|
||||||
mineSpeed = 3f;
|
mineSpeed = 2f;
|
||||||
speed = 0.5f;
|
speed = 0.5f;
|
||||||
drag = 0.09f;
|
drag = 0.09f;
|
||||||
health = 200f;
|
health = 200f;
|
||||||
@@ -239,17 +305,32 @@ public class Mechs implements ContentList{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean alwaysUnlocked(){
|
public void update(Player player){
|
||||||
return true;
|
super.update(player);
|
||||||
|
|
||||||
|
if(player.timer.get(Player.timerAbility, effectReload)){
|
||||||
|
|
||||||
|
Units.nearby(player.getTeam(), player.x, player.y, effectRange, unit -> {
|
||||||
|
//unit.applyEffect(StatusEffects.overdrive, effectDuration);
|
||||||
|
});
|
||||||
|
|
||||||
|
indexer.eachBlock(player, effectRange, other -> other.entity.damaged(), other -> {
|
||||||
|
other.entity.applyBoost(1.5f, effectDuration);
|
||||||
|
Effects.effect(Fx.healBlockFull, Pal.heal, other.drawx(), other.drawy(), other.block().size);
|
||||||
|
});
|
||||||
|
|
||||||
|
Effects.effect(Fx.overdriveWave, player);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
javelin = new Mech("javelin-ship", true){
|
javelin = new UnitDef("javelin-ship"){
|
||||||
float minV = 3.6f;
|
float minV = 3.6f;
|
||||||
float maxV = 6f;
|
float maxV = 6f;
|
||||||
TextureRegion shield;
|
TextureRegion shield;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
flying = true;
|
||||||
drillPower = -1;
|
drillPower = -1;
|
||||||
speed = 0.11f;
|
speed = 0.11f;
|
||||||
drag = 0.01f;
|
drag = 0.01f;
|
||||||
@@ -283,7 +364,7 @@ public class Mechs implements ContentList{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateAlt(Player player){
|
public void update(Player player){
|
||||||
float scl = scld(player);
|
float scl = scld(player);
|
||||||
if(Mathf.chance(Time.delta() * (0.15 * scl))){
|
if(Mathf.chance(Time.delta() * (0.15 * scl))){
|
||||||
Effects.effect(Fx.hitLancer, Pal.lancerLaser, player.x, player.y);
|
Effects.effect(Fx.hitLancer, Pal.lancerLaser, player.x, player.y);
|
||||||
@@ -308,8 +389,9 @@ public class Mechs implements ContentList{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
trident = new Mech("trident-ship", true){
|
trident = new UnitDef("trident-ship"){
|
||||||
{
|
{
|
||||||
|
flying = true;
|
||||||
drillPower = 2;
|
drillPower = 2;
|
||||||
speed = 0.15f;
|
speed = 0.15f;
|
||||||
drag = 0.034f;
|
drag = 0.034f;
|
||||||
@@ -349,8 +431,9 @@ public class Mechs implements ContentList{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
glaive = new Mech("glaive-ship", true){
|
glaive = new UnitDef("glaive-ship"){
|
||||||
{
|
{
|
||||||
|
flying = true;
|
||||||
drillPower = 4;
|
drillPower = 4;
|
||||||
mineSpeed = 1.3f;
|
mineSpeed = 1.3f;
|
||||||
speed = 0.32f;
|
speed = 0.32f;
|
||||||
@@ -373,6 +456,6 @@ public class Mechs implements ContentList{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
starter = dart;
|
starter = vanguard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ import mindustry.gen.*;
|
|||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
|
||||||
public class UnitTypes implements ContentList{
|
public class UnitTypes implements ContentList{
|
||||||
public static UnitType
|
public static UnitDef
|
||||||
draug, spirit, phantom,
|
draug, spirit, phantom,
|
||||||
wraith, ghoul, revenant, lich, reaper,
|
wraith, ghoul, revenant, lich, reaper,
|
||||||
dagger, crawler, titan, fortress, eruptor, chaosArray, eradicator;
|
dagger, crawler, titan, fortress, eruptor, chaosArray, eradicator;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
draug = new UnitType("draug", MinerDrone::new){{
|
draug = new UnitDef("draug", MinerDrone::new){{
|
||||||
flying = true;
|
flying = true;
|
||||||
drag = 0.01f;
|
drag = 0.01f;
|
||||||
speed = 0.3f;
|
speed = 0.3f;
|
||||||
@@ -25,12 +25,9 @@ public class UnitTypes implements ContentList{
|
|||||||
minePower = 0.9f;
|
minePower = 0.9f;
|
||||||
engineSize = 1.8f;
|
engineSize = 1.8f;
|
||||||
engineOffset = 5.7f;
|
engineOffset = 5.7f;
|
||||||
weapon = new Weapon("you have incurred my wrath. prepare to die."){{
|
|
||||||
bullet = Bullets.lancerLaser;
|
|
||||||
}};
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
spirit = new UnitType("spirit", RepairDrone::new){{
|
spirit = new UnitDef("spirit", RepairDrone::new){{
|
||||||
flying = true;
|
flying = true;
|
||||||
drag = 0.01f;
|
drag = 0.01f;
|
||||||
speed = 0.42f;
|
speed = 0.42f;
|
||||||
@@ -51,7 +48,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
phantom = new UnitType("phantom", BuilderDrone::new){{
|
phantom = new UnitDef("phantom", BuilderDrone::new){{
|
||||||
flying = true;
|
flying = true;
|
||||||
drag = 0.01f;
|
drag = 0.01f;
|
||||||
mass = 2f;
|
mass = 2f;
|
||||||
@@ -74,7 +71,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
dagger = new UnitType("dagger", GroundUnit::new){{
|
dagger = new UnitDef("dagger", GroundUnit::new){{
|
||||||
maxVelocity = 1.1f;
|
maxVelocity = 1.1f;
|
||||||
speed = 0.2f;
|
speed = 0.2f;
|
||||||
drag = 0.4f;
|
drag = 0.4f;
|
||||||
@@ -90,7 +87,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
crawler = new UnitType("crawler", GroundUnit::new){{
|
crawler = new UnitDef("crawler", GroundUnit::new){{
|
||||||
maxVelocity = 1.27f;
|
maxVelocity = 1.27f;
|
||||||
speed = 0.285f;
|
speed = 0.285f;
|
||||||
drag = 0.4f;
|
drag = 0.4f;
|
||||||
@@ -113,7 +110,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
titan = new UnitType("titan", GroundUnit::new){{
|
titan = new UnitDef("titan", GroundUnit::new){{
|
||||||
maxVelocity = 0.8f;
|
maxVelocity = 0.8f;
|
||||||
speed = 0.22f;
|
speed = 0.22f;
|
||||||
drag = 0.4f;
|
drag = 0.4f;
|
||||||
@@ -134,7 +131,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
fortress = new UnitType("fortress", GroundUnit::new){{
|
fortress = new UnitDef("fortress", GroundUnit::new){{
|
||||||
maxVelocity = 0.78f;
|
maxVelocity = 0.78f;
|
||||||
speed = 0.15f;
|
speed = 0.15f;
|
||||||
drag = 0.4f;
|
drag = 0.4f;
|
||||||
@@ -156,7 +153,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
eruptor = new UnitType("eruptor", GroundUnit::new){{
|
eruptor = new UnitDef("eruptor", GroundUnit::new){{
|
||||||
maxVelocity = 0.81f;
|
maxVelocity = 0.81f;
|
||||||
speed = 0.16f;
|
speed = 0.16f;
|
||||||
drag = 0.4f;
|
drag = 0.4f;
|
||||||
@@ -178,7 +175,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
chaosArray = new UnitType("chaos-array", GroundUnit::new){{
|
chaosArray = new UnitDef("chaos-array", GroundUnit::new){{
|
||||||
maxVelocity = 0.68f;
|
maxVelocity = 0.68f;
|
||||||
speed = 0.12f;
|
speed = 0.12f;
|
||||||
drag = 0.4f;
|
drag = 0.4f;
|
||||||
@@ -202,7 +199,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
eradicator = new UnitType("eradicator", GroundUnit::new){{
|
eradicator = new UnitDef("eradicator", GroundUnit::new){{
|
||||||
maxVelocity = 0.68f;
|
maxVelocity = 0.68f;
|
||||||
speed = 0.12f;
|
speed = 0.12f;
|
||||||
drag = 0.4f;
|
drag = 0.4f;
|
||||||
@@ -227,7 +224,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
wraith = new UnitType("wraith", FlyingUnit::new){{
|
wraith = new UnitDef("wraith", FlyingUnit::new){{
|
||||||
speed = 0.3f;
|
speed = 0.3f;
|
||||||
maxVelocity = 1.9f;
|
maxVelocity = 1.9f;
|
||||||
drag = 0.01f;
|
drag = 0.01f;
|
||||||
@@ -246,7 +243,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
ghoul = new UnitType("ghoul", FlyingUnit::new){{
|
ghoul = new UnitDef("ghoul", FlyingUnit::new){{
|
||||||
health = 220;
|
health = 220;
|
||||||
speed = 0.2f;
|
speed = 0.2f;
|
||||||
maxVelocity = 1.4f;
|
maxVelocity = 1.4f;
|
||||||
@@ -270,7 +267,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
revenant = new UnitType("revenant", HoverUnit::new){{
|
revenant = new UnitDef("revenant", HoverUnit::new){{
|
||||||
health = 1000;
|
health = 1000;
|
||||||
mass = 5f;
|
mass = 5f;
|
||||||
hitsize = 20f;
|
hitsize = 20f;
|
||||||
@@ -301,7 +298,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
lich = new UnitType("lich", HoverUnit::new){{
|
lich = new UnitDef("lich", HoverUnit::new){{
|
||||||
health = 6000;
|
health = 6000;
|
||||||
mass = 20f;
|
mass = 20f;
|
||||||
hitsize = 40f;
|
hitsize = 40f;
|
||||||
@@ -334,7 +331,7 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
reaper = new UnitType("reaper", HoverUnit::new){{
|
reaper = new UnitDef("reaper", HoverUnit::new){{
|
||||||
health = 11000;
|
health = 11000;
|
||||||
mass = 30f;
|
mass = 30f;
|
||||||
hitsize = 56f;
|
hitsize = 56f;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import mindustry.ui.Cicon;
|
|||||||
|
|
||||||
/** Base interface for an unlockable content type. */
|
/** Base interface for an unlockable content type. */
|
||||||
public abstract class UnlockableContent extends MappableContent{
|
public abstract class UnlockableContent extends MappableContent{
|
||||||
/** Localized, formal name. Never null. Set to block name if not found in bundle. */
|
/** Localized, formal name. Never null. Set to internal name if not found in bundle. */
|
||||||
public String localizedName;
|
public String localizedName;
|
||||||
/** Localized description. May be null. */
|
/** Localized description. May be null. */
|
||||||
public @Nullable String description;
|
public @Nullable String description;
|
||||||
|
|||||||
@@ -166,33 +166,42 @@ public enum EditorTool{
|
|||||||
stack.clear();
|
stack.clear();
|
||||||
stack.add(Pos.get(x, y));
|
stack.add(Pos.get(x, y));
|
||||||
|
|
||||||
while(stack.size > 0){
|
try{
|
||||||
int popped = stack.pop();
|
while(stack.size > 0 && stack.size < width*height){
|
||||||
x = Pos.x(popped);
|
int popped = stack.pop();
|
||||||
y = Pos.y(popped);
|
x = Pos.x(popped);
|
||||||
|
y = Pos.y(popped);
|
||||||
|
|
||||||
x1 = x;
|
x1 = x;
|
||||||
while(x1 >= 0 && tester.get(editor.tile(x1, y))) x1--;
|
while(x1 >= 0 && tester.get(editor.tile(x1, y))) x1--;
|
||||||
x1++;
|
|
||||||
boolean spanAbove = false, spanBelow = false;
|
|
||||||
while(x1 < width && tester.get(editor.tile(x1, y))){
|
|
||||||
filler.get(editor.tile(x1, y));
|
|
||||||
|
|
||||||
if(!spanAbove && y > 0 && tester.get(editor.tile(x1, y - 1))){
|
|
||||||
stack.add(Pos.get(x1, y - 1));
|
|
||||||
spanAbove = true;
|
|
||||||
}else if(spanAbove && !tester.get(editor.tile(x1, y - 1))){
|
|
||||||
spanAbove = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!spanBelow && y < height - 1 && tester.get(editor.tile(x1, y + 1))){
|
|
||||||
stack.add(Pos.get(x1, y + 1));
|
|
||||||
spanBelow = true;
|
|
||||||
}else if(spanBelow && y < height - 1 && !tester.get(editor.tile(x1, y + 1))){
|
|
||||||
spanBelow = false;
|
|
||||||
}
|
|
||||||
x1++;
|
x1++;
|
||||||
|
boolean spanAbove = false, spanBelow = false;
|
||||||
|
while(x1 < width && tester.get(editor.tile(x1, y))){
|
||||||
|
filler.get(editor.tile(x1, y));
|
||||||
|
|
||||||
|
if(!spanAbove && y > 0 && tester.get(editor.tile(x1, y - 1))){
|
||||||
|
stack.add(Pos.get(x1, y - 1));
|
||||||
|
spanAbove = true;
|
||||||
|
}else if(spanAbove && !tester.get(editor.tile(x1, y - 1))){
|
||||||
|
spanAbove = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!spanBelow && y < height - 1 && tester.get(editor.tile(x1, y + 1))){
|
||||||
|
stack.add(Pos.get(x1, y + 1));
|
||||||
|
spanBelow = true;
|
||||||
|
}else if(spanBelow && y < height - 1 && !tester.get(editor.tile(x1, y + 1))){
|
||||||
|
spanBelow = false;
|
||||||
|
}
|
||||||
|
x1++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
stack.clear();
|
||||||
|
}catch(OutOfMemoryError e){
|
||||||
|
//hack
|
||||||
|
stack = null;
|
||||||
|
System.gc();
|
||||||
|
e.printStackTrace();
|
||||||
|
stack = new IntArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import arc.struct.Array;
|
|||||||
import arc.math.Mathf;
|
import arc.math.Mathf;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import mindustry.entities.traits.Entity;
|
import mindustry.entities.traits.Entity;
|
||||||
import mindustry.entities.traits.SolidTrait;
|
|
||||||
import mindustry.world.Tile;
|
import mindustry.world.Tile;
|
||||||
|
|
||||||
import static mindustry.Vars.tilesize;
|
import static mindustry.Vars.tilesize;
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import mindustry.world.blocks.*;
|
|||||||
|
|
||||||
public class HealBulletType extends BulletType{
|
public class HealBulletType extends BulletType{
|
||||||
protected float healPercent = 3f;
|
protected float healPercent = 3f;
|
||||||
|
protected float bulletHeight = 7f, bulletWidth = 2f;
|
||||||
|
protected Color backColor = Pal.heal, frontColor = Color.white;
|
||||||
|
|
||||||
public HealBulletType(float speed, float damage){
|
public HealBulletType(float speed, float damage){
|
||||||
super(speed, damage);
|
super(speed, damage);
|
||||||
@@ -33,11 +35,11 @@ public class HealBulletType extends BulletType{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Bullet b){
|
public void draw(Bullet b){
|
||||||
Draw.color(Pal.heal);
|
Draw.color(backColor);
|
||||||
Lines.stroke(2f);
|
Lines.stroke(bulletWidth);
|
||||||
Lines.lineAngleCenter(b.x, b.y, b.rot(), 7f);
|
Lines.lineAngleCenter(b.x, b.y, b.rot(), bulletHeight);
|
||||||
Draw.color(Color.white);
|
Draw.color(frontColor);
|
||||||
Lines.lineAngleCenter(b.x, b.y, b.rot(), 3f);
|
Lines.lineAngleCenter(b.x, b.y, b.rot(), bulletHeight / 2f);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
73
core/src/mindustry/entities/bullet/LaserBulletType.java
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package mindustry.entities.bullet;
|
||||||
|
|
||||||
|
import arc.graphics.*;
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
|
import mindustry.entities.type.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
|
|
||||||
|
public class LaserBulletType extends BulletType{
|
||||||
|
protected Color[] colors = {Pal.lancerLaser.cpy().mul(1f, 1f, 1f, 0.4f), Pal.lancerLaser, Color.white};
|
||||||
|
protected float length = 160f;
|
||||||
|
protected float width = 15f;
|
||||||
|
protected float lengthFalloff = 0.5f;
|
||||||
|
protected float sideLength = 29f, sideWidth = 0.7f;
|
||||||
|
protected float sideAngle = 90f;
|
||||||
|
|
||||||
|
public LaserBulletType(float damage){
|
||||||
|
super(0.01f, damage);
|
||||||
|
|
||||||
|
keepVelocity = false;
|
||||||
|
hitEffect = Fx.hitLancer;
|
||||||
|
despawnEffect = Fx.none;
|
||||||
|
shootEffect = Fx.hitLancer;
|
||||||
|
smokeEffect = Fx.lancerLaserShootSmoke;
|
||||||
|
hitSize = 4;
|
||||||
|
lifetime = 16f;
|
||||||
|
pierce = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LaserBulletType(){
|
||||||
|
this(1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Bullet b){
|
||||||
|
float f = Mathf.curve(b.fin(), 0f, 0.2f);
|
||||||
|
float baseLen = length * f;
|
||||||
|
float cwidth = width;
|
||||||
|
float compound = 1f;
|
||||||
|
|
||||||
|
Lines.lineAngle(b.x, b.y, b.rot(), baseLen);
|
||||||
|
Lines.precise(true);
|
||||||
|
for(Color color : colors){
|
||||||
|
Draw.color(color);
|
||||||
|
Lines.stroke((cwidth *= lengthFalloff) * b.fout());
|
||||||
|
Lines.lineAngle(b.x, b.y, b.rot(), baseLen, CapStyle.none);
|
||||||
|
Tmp.v1.trns(b.rot(), baseLen);
|
||||||
|
Drawf.tri(b.x + Tmp.v1.x, b.y + Tmp.v1.y, Lines.getStroke() * 1.22f, cwidth * 2f + width / 2f, b.rot());
|
||||||
|
|
||||||
|
Fill.circle(b.x, b.y, 1f * cwidth * b.fout());
|
||||||
|
for(int i : Mathf.signs){
|
||||||
|
Drawf.tri(b.x, b.y, sideWidth * b.fout() * cwidth, sideLength * compound, b.rot() + sideAngle * i);
|
||||||
|
}
|
||||||
|
|
||||||
|
compound *= lengthFalloff;
|
||||||
|
}
|
||||||
|
Lines.precise(false);
|
||||||
|
Draw.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
30
core/src/mindustry/entities/bullet/LightningBulletType.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package mindustry.entities.bullet;
|
||||||
|
|
||||||
|
import arc.graphics.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.entities.effect.*;
|
||||||
|
import mindustry.entities.type.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
|
|
||||||
|
public class LightningBulletType extends BulletType{
|
||||||
|
protected Color lightningColor = Pal.lancerLaser;
|
||||||
|
protected int lightningLength = 25;
|
||||||
|
|
||||||
|
public LightningBulletType(){
|
||||||
|
super(0.0001f, 1f);
|
||||||
|
|
||||||
|
lifetime = 1;
|
||||||
|
despawnEffect = Fx.none;
|
||||||
|
hitEffect = Fx.hitLancer;
|
||||||
|
keepVelocity = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Bullet b){
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Bullet b){
|
||||||
|
Lightning.create(b.getTeam(), lightningColor, damage, b.x, b.y, b.rot(), lightningLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,22 @@
|
|||||||
package mindustry.entities.def;
|
package mindustry.entities.def;
|
||||||
|
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.Bits;
|
import arc.struct.Bits;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.pooling.*;
|
import arc.util.pooling.*;
|
||||||
|
import mindustry.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
|
import mindustry.entities.Effects.*;
|
||||||
import mindustry.entities.bullet.*;
|
import mindustry.entities.bullet.*;
|
||||||
|
import mindustry.entities.traits.*;
|
||||||
|
import mindustry.entities.type.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
@@ -23,19 +29,23 @@ import static mindustry.Vars.content;
|
|||||||
|
|
||||||
public class EntityComps{
|
public class EntityComps{
|
||||||
|
|
||||||
@Depends({HealthComp.class, VelComp.class, StatusComp.class, TeamComp.class, ItemsComp.class})
|
@Component({HealthComp.class, VelComp.class, StatusComp.class, TeamComp.class, ItemsComp.class})
|
||||||
class UnitComp{
|
class UnitComp{
|
||||||
//UnitDef type;
|
UnitDef type;
|
||||||
}
|
}
|
||||||
|
|
||||||
class OwnerComp{
|
class OwnerComp{
|
||||||
Entityc owner;
|
Entityc owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Depends({TimedComp.class})
|
@Component({TimedComp.class, DamageComp.class, Hitboxc.class})
|
||||||
class BulletComp{
|
class BulletComp{
|
||||||
BulletType bullet;
|
BulletType bullet;
|
||||||
|
|
||||||
|
float getDamage(){
|
||||||
|
return bullet.damage;
|
||||||
|
}
|
||||||
|
|
||||||
void init(){
|
void init(){
|
||||||
//TODO
|
//TODO
|
||||||
bullet.init(null);
|
bullet.init(null);
|
||||||
@@ -47,6 +57,12 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
abstract class DamageComp{
|
||||||
|
abstract float getDamage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
abstract class TimedComp extends EntityComp implements Scaled{
|
abstract class TimedComp extends EntityComp implements Scaled{
|
||||||
float time, lifetime;
|
float time, lifetime;
|
||||||
|
|
||||||
@@ -64,79 +80,339 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
class HealthComp{
|
class HealthComp{
|
||||||
float health, maxHealth;
|
float health, maxHealth, hitTime;
|
||||||
boolean dead;
|
boolean dead;
|
||||||
|
|
||||||
float healthf(){
|
float healthf(){
|
||||||
return health / maxHealth;
|
return health / maxHealth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update(){
|
||||||
|
hitTime -= Time.delta() / 9f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void killed(){
|
||||||
|
//implement by other components
|
||||||
|
}
|
||||||
|
|
||||||
|
void kill(){
|
||||||
|
health = 0;
|
||||||
|
dead = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void heal(){
|
||||||
|
dead = false;
|
||||||
|
health = maxHealth;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean damaged(){
|
||||||
|
return health <= maxHealth - 0.0001f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void damage(float amount){
|
||||||
|
health -= amount;
|
||||||
|
if(health <= 0 && !dead){
|
||||||
|
dead = true;
|
||||||
|
killed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clampHealth(){
|
||||||
|
health = Mathf.clamp(health, 0, maxHealth);
|
||||||
|
}
|
||||||
|
|
||||||
|
void heal(float amount){
|
||||||
|
health += amount;
|
||||||
|
clampHealth();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
class FlyingComp{
|
class FlyingComp{
|
||||||
boolean flying;
|
boolean flying;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
class LegsComp{
|
class LegsComp{
|
||||||
|
float baseRotation;
|
||||||
|
float drownTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
class RotComp{
|
class RotComp{
|
||||||
float rotation;
|
float rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
class TeamComp{
|
class TeamComp{
|
||||||
Team team = Team.sharded;
|
Team team = Team.sharded;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Depends(PosComp.class)
|
@Component({RotComp.class, PosComp.class})
|
||||||
class SyncComp{
|
static class WeaponsComp{
|
||||||
Interpolator interpolator;
|
transient float x, y, rotation;
|
||||||
|
|
||||||
|
/** 1 */
|
||||||
|
static final int[] one = {1};
|
||||||
|
/** minimum cursor distance from player, fixes 'cross-eyed' shooting */
|
||||||
|
static final float minAimDst = 20f;
|
||||||
|
/** temporary weapon sequence number */
|
||||||
|
static int sequenceNum = 0;
|
||||||
|
|
||||||
|
/** weapon mount array, never null */
|
||||||
|
WeaponMount[] mounts = {};
|
||||||
|
|
||||||
|
public void init(UnitDef def){
|
||||||
|
mounts = new WeaponMount[def.weapons.size];
|
||||||
|
for(int i = 0; i < mounts.length; i++){
|
||||||
|
mounts[i] = new WeaponMount(def.weapons.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Aim at something. This will make all mounts point at it. */
|
||||||
|
public void aim(Unit unit, float x, float y){
|
||||||
|
Tmp.v1.set(x, y).sub(unit.x, unit.y);
|
||||||
|
if(Tmp.v1.len() < minAimDst) Tmp.v1.setLength(minAimDst);
|
||||||
|
|
||||||
|
x = Tmp.v1.x + unit.x;
|
||||||
|
y = Tmp.v1.y + unit.y;
|
||||||
|
|
||||||
|
for(WeaponMount mount : mounts){
|
||||||
|
mount.aimX = x;
|
||||||
|
mount.aimY = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update shooting and rotation for this unit. */
|
||||||
|
public void update(Unit unit){
|
||||||
|
for(WeaponMount mount : mounts){
|
||||||
|
Weapon weapon = mount.weapon;
|
||||||
|
mount.reload -= Time.delta();
|
||||||
|
|
||||||
|
float rotation = unit.rotation - 90;
|
||||||
|
|
||||||
|
//rotate if applicable
|
||||||
|
if(weapon.rotate){
|
||||||
|
float axisXOffset = weapon.mirror ? 0f : weapon.x;
|
||||||
|
float axisX = unit.x + Angles.trnsx(rotation, axisXOffset, weapon.y),
|
||||||
|
axisY = unit.y + Angles.trnsy(rotation, axisXOffset, weapon.y);
|
||||||
|
|
||||||
|
mount.rotation = Angles.moveToward(mount.rotation, Angles.angle(axisX, axisY, mount.aimX, mount.aimY), weapon.rotateSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
//shoot if applicable
|
||||||
|
//TODO only shoot if angle is reached, don't shoot inaccurately
|
||||||
|
if(mount.reload <= 0){
|
||||||
|
for(int i : (weapon.mirror && !weapon.alternate ? Mathf.signs : one)){
|
||||||
|
i *= Mathf.sign(weapon.flipped) * Mathf.sign(mount.side);
|
||||||
|
|
||||||
|
//m a t h
|
||||||
|
float weaponRotation = rotation + (weapon.rotate ? mount.rotation : 0);
|
||||||
|
float mountX = unit.x + Angles.trnsx(rotation, weapon.x * i, weapon.y),
|
||||||
|
mountY = unit.y + Angles.trnsy(rotation, weapon.x * i, weapon.y);
|
||||||
|
float shootX = mountX + Angles.trnsx(weaponRotation, weapon.shootX * i, weapon.shootY),
|
||||||
|
shootY = mountY + Angles.trnsy(weaponRotation, weapon.shootX * i, weapon.shootY);
|
||||||
|
float shootAngle = weapon.rotate ? weaponRotation : Angles.angle(shootX, shootY, mount.aimX, mount.aimY);
|
||||||
|
|
||||||
|
shoot(unit, weapon, shootX, shootY, shootAngle);
|
||||||
|
}
|
||||||
|
|
||||||
|
mount.side = !mount.side;
|
||||||
|
mount.reload = weapon.reload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Draw weapon mounts. */
|
||||||
|
void draw(){
|
||||||
|
for(WeaponMount mount : mounts){
|
||||||
|
Weapon weapon = mount.weapon;
|
||||||
|
|
||||||
|
for(int i : (weapon.mirror ? Mathf.signs : one)){
|
||||||
|
i *= Mathf.sign(weapon.flipped);
|
||||||
|
|
||||||
|
float rotation = this.rotation - 90 + (weapon.rotate ? mount.rotation : 0);
|
||||||
|
float trY = weapon.y - (mount.reload / weapon.reload * weapon.recoil) * (weapon.alternate ? Mathf.num(i == Mathf.sign(mount.side)) : 1);
|
||||||
|
float width = i > 0 ? -weapon.region.getWidth() : weapon.region.getWidth();
|
||||||
|
|
||||||
|
Draw.rect(weapon.region,
|
||||||
|
x + Angles.trnsx(rotation, weapon.x * i, trY),
|
||||||
|
y + Angles.trnsy(rotation, weapon.x * i, trY),
|
||||||
|
width * Draw.scl,
|
||||||
|
weapon.region.getHeight() * Draw.scl,
|
||||||
|
rotation - 90);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shoot(ShooterTrait shooter, Weapon weapon, float x, float y, float rotation){
|
||||||
|
float baseX = shooter.getX(), baseY = shooter.getY();
|
||||||
|
|
||||||
|
weapon.shootSound.at(x, y, Mathf.random(0.8f, 1.0f));
|
||||||
|
|
||||||
|
sequenceNum = 0;
|
||||||
|
if(weapon.shotDelay > 0.01f){
|
||||||
|
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> {
|
||||||
|
Time.run(sequenceNum * weapon.shotDelay, () -> bullet(shooter, weapon, x + shooter.getX() - baseX, y + shooter.getY() - baseY, f + Mathf.range(weapon.inaccuracy)));
|
||||||
|
sequenceNum++;
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> bullet(shooter, weapon, x, y, f + Mathf.range(weapon.inaccuracy)));
|
||||||
|
}
|
||||||
|
|
||||||
|
BulletType ammo = weapon.bullet;
|
||||||
|
|
||||||
|
Tmp.v1.trns(rotation + 180f, ammo.recoil);
|
||||||
|
|
||||||
|
shooter.velocity().add(Tmp.v1);
|
||||||
|
|
||||||
|
Tmp.v1.trns(rotation, 3f);
|
||||||
|
boolean parentize = ammo.keepVelocity;
|
||||||
|
|
||||||
|
Effects.shake(weapon.shake, weapon.shake, x, y);
|
||||||
|
Effects.effect(weapon.ejectEffect, x, y, rotation);
|
||||||
|
Effects.effect(ammo.shootEffect, x + Tmp.v1.x, y + Tmp.v1.y, rotation, parentize ? shooter : null);
|
||||||
|
Effects.effect(ammo.smokeEffect, x + Tmp.v1.x, y + Tmp.v1.y, rotation, parentize ? shooter : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bullet(ShooterTrait owner, Weapon weapon, float x, float y, float angle){
|
||||||
|
Tmp.v1.trns(angle, 3f);
|
||||||
|
Bullet.create(weapon.bullet, owner, owner.getTeam(), x + Tmp.v1.x, y + Tmp.v1.y, angle, (1f - weapon.velocityRnd) + Mathf.random(weapon.velocityRnd));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class PosComp implements Position{
|
@Component
|
||||||
|
abstract class DrawComp{
|
||||||
|
//TODO ponder.
|
||||||
|
|
||||||
|
abstract float drawSize();
|
||||||
|
|
||||||
|
void draw(){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component(PosComp.class)
|
||||||
|
abstract class SyncComp extends PosComp{
|
||||||
|
Interpolator interpolator = new Interpolator();
|
||||||
|
|
||||||
|
void setNet(float x, float y){
|
||||||
|
set(x, y);
|
||||||
|
|
||||||
|
//TODO change interpolator API
|
||||||
|
if(interpolator != null){
|
||||||
|
interpolator.target.set(x, y);
|
||||||
|
interpolator.last.set(x, y);
|
||||||
|
interpolator.pos.set(0, 0);
|
||||||
|
interpolator.updateSpacing = 16;
|
||||||
|
interpolator.lastUpdated = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(){
|
||||||
|
if(Vars.net.client() && !isLocal()){
|
||||||
|
interpolate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void interpolate(){
|
||||||
|
interpolator.update();
|
||||||
|
x = interpolator.pos.x;
|
||||||
|
y = interpolator.pos.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
abstract class PosComp extends EntityComp implements Position{
|
||||||
float x, y;
|
float x, y;
|
||||||
|
|
||||||
void set(float x, float y){
|
void set(float x, float y){
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void trns(float x, float y){
|
||||||
|
set(this.x + x, this.y + y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class DamageComp{
|
@Component
|
||||||
abstract float getDamage();
|
|
||||||
}
|
|
||||||
|
|
||||||
class MinerComp{
|
class MinerComp{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
class BuilderComp{
|
class BuilderComp{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
class ItemsComp{
|
class ItemsComp{
|
||||||
ItemStack item = new ItemStack();
|
ItemStack item = new ItemStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Depends(PosComp.class)
|
@Component(VelComp.class)
|
||||||
class VelComp{
|
class MassComp{
|
||||||
transient float x, y;
|
float mass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({PosComp.class, DrawComp.class, TimedComp.class})
|
||||||
|
class EffectComp extends EntityComp{
|
||||||
|
Effect effect;
|
||||||
|
Color color = new Color(Color.white);
|
||||||
|
Object data;
|
||||||
|
float rotation = 0f;
|
||||||
|
|
||||||
|
void draw(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(){
|
||||||
|
//TODO fix effects, make everything poolable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
abstract class VelComp extends PosComp{
|
||||||
final Vec2 vel = new Vec2();
|
final Vec2 vel = new Vec2();
|
||||||
|
float drag = 0f;
|
||||||
|
|
||||||
void update(){
|
void update(){
|
||||||
x += vel.x;
|
x += vel.x;
|
||||||
y += vel.y;
|
y += vel.y;
|
||||||
vel.scl(0.9f);
|
vel.scl(1f - drag * Time.delta());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Depends(PosComp.class)
|
@Component(PosComp.class)
|
||||||
class HitboxComp{
|
class HitboxComp{
|
||||||
transient float x, y;
|
transient float x, y;
|
||||||
|
|
||||||
float hitSize;
|
float hitSize;
|
||||||
|
float lastX, lastY;
|
||||||
|
|
||||||
|
void update(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateLastPosition(){
|
||||||
|
lastX = x;
|
||||||
|
lastY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void collision(Hitboxc other){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
float getDeltaX(){
|
||||||
|
return x - lastX;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getDeltaY(){
|
||||||
|
return y - lastY;
|
||||||
|
}
|
||||||
|
|
||||||
boolean collides(Hitboxc other){
|
boolean collides(Hitboxc other){
|
||||||
return Intersector.overlapsRect(x - hitSize/2f, y - hitSize/2f, hitSize, hitSize,
|
return Intersector.overlapsRect(x - hitSize/2f, y - hitSize/2f, hitSize, hitSize,
|
||||||
@@ -144,7 +420,7 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Depends(PosComp.class)
|
@Component(PosComp.class)
|
||||||
class StatusComp{
|
class StatusComp{
|
||||||
private Array<StatusEntry> statuses = new Array<>();
|
private Array<StatusEntry> statuses = new Array<>();
|
||||||
private Bits applied = new Bits(content.getBy(ContentType.status).size);
|
private Bits applied = new Bits(content.getBy(ContentType.status).size);
|
||||||
@@ -258,6 +534,7 @@ public class EntityComps{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
@BaseComponent
|
@BaseComponent
|
||||||
class EntityComp{
|
class EntityComp{
|
||||||
int id;
|
int id;
|
||||||
@@ -268,6 +545,11 @@ public class EntityComps{
|
|||||||
|
|
||||||
void remove(){}
|
void remove(){}
|
||||||
|
|
||||||
|
boolean isLocal(){
|
||||||
|
//TODO fix
|
||||||
|
return this == (Object)Vars.player;
|
||||||
|
}
|
||||||
|
|
||||||
<T> T as(Class<T> type){
|
<T> T as(Class<T> type){
|
||||||
return (T)this;
|
return (T)this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import arc.math.Mathf;
|
|||||||
import mindustry.entities.EntityGroup;
|
import mindustry.entities.EntityGroup;
|
||||||
import mindustry.entities.type.TimedEntity;
|
import mindustry.entities.type.TimedEntity;
|
||||||
import mindustry.entities.traits.BelowLiquidTrait;
|
import mindustry.entities.traits.BelowLiquidTrait;
|
||||||
import mindustry.entities.traits.DrawTrait;
|
|
||||||
import mindustry.graphics.Pal;
|
import mindustry.graphics.Pal;
|
||||||
|
|
||||||
import static mindustry.Vars.groundEffectGroup;
|
import static mindustry.Vars.groundEffectGroup;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import arc.util.Time;
|
|||||||
import arc.util.pooling.Pools;
|
import arc.util.pooling.Pools;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.type.TimedEntity;
|
import mindustry.entities.type.TimedEntity;
|
||||||
import mindustry.entities.traits.DrawTrait;
|
|
||||||
import mindustry.entities.type.Unit;
|
import mindustry.entities.type.Unit;
|
||||||
import mindustry.graphics.Pal;
|
import mindustry.graphics.Pal;
|
||||||
import mindustry.type.Item;
|
import mindustry.type.Item;
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ import mindustry.entities.EntityGroup;
|
|||||||
import mindustry.entities.Units;
|
import mindustry.entities.Units;
|
||||||
import mindustry.entities.type.Bullet;
|
import mindustry.entities.type.Bullet;
|
||||||
import mindustry.entities.type.TimedEntity;
|
import mindustry.entities.type.TimedEntity;
|
||||||
import mindustry.entities.traits.DrawTrait;
|
|
||||||
import mindustry.entities.traits.TimeTrait;
|
|
||||||
import mindustry.entities.type.Unit;
|
import mindustry.entities.type.Unit;
|
||||||
import mindustry.game.Team;
|
import mindustry.game.Team;
|
||||||
import mindustry.gen.Call;
|
import mindustry.gen.Call;
|
||||||
|
|||||||
@@ -67,9 +67,9 @@ public interface BuilderTrait extends Entity, TeamTrait{
|
|||||||
|
|
||||||
if(!(tile.block() instanceof BuildBlock)){
|
if(!(tile.block() instanceof BuildBlock)){
|
||||||
if(!current.initialized && canCreateBlocks() && !current.breaking && Build.validPlace(getTeam(), current.x, current.y, current.block, current.rotation)){
|
if(!current.initialized && canCreateBlocks() && !current.breaking && Build.validPlace(getTeam(), current.x, current.y, current.block, current.rotation)){
|
||||||
Call.beginPlace(getTeam(), current.x, current.y, current.block, current.rotation);
|
Build.beginPlace(getTeam(), current.x, current.y, current.block, current.rotation);
|
||||||
}else if(!current.initialized && canCreateBlocks() && current.breaking && Build.validBreak(getTeam(), current.x, current.y)){
|
}else if(!current.initialized && canCreateBlocks() && current.breaking && Build.validBreak(getTeam(), current.x, current.y)){
|
||||||
Call.beginBreak(getTeam(), current.x, current.y);
|
Build.beginBreak(getTeam(), current.x, current.y);
|
||||||
}else{
|
}else{
|
||||||
buildQueue().removeFirst();
|
buildQueue().removeFirst();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
public interface DamageTrait{
|
|
||||||
float damage();
|
|
||||||
|
|
||||||
default void killed(Entity other){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
public interface DrawTrait extends Entity{
|
|
||||||
|
|
||||||
default float drawSize(){
|
|
||||||
return 20f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw();
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.entities.traits;
|
package mindustry.entities.traits;
|
||||||
|
|
||||||
import mindustry.entities.EntityGroup;
|
import mindustry.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
|
|
||||||
public interface Entity extends MoveTrait{
|
public interface Entity extends MoveTrait{
|
||||||
|
|
||||||
@@ -14,6 +15,14 @@ public interface Entity extends MoveTrait{
|
|||||||
|
|
||||||
default void added(){}
|
default void added(){}
|
||||||
|
|
||||||
|
default int tileX(){
|
||||||
|
return Vars.world.toTile(getX());
|
||||||
|
}
|
||||||
|
|
||||||
|
default int tileY(){
|
||||||
|
return Vars.world.toTile(getY());
|
||||||
|
}
|
||||||
|
|
||||||
EntityGroup targetGroup();
|
EntityGroup targetGroup();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
import arc.math.Mathf;
|
|
||||||
|
|
||||||
public interface HealthTrait{
|
|
||||||
|
|
||||||
void health(float health);
|
|
||||||
|
|
||||||
float health();
|
|
||||||
|
|
||||||
float maxHealth();
|
|
||||||
|
|
||||||
boolean isDead();
|
|
||||||
|
|
||||||
void setDead(boolean dead);
|
|
||||||
|
|
||||||
default void kill(){
|
|
||||||
health(-1);
|
|
||||||
damage(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
default void onHit(SolidTrait entity){
|
|
||||||
}
|
|
||||||
|
|
||||||
default void onDeath(){
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean damaged(){
|
|
||||||
return health() < maxHealth() - 0.0001f;
|
|
||||||
}
|
|
||||||
|
|
||||||
default void damage(float amount){
|
|
||||||
health(health() - amount);
|
|
||||||
if(health() <= 0 && !isDead()){
|
|
||||||
onDeath();
|
|
||||||
setDead(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default void clampHealth(){
|
|
||||||
health(Mathf.clamp(health(), 0, maxHealth()));
|
|
||||||
}
|
|
||||||
|
|
||||||
default float healthf(){
|
|
||||||
return health() / maxHealth();
|
|
||||||
}
|
|
||||||
|
|
||||||
default void healBy(float amount){
|
|
||||||
health(health() + amount);
|
|
||||||
clampHealth();
|
|
||||||
}
|
|
||||||
|
|
||||||
default void heal(){
|
|
||||||
health(maxHealth());
|
|
||||||
setDead(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
public interface KillerTrait{
|
|
||||||
void killed(Entity other);
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
import arc.math.geom.Position;
|
|
||||||
|
|
||||||
public interface MoveTrait extends Position{
|
|
||||||
|
|
||||||
void setX(float x);
|
|
||||||
|
|
||||||
void setY(float y);
|
|
||||||
|
|
||||||
default void moveBy(float x, float y){
|
|
||||||
setX(getX() + x);
|
|
||||||
setY(getY() + y);
|
|
||||||
}
|
|
||||||
|
|
||||||
default void set(float x, float y){
|
|
||||||
setX(x);
|
|
||||||
setY(y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
import arc.util.Interval;
|
|
||||||
import mindustry.type.Weapon;
|
|
||||||
|
|
||||||
public interface ShooterTrait extends VelocityTrait, TeamTrait{
|
|
||||||
|
|
||||||
Interval getTimer();
|
|
||||||
|
|
||||||
int getShootTimer(boolean left);
|
|
||||||
|
|
||||||
Weapon getWeapon();
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
|
|
||||||
import arc.math.geom.*;
|
|
||||||
import arc.math.geom.QuadTree.QuadTreeObject;
|
|
||||||
import mindustry.Vars;
|
|
||||||
|
|
||||||
public interface SolidTrait extends QuadTreeObject, MoveTrait, VelocityTrait, Entity, Position{
|
|
||||||
|
|
||||||
void hitbox(Rect rect);
|
|
||||||
|
|
||||||
void hitboxTile(Rect rect);
|
|
||||||
|
|
||||||
Vec2 lastPosition();
|
|
||||||
|
|
||||||
default boolean collidesGrid(int x, int y){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
default float getDeltaX(){
|
|
||||||
return getX() - lastPosition().x;
|
|
||||||
}
|
|
||||||
|
|
||||||
default float getDeltaY(){
|
|
||||||
return getY() - lastPosition().y;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean collides(SolidTrait other){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
default void collision(SolidTrait other, float x, float y){
|
|
||||||
}
|
|
||||||
|
|
||||||
default void move(float x, float y){
|
|
||||||
Vars.collisions.move(this, x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
import mindustry.net.Interpolator;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
public interface SyncTrait extends Entity, TypeTrait{
|
|
||||||
|
|
||||||
/** Sets the position of this entity and updated the interpolator. */
|
|
||||||
default void setNet(float x, float y){
|
|
||||||
set(x, y);
|
|
||||||
|
|
||||||
if(getInterpolator() != null){
|
|
||||||
getInterpolator().target.set(x, y);
|
|
||||||
getInterpolator().last.set(x, y);
|
|
||||||
getInterpolator().pos.set(0, 0);
|
|
||||||
getInterpolator().updateSpacing = 16;
|
|
||||||
getInterpolator().lastUpdated = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Interpolate entity position only. Override if you need to interpolate rotations or other values. */
|
|
||||||
default void interpolate(){
|
|
||||||
if(getInterpolator() == null){
|
|
||||||
throw new RuntimeException("This entity must have an interpolator to interpolate()!");
|
|
||||||
}
|
|
||||||
|
|
||||||
getInterpolator().update();
|
|
||||||
|
|
||||||
setX(getInterpolator().pos.x);
|
|
||||||
setY(getInterpolator().pos.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the interpolator used for smoothing the position. Optional. */
|
|
||||||
default Interpolator getInterpolator(){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Read and write sync data, usually position
|
|
||||||
void write(DataOutput data) throws IOException;
|
|
||||||
|
|
||||||
void read(DataInput data) throws IOException;
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
import arc.math.geom.Position;
|
|
||||||
import mindustry.game.Team;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base interface for targetable entities.
|
|
||||||
*/
|
|
||||||
public interface TargetTrait extends Position, VelocityTrait{
|
|
||||||
|
|
||||||
boolean isDead();
|
|
||||||
|
|
||||||
Team getTeam();
|
|
||||||
|
|
||||||
default float getTargetVelocityX(){
|
|
||||||
if(this instanceof SolidTrait){
|
|
||||||
return ((SolidTrait)this).getDeltaX();
|
|
||||||
}
|
|
||||||
return velocity().x;
|
|
||||||
}
|
|
||||||
|
|
||||||
default float getTargetVelocityY(){
|
|
||||||
if(this instanceof SolidTrait){
|
|
||||||
return ((SolidTrait)this).getDeltaY();
|
|
||||||
}
|
|
||||||
return velocity().y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether this entity is a valid target.
|
|
||||||
*/
|
|
||||||
default boolean isValid(){
|
|
||||||
return !isDead();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
import mindustry.game.Team;
|
|
||||||
|
|
||||||
public interface TeamTrait extends Entity{
|
|
||||||
Team getTeam();
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
import arc.math.*;
|
|
||||||
import arc.util.Time;
|
|
||||||
|
|
||||||
public interface TimeTrait extends Scaled, Entity{
|
|
||||||
|
|
||||||
float lifetime();
|
|
||||||
|
|
||||||
void time(float time);
|
|
||||||
|
|
||||||
float time();
|
|
||||||
|
|
||||||
default void updateTime(){
|
|
||||||
time(Mathf.clamp(time() + Time.delta(), 0, lifetime()));
|
|
||||||
|
|
||||||
if(time() >= lifetime()){
|
|
||||||
remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//fin() is not implemented due to compiler issues with iOS/RoboVM
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
import mindustry.type.TypeID;
|
|
||||||
|
|
||||||
public interface TypeTrait{
|
|
||||||
|
|
||||||
TypeID getTypeID();
|
|
||||||
/*
|
|
||||||
int[] lastRegisteredID = {0};
|
|
||||||
Array<Supplier<? extends TypeTrait>> registeredTypes = new Array<>();
|
|
||||||
ObjectIntMap<Class<? extends TypeTrait>> typeToID = new ObjectIntMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register and return a type ID. The supplier should return a fresh instace of that type.
|
|
||||||
|
|
||||||
static <T extends TypeTrait> void registerType(Class<T> type, Supplier<T> supplier){
|
|
||||||
if(typeToID.get(type, -1) != -1){
|
|
||||||
return; //already registered
|
|
||||||
}
|
|
||||||
|
|
||||||
registeredTypes.add(supplier);
|
|
||||||
int result = lastRegisteredID[0];
|
|
||||||
typeToID.put(type, result);
|
|
||||||
lastRegisteredID[0]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**Gets a syncable type by ID.
|
|
||||||
static Supplier<? extends TypeTrait> getTypeByID(int id){
|
|
||||||
if(id == -1){
|
|
||||||
throw new IllegalArgumentException("Attempt to retrieve invalid entity type ID! Did you forget to set it in ContentLoader.registerTypes()?");
|
|
||||||
}
|
|
||||||
return registeredTypes.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the type ID of this entity used for intstantiation. Should be < BYTE_MAX.
|
|
||||||
* Do not override!
|
|
||||||
|
|
||||||
default int getTypeID(){
|
|
||||||
int id = typeToID.get(getClass(), -1);
|
|
||||||
if(id == -1)
|
|
||||||
throw new RuntimeException("Class of type '" + getClass() + "' is not registered! Did you forget to register it in ContentLoader#registerTypes()?");
|
|
||||||
return id;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package mindustry.entities.traits;
|
|
||||||
|
|
||||||
import arc.math.geom.Vec2;
|
|
||||||
import arc.util.Time;
|
|
||||||
|
|
||||||
public interface VelocityTrait extends MoveTrait{
|
|
||||||
|
|
||||||
Vec2 velocity();
|
|
||||||
|
|
||||||
default void applyImpulse(float x, float y){
|
|
||||||
velocity().x += x / mass();
|
|
||||||
velocity().y += y / mass();
|
|
||||||
}
|
|
||||||
|
|
||||||
default float maxVelocity(){
|
|
||||||
return Float.MAX_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
default float mass(){
|
|
||||||
return 1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
default float drag(){
|
|
||||||
return 0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
default void updateVelocity(){
|
|
||||||
velocity().scl(1f - drag() * Time.delta());
|
|
||||||
|
|
||||||
if(this instanceof SolidTrait){
|
|
||||||
((SolidTrait)this).move(velocity().x * Time.delta(), velocity().y * Time.delta());
|
|
||||||
}else{
|
|
||||||
moveBy(velocity().x * Time.delta(), velocity().y * Time.delta());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,14 +15,6 @@ public abstract class BaseEntity implements Entity{
|
|||||||
id = lastid++;
|
id = lastid++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int tileX(){
|
|
||||||
return Vars.world.toTile(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int tileY(){
|
|
||||||
return Vars.world.toTile(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getID(){
|
public int getID(){
|
||||||
return id;
|
return id;
|
||||||
|
|||||||
@@ -36,11 +36,9 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
|||||||
|
|
||||||
protected static final int timerTarget = timerIndex++;
|
protected static final int timerTarget = timerIndex++;
|
||||||
protected static final int timerTarget2 = timerIndex++;
|
protected static final int timerTarget2 = timerIndex++;
|
||||||
protected static final int timerShootLeft = timerIndex++;
|
|
||||||
protected static final int timerShootRight = timerIndex++;
|
|
||||||
|
|
||||||
protected boolean loaded;
|
protected boolean loaded;
|
||||||
protected UnitType type;
|
protected UnitDef type;
|
||||||
protected Interval timer = new Interval(5);
|
protected Interval timer = new Interval(5);
|
||||||
protected StateMachine state = new StateMachine();
|
protected StateMachine state = new StateMachine();
|
||||||
protected TargetTrait target;
|
protected TargetTrait target;
|
||||||
@@ -76,11 +74,6 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
|||||||
Core.app.post(unit::remove);
|
Core.app.post(unit::remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public float drag(){
|
|
||||||
return type.drag;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeID getTypeID(){
|
public TypeID getTypeID(){
|
||||||
return type.typeID;
|
return type.typeID;
|
||||||
@@ -119,7 +112,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Initialize the type and team of this unit. Only call once! */
|
/** Initialize the type and team of this unit. Only call once! */
|
||||||
public void init(UnitType type, Team team){
|
public void init(UnitDef type, Team team){
|
||||||
if(this.type != null) throw new RuntimeException("This unit is already initialized!");
|
if(this.type != null) throw new RuntimeException("This unit is already initialized!");
|
||||||
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
@@ -131,16 +124,12 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnitType getType(){
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSpawner(Tile tile){
|
public void setSpawner(Tile tile){
|
||||||
this.spawner = tile.pos();
|
this.spawner = tile.pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rotate(float angle){
|
public void rotate(float angle){
|
||||||
rotation = Mathf.slerpDelta(rotation, angle, type.rotatespeed);
|
rotation = Mathf.slerpDelta(rotation, angle, type.rotateSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean targetHasFlag(BlockFlag flag){
|
public boolean targetHasFlag(BlockFlag flag){
|
||||||
@@ -179,7 +168,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void targetClosest(){
|
public void targetClosest(){
|
||||||
TargetTrait newTarget = Units.closestTarget(team, x, y, Math.max(getWeapon().bullet.range(), type.range), u -> type.targetAir || !u.isFlying());
|
TargetTrait newTarget = Units.closestTarget(team, x, y, type.range, u -> type.targetAir || !u.isFlying());
|
||||||
if(newTarget != null){
|
if(newTarget != null){
|
||||||
target = newTarget;
|
target = newTarget;
|
||||||
}
|
}
|
||||||
@@ -210,41 +199,11 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
|||||||
return status.getDamageMultiplier() * Vars.state.rules.unitDamageMultiplier;
|
return status.getDamageMultiplier() * Vars.state.rules.unitDamageMultiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isImmune(StatusEffect effect){
|
|
||||||
return type.immunities.contains(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isValid(){
|
|
||||||
return super.isValid() && isAdded();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Interval getTimer(){
|
|
||||||
return timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getShootTimer(boolean left){
|
|
||||||
return left ? timerShootLeft : timerShootRight;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Weapon getWeapon(){
|
|
||||||
return type.weapon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TextureRegion getIconRegion(){
|
public TextureRegion getIconRegion(){
|
||||||
return type.icon(Cicon.full);
|
return type.icon(Cicon.full);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCapacity(){
|
|
||||||
return type.itemCapacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void interpolate(){
|
public void interpolate(){
|
||||||
super.interpolate();
|
super.interpolate();
|
||||||
@@ -259,16 +218,6 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
|||||||
return type.health * Vars.state.rules.unitHealthMultiplier;
|
return type.health * Vars.state.rules.unitHealthMultiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public float mass(){
|
|
||||||
return type.mass;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFlying(){
|
|
||||||
return type.flying;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
if(isDead()){
|
if(isDead()){
|
||||||
@@ -312,11 +261,6 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public float maxVelocity(){
|
|
||||||
return type.maxVelocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removed(){
|
public void removed(){
|
||||||
super.removed();
|
super.removed();
|
||||||
@@ -351,16 +295,6 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void hitbox(Rect rect){
|
|
||||||
rect.setSize(type.hitsize).setCenter(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void hitboxTile(Rect rect){
|
|
||||||
rect.setSize(type.hitsizeTile).setCenter(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityGroup targetGroup(){
|
public EntityGroup targetGroup(){
|
||||||
return unitGroup;
|
return unitGroup;
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
package mindustry.entities.type;
|
|
||||||
|
|
||||||
|
|
||||||
import mindustry.entities.traits.*;
|
|
||||||
|
|
||||||
public abstract class DestructibleEntity extends SolidEntity implements HealthTrait{
|
|
||||||
public transient boolean dead;
|
|
||||||
public float health;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean collides(SolidTrait other){
|
|
||||||
return other instanceof DamageTrait;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void collision(SolidTrait other, float x, float y){
|
|
||||||
if(other instanceof DamageTrait){
|
|
||||||
boolean wasDead = isDead();
|
|
||||||
onHit(other);
|
|
||||||
damage(((DamageTrait)other).damage());
|
|
||||||
if(!wasDead && isDead()){
|
|
||||||
((DamageTrait)other).killed(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void health(float health){
|
|
||||||
this.health = health;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float health(){
|
|
||||||
return health;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDead(){
|
|
||||||
return dead;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDead(boolean dead){
|
|
||||||
this.dead = dead;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,11 @@
|
|||||||
package mindustry.entities.type;
|
package mindustry.entities.type;
|
||||||
|
|
||||||
import arc.graphics.Color;
|
import arc.graphics.*;
|
||||||
import arc.util.pooling.Pool.Poolable;
|
import arc.util.pooling.Pool.*;
|
||||||
import arc.util.pooling.Pools;
|
import arc.util.pooling.*;
|
||||||
import mindustry.entities.Effects;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.Effects.Effect;
|
import mindustry.entities.Effects.*;
|
||||||
import mindustry.entities.EntityGroup;
|
import mindustry.entities.traits.*;
|
||||||
import mindustry.entities.traits.DrawTrait;
|
|
||||||
import mindustry.entities.traits.Entity;
|
|
||||||
|
|
||||||
import static mindustry.Vars.effectGroup;
|
import static mindustry.Vars.effectGroup;
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,6 @@ import static mindustry.Vars.*;
|
|||||||
public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
||||||
public static final int timerSync = 2;
|
public static final int timerSync = 2;
|
||||||
public static final int timerAbility = 3;
|
public static final int timerAbility = 3;
|
||||||
private static final int timerShootLeft = 0;
|
|
||||||
private static final int timerShootRight = 1;
|
|
||||||
private static final float liftoffBoost = 0.2f;
|
private static final float liftoffBoost = 0.2f;
|
||||||
|
|
||||||
private static final Rect rect = new Rect();
|
private static final Rect rect = new Rect();
|
||||||
@@ -53,7 +51,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
public float boostHeat, shootHeat, destructTime;
|
public float boostHeat, shootHeat, destructTime;
|
||||||
public boolean achievedFlight;
|
public boolean achievedFlight;
|
||||||
public Color color = new Color();
|
public Color color = new Color();
|
||||||
public Mech mech = Mechs.starter;
|
public UnitDef mech = Mechs.starter;
|
||||||
public SpawnerTrait spawner, lastSpawner;
|
public SpawnerTrait spawner, lastSpawner;
|
||||||
public int respawns;
|
public int respawns;
|
||||||
|
|
||||||
@@ -90,16 +88,6 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
return status.getDamageMultiplier() * state.rules.playerDamageMultiplier;
|
return status.getDamageMultiplier() * state.rules.playerDamageMultiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void hitbox(Rect rect){
|
|
||||||
rect.setSize(mech.hitsize).setCenter(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void hitboxTile(Rect rect){
|
|
||||||
rect.setSize(mech.hitsize * 2f / 3f).setCenter(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRespawn(Tile tile){
|
public void onRespawn(Tile tile){
|
||||||
velocity.setZero();
|
velocity.setZero();
|
||||||
@@ -127,6 +115,16 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
return TypeIDs.player;
|
return TypeIDs.player;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UnitDef type(){
|
||||||
|
return mech;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Weapons getWeapons(){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void move(float x, float y){
|
public void move(float x, float y){
|
||||||
if(!mech.flying){
|
if(!mech.flying){
|
||||||
@@ -136,29 +134,9 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public float drag(){
|
|
||||||
return mech.drag;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Interval getTimer(){
|
|
||||||
return timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getShootTimer(boolean left){
|
|
||||||
return left ? timerShootLeft : timerShootRight;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Weapon getWeapon(){
|
|
||||||
return mech.weapon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getMinePower(){
|
public float getMinePower(){
|
||||||
return mech.mineSpeed;
|
return mech.minePower;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -166,11 +144,6 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
return mech.icon(Cicon.full);
|
return mech.icon(Cicon.full);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCapacity(){
|
|
||||||
return mech.itemCapacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void interpolate(){
|
public void interpolate(){
|
||||||
super.interpolate();
|
super.interpolate();
|
||||||
@@ -206,7 +179,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canMine(Item item){
|
public boolean canMine(Item item){
|
||||||
return item.hardness <= mech.drillPower;
|
return item.hardness <= mech.drillTier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -247,11 +220,6 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
this.y = y;
|
this.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public float maxVelocity(){
|
|
||||||
return mech.maxSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Queue<BuildRequest> buildQueue(){
|
public Queue<BuildRequest> buildQueue(){
|
||||||
return placeQueue;
|
return placeQueue;
|
||||||
@@ -312,7 +280,10 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
float boostTrnsX = boostHeat * 3f;
|
float boostTrnsX = boostHeat * 3f;
|
||||||
float boostAng = boostHeat * 40f;
|
float boostAng = boostHeat * 40f;
|
||||||
|
|
||||||
|
float light = 0.2f;
|
||||||
|
|
||||||
for(int i : Mathf.signs){
|
for(int i : Mathf.signs){
|
||||||
|
Draw.colorl(1f-light + Mathf.clamp(ft * i, 0, 1) *light);
|
||||||
Draw.rect(mech.legRegion,
|
Draw.rect(mech.legRegion,
|
||||||
x + Angles.trnsx(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i),
|
x + Angles.trnsx(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i),
|
||||||
y + Angles.trnsy(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i),
|
y + Angles.trnsy(baseRotation, ft * i + boostTrnsY, -boostTrnsX * i),
|
||||||
@@ -320,6 +291,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
(mech.legRegion.getHeight() - Mathf.clamp(ft * i, 0, 2)) * Draw.scl,
|
(mech.legRegion.getHeight() - Mathf.clamp(ft * i, 0, 2)) * Draw.scl,
|
||||||
baseRotation - 90 + boostAng * i);
|
baseRotation - 90 + boostAng * i);
|
||||||
}
|
}
|
||||||
|
Draw.color();
|
||||||
|
|
||||||
Draw.rect(mech.baseRegion, x, y, baseRotation - 90);
|
Draw.rect(mech.baseRegion, x, y, baseRotation - 90);
|
||||||
}
|
}
|
||||||
@@ -333,18 +305,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
Draw.rect(mech.region, x, y, rotation - 90);
|
Draw.rect(mech.region, x, y, rotation - 90);
|
||||||
|
|
||||||
mech.draw(this);
|
mech.draw(this);
|
||||||
|
weapons.draw(this);
|
||||||
for(int i : Mathf.signs){
|
|
||||||
float tra = rotation - 90, trY = -mech.weapon.getRecoil(this, i > 0) + mech.weaponOffsetY;
|
|
||||||
float w = i > 0 ? -mech.weapon.region.getWidth() : mech.weapon.region.getWidth();
|
|
||||||
Draw.rect(mech.weapon.region,
|
|
||||||
x + Angles.trnsx(tra, (mech.weaponOffsetX + mech.spreadX(this)) * i, trY),
|
|
||||||
y + Angles.trnsy(tra, (mech.weaponOffsetX + mech.spreadX(this)) * i, trY),
|
|
||||||
w * Draw.scl,
|
|
||||||
mech.weapon.region.getHeight() * Draw.scl,
|
|
||||||
rotation - 90);
|
|
||||||
}
|
|
||||||
|
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,7 +483,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
|
|
||||||
boostHeat = Mathf.lerpDelta(boostHeat, (tile != null && tile.solid()) || (isBoosting && ((!movement.isZero() && moved) || !isLocal)) ? 1f : 0f, 0.08f);
|
boostHeat = Mathf.lerpDelta(boostHeat, (tile != null && tile.solid()) || (isBoosting && ((!movement.isZero() && moved) || !isLocal)) ? 1f : 0f, 0.08f);
|
||||||
shootHeat = Mathf.lerpDelta(shootHeat, isShooting() ? 1f : 0f, 0.06f);
|
shootHeat = Mathf.lerpDelta(shootHeat, isShooting() ? 1f : 0f, 0.06f);
|
||||||
mech.updateAlt(this); //updated regardless
|
mech.update(this); //updated regardless
|
||||||
|
|
||||||
if(boostHeat > liftoffBoost + 0.1f){
|
if(boostHeat > liftoffBoost + 0.1f){
|
||||||
achievedFlight = true;
|
achievedFlight = true;
|
||||||
@@ -530,9 +491,6 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
|
|
||||||
if(boostHeat <= liftoffBoost + 0.05f && achievedFlight && !mech.flying){
|
if(boostHeat <= liftoffBoost + 0.05f && achievedFlight && !mech.flying){
|
||||||
if(tile != null){
|
if(tile != null){
|
||||||
if(mech.shake > 1f){
|
|
||||||
Effects.shake(mech.shake, mech.shake, this);
|
|
||||||
}
|
|
||||||
Effects.effect(Fx.unitLand, tile.floor().color, x, y, tile.floor().isLiquid ? 1f : 0.5f);
|
Effects.effect(Fx.unitLand, tile.floor().color, x, y, tile.floor().isLiquid ? 1f : 0.5f);
|
||||||
}
|
}
|
||||||
mech.onLand(this);
|
mech.onLand(this);
|
||||||
@@ -620,7 +578,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
|
|
||||||
if(canMove){
|
if(canMove){
|
||||||
float baseLerp = mech.getRotationAlpha(this);
|
float baseLerp = mech.getRotationAlpha(this);
|
||||||
if(!isShooting() || !mech.turnCursor){
|
if(!isShooting() || !mech.faceTarget){
|
||||||
if(!movement.isZero()){
|
if(!movement.isZero()){
|
||||||
rotation = Mathf.slerpDelta(rotation, mech.flying ? velocity.angle() : movement.angle(), 0.13f * baseLerp);
|
rotation = Mathf.slerpDelta(rotation, mech.flying ? velocity.angle() : movement.angle(), 0.13f * baseLerp);
|
||||||
}
|
}
|
||||||
@@ -633,18 +591,19 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
|
|
||||||
protected void updateShooting(){
|
protected void updateShooting(){
|
||||||
if(!state.isEditor() && isShooting() && mech.canShoot(this)){
|
if(!state.isEditor() && isShooting() && mech.canShoot(this)){
|
||||||
if(!mech.turnCursor){
|
weapons.update(this);
|
||||||
|
//if(!mech.turnCursor){
|
||||||
//shoot forward ignoring cursor
|
//shoot forward ignoring cursor
|
||||||
mech.weapon.update(this, x + Angles.trnsx(rotation, mech.weapon.targetDistance), y + Angles.trnsy(rotation, mech.weapon.targetDistance));
|
//mech.weapon.update(this, x + Angles.trnsx(rotation, mech.weapon.targetDistance), y + Angles.trnsy(rotation, mech.weapon.targetDistance));
|
||||||
}else{
|
//}else{
|
||||||
mech.weapon.update(this, pointerX, pointerY);
|
//mech.weapon.update(this, pointerX, pointerY);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateTouch(){
|
protected void updateTouch(){
|
||||||
if(Units.invalidateTarget(target, this) &&
|
if(Units.invalidateTarget(target, this) &&
|
||||||
!(target instanceof TileEntity && ((TileEntity)target).damaged() && target.isValid() && target.getTeam() == team && mech.canHeal && dst(target) < getWeapon().bullet.range() && !(((TileEntity)target).block instanceof BuildBlock))){
|
!(target instanceof TileEntity && ((TileEntity)target).damaged() && target.isValid() && target.getTeam() == team && mech.canHeal && dst(target) < mech.range && !(((TileEntity)target).block instanceof BuildBlock))){
|
||||||
target = null;
|
target = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -720,11 +679,11 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
if(target == null){
|
if(target == null){
|
||||||
isShooting = false;
|
isShooting = false;
|
||||||
if(Core.settings.getBool("autotarget")){
|
if(Core.settings.getBool("autotarget")){
|
||||||
target = Units.closestTarget(team, x, y, getWeapon().bullet.range(), u -> u.getTeam() != Team.derelict, u -> u.getTeam() != Team.derelict);
|
target = Units.closestTarget(team, x, y, mech.range, u -> u.getTeam() != Team.derelict, u -> u.getTeam() != Team.derelict);
|
||||||
|
|
||||||
if(mech.canHeal && target == null){
|
if(mech.canHeal && target == null){
|
||||||
target = Geometry.findClosest(x, y, indexer.getDamaged(Team.sharded));
|
target = Geometry.findClosest(x, y, indexer.getDamaged(Team.sharded));
|
||||||
if(target != null && dst(target) > getWeapon().bullet.range()){
|
if(target != null && dst(target) > mech.range){
|
||||||
target = null;
|
target = null;
|
||||||
}else if(target != null){
|
}else if(target != null){
|
||||||
target = ((Tile)target).entity;
|
target = ((Tile)target).entity;
|
||||||
@@ -735,10 +694,9 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
|||||||
setMineTile(null);
|
setMineTile(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else if(target.isValid() || (target instanceof TileEntity && ((TileEntity)target).damaged() && target.getTeam() == team &&
|
}else if(target.isValid() || (target instanceof TileEntity && ((TileEntity)target).damaged() && target.getTeam() == team && mech.canHeal && dst(target) < mech.range)){
|
||||||
mech.canHeal && dst(target) < getWeapon().bullet.range())){
|
|
||||||
//rotate toward and shoot the target
|
//rotate toward and shoot the target
|
||||||
if(mech.turnCursor){
|
if(mech.faceTarget){
|
||||||
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f);
|
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
package mindustry.entities.type;
|
|
||||||
|
|
||||||
import arc.math.geom.Vec2;
|
|
||||||
import mindustry.entities.traits.SolidTrait;
|
|
||||||
|
|
||||||
public abstract class SolidEntity extends BaseEntity implements SolidTrait{
|
|
||||||
protected transient Vec2 velocity = new Vec2(0f, 0.0001f);
|
|
||||||
private transient Vec2 lastPosition = new Vec2();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vec2 lastPosition(){
|
|
||||||
return lastPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vec2 velocity(){
|
|
||||||
return velocity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,8 +10,6 @@ import arc.math.geom.Vec2;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import mindustry.entities.EntityGroup;
|
import mindustry.entities.EntityGroup;
|
||||||
import mindustry.entities.traits.HealthTrait;
|
|
||||||
import mindustry.entities.traits.TargetTrait;
|
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.game.EventType.BlockDestroyEvent;
|
import mindustry.game.EventType.BlockDestroyEvent;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import java.io.*;
|
|||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public abstract class Unit extends DestructibleEntity implements SaveTrait, TargetTrait, SyncTrait, DrawTrait, TeamTrait{
|
public abstract class Unit extends DestructibleEntity implements SaveTrait, TargetTrait, SyncTrait, DrawTrait, TeamTrait, ShooterTrait{
|
||||||
/** Total duration of hit flash effect */
|
/** Total duration of hit flash effect */
|
||||||
public static final float hitDuration = 9f;
|
public static final float hitDuration = 9f;
|
||||||
/** Percision divisor of velocity, used when writing. For example a value of '2' would mean the percision is 1/2 = 0.5-size chunks. */
|
/** Percision divisor of velocity, used when writing. For example a value of '2' would mean the percision is 1/2 = 0.5-size chunks. */
|
||||||
@@ -42,11 +42,29 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
public float rotation;
|
public float rotation;
|
||||||
|
|
||||||
protected final Interpolator interpolator = new Interpolator();
|
protected final Interpolator interpolator = new Interpolator();
|
||||||
|
/** status effects */
|
||||||
protected final Statuses status = new Statuses();
|
protected final Statuses status = new Statuses();
|
||||||
|
/** current item held */
|
||||||
protected final ItemStack item = new ItemStack(content.item(0), 0);
|
protected final ItemStack item = new ItemStack(content.item(0), 0);
|
||||||
|
/** holds weapon aiming positions and angles */
|
||||||
|
protected final Weapons weapons = new Weapons();
|
||||||
|
|
||||||
|
/** team; can be changed at any time */
|
||||||
protected Team team = Team.sharded;
|
protected Team team = Team.sharded;
|
||||||
|
/** timers for drowning and getting hit */
|
||||||
protected float drownTime, hitTime;
|
protected float drownTime, hitTime;
|
||||||
|
/** this unit's type; do not change internally without calling setType(...) */
|
||||||
|
protected UnitDef type;
|
||||||
|
|
||||||
|
public void setType(UnitDef type){
|
||||||
|
this.type = type;
|
||||||
|
clampHealth();
|
||||||
|
weapons.init(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitDef type(){
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean collidesGrid(int x, int y){
|
public boolean collidesGrid(int x, int y){
|
||||||
@@ -58,6 +76,11 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
return team;
|
return team;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Weapons getWeapons(){
|
||||||
|
return weapons;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void interpolate(){
|
public void interpolate(){
|
||||||
interpolator.update();
|
interpolator.update();
|
||||||
@@ -134,6 +157,22 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
return !isDead() && isAdded();
|
return !isDead() && isAdded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hitbox(Rect rect){
|
||||||
|
rect.setSize(type.hitsize).setCenter(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hitboxTile(Rect rect){
|
||||||
|
rect.setSize(type.hitsizeTile).setCenter(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float drag(){
|
||||||
|
return type.drag;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSave(DataOutput stream) throws IOException{
|
public void writeSave(DataOutput stream) throws IOException{
|
||||||
writeSave(stream, false);
|
writeSave(stream, false);
|
||||||
@@ -186,7 +225,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isImmune(StatusEffect effect){
|
public boolean isImmune(StatusEffect effect){
|
||||||
return false;
|
return type.immunities.contains(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOutOfBounds(){
|
public boolean isOutOfBounds(){
|
||||||
@@ -253,7 +292,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
status.update(this);
|
status.update(this);
|
||||||
item.amount = Mathf.clamp(this.item.amount, 0, getItemCapacity());
|
item.amount = Mathf.clamp(this.item.amount, 0, getItemCapacity());
|
||||||
|
|
||||||
velocity.limit(maxVelocity()).scl(1f + (status.getSpeedMultiplier() - 1f) * Time.delta());
|
//velocity.limit(maxVelocity()).scl(1f + (status.getSpeedMultiplier() - 1f) * Time.delta());
|
||||||
|
|
||||||
if(x < -finalWorldBounds || y < -finalWorldBounds || x >= world.width() * tilesize + finalWorldBounds || y >= world.height() * tilesize + finalWorldBounds){
|
if(x < -finalWorldBounds || y < -finalWorldBounds || x >= world.width() * tilesize + finalWorldBounds || y >= world.height() * tilesize + finalWorldBounds){
|
||||||
kill();
|
kill();
|
||||||
@@ -277,7 +316,6 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
if(x > world.unitWidth()) velocity.x -= (x - world.unitWidth())/warpDst;
|
if(x > world.unitWidth()) velocity.x -= (x - world.unitWidth())/warpDst;
|
||||||
if(y > world.unitHeight()) velocity.y -= (y - world.unitHeight())/warpDst;
|
if(y > world.unitHeight()) velocity.y -= (y - world.unitHeight())/warpDst;
|
||||||
|
|
||||||
|
|
||||||
if(isFlying()){
|
if(isFlying()){
|
||||||
drownTime = 0f;
|
drownTime = 0f;
|
||||||
move(velocity.x * Time.delta(), velocity.y * Time.delta());
|
move(velocity.x * Time.delta(), velocity.y * Time.delta());
|
||||||
@@ -327,7 +365,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
if(Math.abs(py - y) <= 0.0001f) velocity.y = 0f;
|
if(Math.abs(py - y) <= 0.0001f) velocity.y = 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
velocity.scl(Mathf.clamp(1f - drag() * (isFlying() ? 1f : floor.dragMultiplier) * Time.delta()));
|
//velocity.scl(Mathf.clamp(1f - drag() * (isFlying() ? 1f : floor.dragMultiplier) * Time.delta()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptsItem(Item item){
|
public boolean acceptsItem(Item item){
|
||||||
@@ -392,7 +430,9 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void drawLight(){
|
public void drawLight(){
|
||||||
renderer.lights.add(x, y, 50f, Pal.powerLight, 0.6f);
|
if(type.lightRadius > 0){
|
||||||
|
renderer.lights.add(x, y, type.lightRadius, type.lightColor, 0.6f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawBackItems(float itemtime, boolean number){
|
public void drawBackItems(float itemtime, boolean number){
|
||||||
@@ -449,11 +489,16 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
|
|
||||||
public abstract TextureRegion getIconRegion();
|
public abstract TextureRegion getIconRegion();
|
||||||
|
|
||||||
public abstract Weapon getWeapon();
|
public final int getItemCapacity(){
|
||||||
|
return type.itemCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract int getItemCapacity();
|
@Override
|
||||||
|
public float mass(){
|
||||||
|
return type.mass;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract float mass();
|
public boolean isFlying(){
|
||||||
|
return type.flying;
|
||||||
public abstract boolean isFlying();
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ public abstract class BaseDrone extends FlyingUnit{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean countsAsEnemy(){
|
public boolean countsAsEnemy(){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,11 +119,6 @@ public class GroundUnit extends BaseUnit{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Weapon getWeapon(){
|
|
||||||
return type.weapon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
Draw.mixcol(Color.white, hitTime / hitDuration);
|
Draw.mixcol(Color.white, hitTime / hitDuration);
|
||||||
|
|||||||
20
core/src/mindustry/entities/units/WeaponMount.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package mindustry.entities.units;
|
||||||
|
|
||||||
|
import mindustry.type.*;
|
||||||
|
|
||||||
|
public class WeaponMount{
|
||||||
|
/** weapon associated with this mount */
|
||||||
|
public final Weapon weapon;
|
||||||
|
/** reload in frames; 0 means ready to fire */
|
||||||
|
public float reload;
|
||||||
|
/** rotation relative to the unit this mount is on */
|
||||||
|
public float rotation;
|
||||||
|
/** aiming position in world coordinates */
|
||||||
|
public float aimX, aimY;
|
||||||
|
/** side that's being shot - only valid for mirrors */
|
||||||
|
public boolean side;
|
||||||
|
|
||||||
|
public WeaponMount(Weapon weapon){
|
||||||
|
this.weapon = weapon;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -321,11 +321,12 @@ public class EventType{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO rename
|
||||||
public static class MechChangeEvent{
|
public static class MechChangeEvent{
|
||||||
public final Player player;
|
public final Player player;
|
||||||
public final Mech mech;
|
public final UnitDef mech;
|
||||||
|
|
||||||
public MechChangeEvent(Player player, Mech mech){
|
public MechChangeEvent(Player player, UnitDef mech){
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.mech = mech;
|
this.mech = mech;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import arc.util.noise.RidgedPerlin;
|
|||||||
import arc.util.noise.Simplex;
|
import arc.util.noise.Simplex;
|
||||||
import mindustry.content.Blocks;
|
import mindustry.content.Blocks;
|
||||||
import mindustry.content.UnitTypes;
|
import mindustry.content.UnitTypes;
|
||||||
import mindustry.type.UnitType;
|
|
||||||
import mindustry.ui.Cicon;
|
import mindustry.ui.Cicon;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.Floor;
|
import mindustry.world.blocks.Floor;
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ public abstract class SaveFileReader{
|
|||||||
protected final DataOutputStream dataBytes = new DataOutputStream(byteOutput);
|
protected final DataOutputStream dataBytes = new DataOutputStream(byteOutput);
|
||||||
protected final ReusableByteOutStream byteOutputSmall = new ReusableByteOutStream();
|
protected final ReusableByteOutStream byteOutputSmall = new ReusableByteOutStream();
|
||||||
protected final DataOutputStream dataBytesSmall = new DataOutputStream(byteOutputSmall);
|
protected final DataOutputStream dataBytesSmall = new DataOutputStream(byteOutputSmall);
|
||||||
protected final ObjectMap<String, String> fallback = ObjectMap.of();
|
protected final ObjectMap<String, String> fallback = ObjectMap.of(
|
||||||
|
"dart-mech-pad", "dart-ship-pad"
|
||||||
|
);
|
||||||
|
|
||||||
protected void region(String name, DataInput stream, CounterInputStream counter, IORunner<DataInput> cons) throws IOException{
|
protected void region(String name, DataInput stream, CounterInputStream counter, IORunner<DataInput> cons) throws IOException{
|
||||||
counter.resetCount();
|
counter.resetCount();
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import mindustry.entities.Effects.Effect;
|
|||||||
import mindustry.entities.type.Bullet;
|
import mindustry.entities.type.Bullet;
|
||||||
import mindustry.entities.bullet.BulletType;
|
import mindustry.entities.bullet.BulletType;
|
||||||
import mindustry.entities.traits.BuilderTrait.BuildRequest;
|
import mindustry.entities.traits.BuilderTrait.BuildRequest;
|
||||||
import mindustry.entities.traits.ShooterTrait;
|
|
||||||
import mindustry.entities.type.*;
|
import mindustry.entities.type.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
@@ -232,13 +231,13 @@ public class TypeIO{
|
|||||||
return Effects.getEffect(buffer.getShort());
|
return Effects.getEffect(buffer.getShort());
|
||||||
}
|
}
|
||||||
|
|
||||||
@WriteClass(UnitType.class)
|
@WriteClass(UnitDef.class)
|
||||||
public static void writeUnitType(ByteBuffer buffer, UnitType effect){
|
public static void writeUnitDef(ByteBuffer buffer, UnitDef effect){
|
||||||
buffer.putShort(effect.id);
|
buffer.putShort(effect.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReadClass(UnitType.class)
|
@ReadClass(UnitDef.class)
|
||||||
public static UnitType readUnitType(ByteBuffer buffer){
|
public static UnitDef readUnitDef(ByteBuffer buffer){
|
||||||
return content.getByID(ContentType.unit, buffer.getShort());
|
return content.getByID(ContentType.unit, buffer.getShort());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,16 +251,6 @@ public class TypeIO{
|
|||||||
return new Color(buffer.getInt());
|
return new Color(buffer.getInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@WriteClass(Mech.class)
|
|
||||||
public static void writeMech(ByteBuffer buffer, Mech mech){
|
|
||||||
buffer.put((byte)mech.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ReadClass(Mech.class)
|
|
||||||
public static Mech readMech(ByteBuffer buffer){
|
|
||||||
return content.getByID(ContentType.mech, buffer.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@WriteClass(Liquid.class)
|
@WriteClass(Liquid.class)
|
||||||
public static void writeLiquid(ByteBuffer buffer, Liquid liquid){
|
public static void writeLiquid(ByteBuffer buffer, Liquid liquid){
|
||||||
buffer.putShort(liquid == null ? -1 : liquid.id);
|
buffer.putShort(liquid == null ? -1 : liquid.id);
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ public class ContentParser{
|
|||||||
UnitType unit;
|
UnitType unit;
|
||||||
if(locate(ContentType.unit, name) == null){
|
if(locate(ContentType.unit, name) == null){
|
||||||
Class<BaseUnit> type = resolve(legacyUnitMap.get(Strings.capitalize(getType(value)), getType(value)), "mindustry.entities.type.base");
|
Class<BaseUnit> type = resolve(legacyUnitMap.get(Strings.capitalize(getType(value)), getType(value)), "mindustry.entities.type.base");
|
||||||
unit = new UnitType(mod + "-" + name, supply(type));
|
unit = new UnitDef(mod + "-" + name, supply(type));
|
||||||
}else{
|
}else{
|
||||||
unit = locate(ContentType.unit, name);
|
unit = locate(ContentType.unit, name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ public class Mods implements Loadable{
|
|||||||
public void importMod(Fi file) throws IOException{
|
public void importMod(Fi file) throws IOException{
|
||||||
Fi dest = modDirectory.child(file.name());
|
Fi dest = modDirectory.child(file.name());
|
||||||
if(dest.exists()){
|
if(dest.exists()){
|
||||||
throw new IOException("A mod with the same filename already exists!");
|
throw new IOException("A file with the same name already exists in the mod folder!");
|
||||||
}
|
}
|
||||||
|
|
||||||
file.copyTo(dest);
|
file.copyTo(dest);
|
||||||
|
|||||||
@@ -1,141 +0,0 @@
|
|||||||
package mindustry.type;
|
|
||||||
|
|
||||||
import arc.Core;
|
|
||||||
import arc.graphics.Color;
|
|
||||||
import arc.graphics.g2d.*;
|
|
||||||
import arc.math.*;
|
|
||||||
import arc.scene.ui.layout.Table;
|
|
||||||
import arc.util.ArcAnnotate.*;
|
|
||||||
import arc.util.Time;
|
|
||||||
import mindustry.ctype.ContentType;
|
|
||||||
import mindustry.entities.type.Player;
|
|
||||||
import mindustry.ctype.UnlockableContent;
|
|
||||||
import mindustry.graphics.Pal;
|
|
||||||
import mindustry.ui.ContentDisplay;
|
|
||||||
|
|
||||||
public class Mech extends UnlockableContent{
|
|
||||||
public boolean flying;
|
|
||||||
public float speed = 1.1f;
|
|
||||||
public float maxSpeed = 10f;
|
|
||||||
public float boostSpeed = 0.75f;
|
|
||||||
public float drag = 0.4f;
|
|
||||||
public float mass = 1f;
|
|
||||||
public float shake = 0f;
|
|
||||||
public float health = 200f;
|
|
||||||
|
|
||||||
public float hitsize = 6f;
|
|
||||||
public float cellTrnsY = 0f;
|
|
||||||
public float mineSpeed = 1f;
|
|
||||||
public int drillPower = -1;
|
|
||||||
public float buildPower = 1f;
|
|
||||||
public Color engineColor = Pal.boostTo;
|
|
||||||
public int itemCapacity = 30;
|
|
||||||
public boolean turnCursor = true;
|
|
||||||
public boolean canHeal = false;
|
|
||||||
public float compoundSpeed, compoundSpeedBoost;
|
|
||||||
|
|
||||||
/** draw the health and team indicator */
|
|
||||||
public boolean drawCell = true;
|
|
||||||
/** draw the items on its back */
|
|
||||||
public boolean drawItems = true;
|
|
||||||
/** draw the engine light if it's flying/boosting */
|
|
||||||
public boolean drawLight = true;
|
|
||||||
|
|
||||||
public float weaponOffsetX, weaponOffsetY, engineOffset = 5f, engineSize = 2.5f;
|
|
||||||
public @NonNull Weapon weapon;
|
|
||||||
|
|
||||||
public TextureRegion baseRegion, legRegion, region;
|
|
||||||
|
|
||||||
public Mech(String name, boolean flying){
|
|
||||||
super(name);
|
|
||||||
this.flying = flying;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mech(String name){
|
|
||||||
this(name, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateAlt(Player player){
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(Player player){
|
|
||||||
}
|
|
||||||
|
|
||||||
public void drawStats(Player player){
|
|
||||||
if(drawCell){
|
|
||||||
float health = player.healthf();
|
|
||||||
Draw.color(Color.black, player.getTeam().color, health + Mathf.absin(Time.time(), health * 5f, 1f - health));
|
|
||||||
Draw.rect(player.getPowerCellRegion(),
|
|
||||||
player.x + Angles.trnsx(player.rotation, cellTrnsY, 0f),
|
|
||||||
player.y + Angles.trnsy(player.rotation, cellTrnsY, 0f),
|
|
||||||
player.rotation - 90);
|
|
||||||
Draw.reset();
|
|
||||||
}
|
|
||||||
if(drawItems){
|
|
||||||
player.drawBackItems();
|
|
||||||
}
|
|
||||||
if(drawLight){
|
|
||||||
player.drawLight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getExtraArmor(Player player){
|
|
||||||
return 0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float spreadX(Player player){
|
|
||||||
return 0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getRotationAlpha(Player player){
|
|
||||||
return 1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canShoot(Player player){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onLand(Player player){
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(){
|
|
||||||
super.init();
|
|
||||||
|
|
||||||
for(int i = 0; i < 500; i++){
|
|
||||||
compoundSpeed *= (1f - drag);
|
|
||||||
compoundSpeed += speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < 500; i++){
|
|
||||||
compoundSpeedBoost *= (1f - drag);
|
|
||||||
compoundSpeedBoost += boostSpeed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void displayInfo(Table table){
|
|
||||||
ContentDisplay.displayMech(table, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContentType getContentType(){
|
|
||||||
return ContentType.mech;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(){
|
|
||||||
weapon.load();
|
|
||||||
if(!flying){
|
|
||||||
legRegion = Core.atlas.find(name + "-leg");
|
|
||||||
baseRegion = Core.atlas.find(name + "-base");
|
|
||||||
}
|
|
||||||
|
|
||||||
region = Core.atlas.find(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(){
|
|
||||||
return localizedName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
142
core/src/mindustry/type/UnitDef.java
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
package mindustry.type;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
|
import arc.audio.*;
|
||||||
|
import arc.func.*;
|
||||||
|
import arc.graphics.*;
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.scene.ui.layout.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.annotations.Annotations.*;
|
||||||
|
import mindustry.ctype.*;
|
||||||
|
import mindustry.entities.type.*;
|
||||||
|
import mindustry.entities.type.base.*;
|
||||||
|
import mindustry.game.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.ui.*;
|
||||||
|
|
||||||
|
//TODO change to UnitType or Shell or something
|
||||||
|
public class UnitDef extends UnlockableContent{
|
||||||
|
//TODO implement
|
||||||
|
public @NonNull Prov<? extends BaseUnit> constructor = () -> this.flying ? new FlyingUnit() : new GroundUnit();
|
||||||
|
public TypeID typeID;
|
||||||
|
|
||||||
|
public boolean flying;
|
||||||
|
public float speed = 1.1f, boostSpeed = 0.75f, rotateSpeed = 0.2f, baseRotateSpeed = 0.1f;
|
||||||
|
public float drag = 0.3f, mass = 1f, accel = 0.1f;
|
||||||
|
public float health = 200f, range = -1;
|
||||||
|
public boolean targetAir = false, targetGround = false;
|
||||||
|
public boolean faceTarget = true; //equivalent to turnCursor
|
||||||
|
|
||||||
|
public int itemCapacity = 30;
|
||||||
|
public int drillTier = -1;
|
||||||
|
public float buildPower = 1f, minePower = 1f;
|
||||||
|
|
||||||
|
public Color engineColor = Pal.boostTo;
|
||||||
|
public float engineOffset = 5f, engineSize = 2.5f;
|
||||||
|
|
||||||
|
public float hitsize = 6f, hitsizeTile = 4f;
|
||||||
|
public float cellOffsetX = 0f, cellOffsetY = 0f;
|
||||||
|
public float lightRadius = 60f;
|
||||||
|
public Color lightColor = Pal.powerLight;
|
||||||
|
public boolean drawCell = true, drawItems = true;
|
||||||
|
|
||||||
|
public ObjectSet<StatusEffect> immunities = new ObjectSet<>();
|
||||||
|
public Sound deathSound = Sounds.bang;
|
||||||
|
|
||||||
|
public Array<Weapon> weapons = new Array<>();
|
||||||
|
public TextureRegion baseRegion, legRegion, region;
|
||||||
|
|
||||||
|
public UnitDef(String name){
|
||||||
|
super(name);
|
||||||
|
|
||||||
|
//TODO replace with the sane constructor
|
||||||
|
typeID = new TypeID(name, constructor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseUnit create(Team team){
|
||||||
|
BaseUnit unit = constructor.get();
|
||||||
|
unit.init(this, team);
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayInfo(Table table){
|
||||||
|
ContentDisplay.displayUnit(table, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
|
@Override
|
||||||
|
public void init(){
|
||||||
|
//set up default range
|
||||||
|
if(range < 0){
|
||||||
|
for(Weapon weapon : weapons){
|
||||||
|
range = Math.max(range, weapon.bullet.range());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
|
@Override
|
||||||
|
public void load(){
|
||||||
|
weapons.each(Weapon::load);
|
||||||
|
region = Core.atlas.find(name);
|
||||||
|
legRegion = Core.atlas.find(name + "-leg");
|
||||||
|
baseRegion = Core.atlas.find(name + "-base");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContentType getContentType(){
|
||||||
|
return ContentType.unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO remove methods below!
|
||||||
|
|
||||||
|
public void update(Unit player){
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Unit player){
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawStats(Unit player){
|
||||||
|
if(drawCell){
|
||||||
|
float health = player.healthf();
|
||||||
|
Draw.color(Color.black, player.getTeam().color, health + Mathf.absin(Time.time(), health * 5f, 1f - health));
|
||||||
|
Draw.rect(player.getPowerCellRegion(),
|
||||||
|
player.x + Angles.trnsx(player.rotation, cellOffsetY, cellOffsetX),
|
||||||
|
player.y + Angles.trnsy(player.rotation, cellOffsetY, cellOffsetX),
|
||||||
|
player.rotation - 90);
|
||||||
|
Draw.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(drawItems){
|
||||||
|
//player.drawBackItems(0f, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getExtraArmor(Unit player){
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO remove
|
||||||
|
public float spreadX(Unit player){
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO remove
|
||||||
|
public float getRotationAlpha(Unit player){
|
||||||
|
return 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canShoot(Unit player){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onLand(Unit player){
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
package mindustry.type;
|
|
||||||
|
|
||||||
import arc.*;
|
|
||||||
import arc.audio.*;
|
|
||||||
import arc.struct.*;
|
|
||||||
import arc.func.*;
|
|
||||||
import arc.graphics.g2d.*;
|
|
||||||
import arc.scene.ui.layout.*;
|
|
||||||
import arc.util.ArcAnnotate.*;
|
|
||||||
import mindustry.content.*;
|
|
||||||
import mindustry.ctype.ContentType;
|
|
||||||
import mindustry.ctype.UnlockableContent;
|
|
||||||
import mindustry.entities.type.*;
|
|
||||||
import mindustry.game.*;
|
|
||||||
import mindustry.gen.*;
|
|
||||||
import mindustry.ui.*;
|
|
||||||
|
|
||||||
public class UnitType extends UnlockableContent{
|
|
||||||
public @NonNull TypeID typeID;
|
|
||||||
public @NonNull Prov<? extends BaseUnit> constructor;
|
|
||||||
|
|
||||||
public float health = 60;
|
|
||||||
public float hitsize = 7f;
|
|
||||||
public float hitsizeTile = 4f;
|
|
||||||
public float speed = 0.4f;
|
|
||||||
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 flying;
|
|
||||||
public boolean targetAir = true;
|
|
||||||
public boolean rotateWeapon = false;
|
|
||||||
public float drag = 0.1f;
|
|
||||||
public float maxVelocity = 5f;
|
|
||||||
public float retreatPercent = 0.6f;
|
|
||||||
public int itemCapacity = 30;
|
|
||||||
public ObjectSet<Item> toMine = ObjectSet.with(Items.lead, Items.copper);
|
|
||||||
public float buildPower = 0.3f, minePower = 0.7f;
|
|
||||||
public @NonNull Weapon weapon;
|
|
||||||
public float weaponOffsetY, engineOffset = 6f, engineSize = 2f;
|
|
||||||
public ObjectSet<StatusEffect> immunities = new ObjectSet<>();
|
|
||||||
public Sound deathSound = Sounds.bang;
|
|
||||||
|
|
||||||
public TextureRegion legRegion, baseRegion, region;
|
|
||||||
|
|
||||||
public <T extends BaseUnit> UnitType(String name, Prov<T> mainConstructor){
|
|
||||||
this(name);
|
|
||||||
create(mainConstructor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UnitType(String name){
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T extends BaseUnit> void create(Prov<T> mainConstructor){
|
|
||||||
this.constructor = mainConstructor;
|
|
||||||
this.description = Core.bundle.getOrNull("unit." + name + ".description");
|
|
||||||
this.typeID = new TypeID(name, mainConstructor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void displayInfo(Table table){
|
|
||||||
ContentDisplay.displayUnit(table, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(){
|
|
||||||
weapon.load();
|
|
||||||
region = Core.atlas.find(name);
|
|
||||||
legRegion = Core.atlas.find(name + "-leg");
|
|
||||||
baseRegion = Core.atlas.find(name + "-base");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContentType getContentType(){
|
|
||||||
return ContentType.unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseUnit create(Team team){
|
|
||||||
BaseUnit unit = constructor.get();
|
|
||||||
unit.init(this, team);
|
|
||||||
return unit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,15 +20,22 @@ import mindustry.gen.*;
|
|||||||
import static mindustry.Vars.net;
|
import static mindustry.Vars.net;
|
||||||
|
|
||||||
public class Weapon{
|
public class Weapon{
|
||||||
|
/** displayed weapon region */
|
||||||
public String name;
|
public String name;
|
||||||
|
|
||||||
/** minimum cursor distance from player, fixes 'cross-eyed' shooting. */
|
|
||||||
protected static float minPlayerDist = 20f;
|
|
||||||
protected static int sequenceNum = 0;
|
|
||||||
/** bullet shot */
|
/** bullet shot */
|
||||||
public @NonNull BulletType bullet;
|
public @NonNull BulletType bullet;
|
||||||
/** shell ejection effect */
|
/** shell ejection effect */
|
||||||
public Effect ejectEffect = Fx.none;
|
public Effect ejectEffect = Fx.none;
|
||||||
|
/** whether to mirror the weapon (draw two of them, which is the default) */
|
||||||
|
public boolean mirror = true;
|
||||||
|
/** whether to flip the weapon's position/side on the ship (only valid when mirror is false) */
|
||||||
|
public boolean flipped = false;
|
||||||
|
/** whether to shoot the weapons in different arms one after another, rather than all at once; only valid when mirror = true */
|
||||||
|
public boolean alternate = false;
|
||||||
|
/** whether to rotate toward the target independently of unit */
|
||||||
|
public boolean rotate = false;
|
||||||
|
/** rotation speed of weapon when rotation is enabled, in degrees/t*/
|
||||||
|
public float rotateSpeed = 2f;
|
||||||
/** weapon reload in frames */
|
/** weapon reload in frames */
|
||||||
public float reload;
|
public float reload;
|
||||||
/** amount of shots per fire */
|
/** amount of shots per fire */
|
||||||
@@ -41,14 +48,12 @@ public class Weapon{
|
|||||||
public float shake = 0f;
|
public float shake = 0f;
|
||||||
/** visual weapon knockback. */
|
/** visual weapon knockback. */
|
||||||
public float recoil = 1.5f;
|
public float recoil = 1.5f;
|
||||||
/** shoot barrel y offset */
|
/** projectile/effect offsets from center of weapon */
|
||||||
public float length = 3f;
|
public float shootX = 0f, shootY = 3f;
|
||||||
/** shoot barrel x offset. */
|
/** offsets of weapon position on unit */
|
||||||
public float width = 4f;
|
public float x = 5f, y = 0f;
|
||||||
/** fraction of velocity that is random */
|
/** fraction of velocity that is random */
|
||||||
public float velocityRnd = 0f;
|
public float velocityRnd = 0f;
|
||||||
/** whether to shoot the weapons in different arms one after another, rather than all at once */
|
|
||||||
public boolean alternate = false;
|
|
||||||
/** randomization of shot length */
|
/** randomization of shot length */
|
||||||
public float lengthRand = 0f;
|
public float lengthRand = 0f;
|
||||||
/** delay in ticks between shots */
|
/** delay in ticks between shots */
|
||||||
@@ -57,124 +62,21 @@ public class Weapon{
|
|||||||
public boolean ignoreRotation = false;
|
public boolean ignoreRotation = false;
|
||||||
/** if turnCursor is false for a mech, how far away will the weapon target. */
|
/** if turnCursor is false for a mech, how far away will the weapon target. */
|
||||||
public float targetDistance = 1f;
|
public float targetDistance = 1f;
|
||||||
|
/** sound used for shooting */
|
||||||
public Sound shootSound = Sounds.pew;
|
public Sound shootSound = Sounds.pew;
|
||||||
|
/** displayed region (autoloaded) */
|
||||||
public TextureRegion region;
|
public TextureRegion region;
|
||||||
|
|
||||||
protected Weapon(String name){
|
public Weapon(String name){
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Weapon(){
|
public Weapon(){
|
||||||
//no region
|
this("");
|
||||||
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;
|
|
||||||
//clients do not see their own shoot events: they are simulated completely clientside to prevent laggy visuals
|
|
||||||
//messing with the firerate or any other stats does not affect the server (take that, script kiddies!)
|
|
||||||
if(net.client() && player == Vars.player){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
shootDirect(player, x, y, rotation, left);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Remote(targets = Loc.server, called = Loc.both, unreliable = true)
|
|
||||||
public static void onGenericShootWeapon(ShooterTrait shooter, float x, float y, float rotation, boolean left){
|
|
||||||
if(shooter == null) return;
|
|
||||||
shootDirect(shooter, x, y, rotation, left);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void shootDirect(ShooterTrait shooter, float offsetX, float offsetY, float rotation, boolean left){
|
|
||||||
float x = shooter.getX() + offsetX;
|
|
||||||
float y = shooter.getY() + offsetY;
|
|
||||||
float baseX = shooter.getX(), baseY = shooter.getY();
|
|
||||||
|
|
||||||
Weapon weapon = shooter.getWeapon();
|
|
||||||
weapon.shootSound.at(x, y, Mathf.random(0.8f, 1.0f));
|
|
||||||
|
|
||||||
sequenceNum = 0;
|
|
||||||
if(weapon.shotDelay > 0.01f){
|
|
||||||
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> {
|
|
||||||
Time.run(sequenceNum * weapon.shotDelay, () -> weapon.bullet(shooter, x + shooter.getX() - baseX, y + shooter.getY() - baseY, 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)));
|
|
||||||
}
|
|
||||||
|
|
||||||
BulletType ammo = weapon.bullet;
|
|
||||||
|
|
||||||
Tmp.v1.trns(rotation + 180f, ammo.recoil);
|
|
||||||
|
|
||||||
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 + 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load(){
|
public void load(){
|
||||||
region = Core.atlas.find(name + "-equip", Core.atlas.find(name, Core.atlas.find("clear")));
|
region = Core.atlas.find(name + "-equip", Core.atlas.find(name, Core.atlas.find("clear")));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(ShooterTrait shooter, float pointerX, float 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(ShooterTrait shooter, float mountX, float mountY, float angle, boolean left){
|
|
||||||
if(shooter.getTimer().get(shooter.getShootTimer(left), reload)){
|
|
||||||
if(alternate){
|
|
||||||
shooter.getTimer().reset(shooter.getShootTimer(!left), reload / 2f);
|
|
||||||
}
|
|
||||||
|
|
||||||
shoot(shooter, mountX - shooter.getX(), mountY - shooter.getY(), angle, left);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getRecoil(ShooterTrait player, boolean left){
|
|
||||||
return (1f - Mathf.clamp(player.getTimer().getTime(player.getShootTimer(left)) / reload)) * recoil;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void shoot(ShooterTrait p, float x, float y, float angle, boolean left){
|
|
||||||
if(net.client()){
|
|
||||||
//call it directly, don't invoke on server
|
|
||||||
shootDirect(p, x, y, angle, left);
|
|
||||||
}else{
|
|
||||||
if(p instanceof Player){ //players need special weapon handling logic
|
|
||||||
Call.onPlayerShootWeapon((Player)p, x, y, angle, left);
|
|
||||||
}else{
|
|
||||||
Call.onGenericShootWeapon(p, x, y, angle, left);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void bullet(ShooterTrait owner, float x, float y, float angle){
|
|
||||||
if(owner == null) return;
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,8 @@ public class ContentDisplay{
|
|||||||
table.row();
|
table.row();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO implement later
|
||||||
|
/*
|
||||||
public static void displayMech(Table table, Mech mech){
|
public static void displayMech(Table table, Mech mech){
|
||||||
table.table(title -> {
|
table.table(title -> {
|
||||||
title.addImage(mech.icon(Cicon.xlarge)).size(8 * 6);
|
title.addImage(mech.icon(Cicon.xlarge)).size(8 * 6);
|
||||||
@@ -177,9 +179,9 @@ public class ContentDisplay{
|
|||||||
table.add(Core.bundle.format("mech.minepower", mech.drillPower));
|
table.add(Core.bundle.format("mech.minepower", mech.drillPower));
|
||||||
table.row();
|
table.row();
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public static void displayUnit(Table table, UnitType unit){
|
public static void displayUnit(Table table, UnitDef unit){
|
||||||
table.table(title -> {
|
table.table(title -> {
|
||||||
title.addImage(unit.icon(Cicon.xlarge)).size(8 * 6);
|
title.addImage(unit.icon(Cicon.xlarge)).size(8 * 6);
|
||||||
title.add("[accent]" + unit.localizedName).padLeft(5);
|
title.add("[accent]" + unit.localizedName).padLeft(5);
|
||||||
|
|||||||
@@ -144,16 +144,16 @@ public class JoinDialog extends FloatingDialog{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}).margin(3f).padTop(6f).top().right();
|
}).margin(3f).pad(2).padTop(6f).top().right();
|
||||||
|
|
||||||
inner.addImageButton(Icon.refresh, Styles.emptyi, () -> {
|
inner.addImageButton(Icon.refresh, Styles.emptyi, () -> {
|
||||||
refreshServer(server);
|
refreshServer(server);
|
||||||
}).margin(3f).padTop(6f).top().right();
|
}).margin(3f).pad(2).padTop(6f).top().right();
|
||||||
|
|
||||||
inner.addImageButton(Icon.pencil, Styles.emptyi, () -> {
|
inner.addImageButton(Icon.pencil, Styles.emptyi, () -> {
|
||||||
renaming = server;
|
renaming = server;
|
||||||
add.show();
|
add.show();
|
||||||
}).margin(3f).padTop(6f).top().right();
|
}).margin(3f).pad(2).padTop(6f).top().right();
|
||||||
|
|
||||||
inner.addImageButton(Icon.trash, Styles.emptyi, () -> {
|
inner.addImageButton(Icon.trash, Styles.emptyi, () -> {
|
||||||
ui.showConfirm("$confirm", "$server.delete", () -> {
|
ui.showConfirm("$confirm", "$server.delete", () -> {
|
||||||
@@ -162,7 +162,7 @@ public class JoinDialog extends FloatingDialog{
|
|||||||
setupRemote();
|
setupRemote();
|
||||||
refreshRemote();
|
refreshRemote();
|
||||||
});
|
});
|
||||||
}).margin(3f).pad(6).top().right();
|
}).margin(3f).pad(2).pad(6).top().right();
|
||||||
|
|
||||||
button.row();
|
button.row();
|
||||||
|
|
||||||
|
|||||||
@@ -78,24 +78,10 @@ public class MendProjector extends Block{
|
|||||||
float realRange = range + entity.phaseHeat * phaseRangeBoost;
|
float realRange = range + entity.phaseHeat * phaseRangeBoost;
|
||||||
entity.charge = 0f;
|
entity.charge = 0f;
|
||||||
|
|
||||||
int tileRange = (int)(realRange / tilesize + 1);
|
indexer.eachBlock(entity, realRange, other -> other.entity.damaged(), other -> {
|
||||||
healed.clear();
|
other.entity.healBy(other.entity.maxHealth() * (healPercent + entity.phaseHeat * phaseBoost) / 100f * entity.efficiency());
|
||||||
|
Effects.effect(Fx.healBlockFull, Tmp.c1.set(baseColor).lerp(phaseColor, entity.phaseHeat), other.drawx(), other.drawy(), other.block().size);
|
||||||
for(int x = -tileRange + tile.x; x <= tileRange + tile.x; x++){
|
});
|
||||||
for(int y = -tileRange + tile.y; y <= tileRange + tile.y; y++){
|
|
||||||
if(!Mathf.within(x * tilesize, y * tilesize, tile.drawx(), tile.drawy(), realRange)) continue;
|
|
||||||
|
|
||||||
Tile other = world.ltile(x, y);
|
|
||||||
|
|
||||||
if(other == null) continue;
|
|
||||||
|
|
||||||
if(other.getTeamID() == tile.getTeamID() && !healed.contains(other.pos()) && other.entity != null && other.entity.health < other.entity.maxHealth()){
|
|
||||||
other.entity.healBy(other.entity.maxHealth() * (healPercent + entity.phaseHeat * phaseBoost) / 100f * entity.efficiency());
|
|
||||||
Effects.effect(Fx.healBlockFull, Tmp.c1.set(baseColor).lerp(phaseColor, entity.phaseHeat), other.drawx(), other.drawy(), other.block().size);
|
|
||||||
healed.add(other.pos());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,9 +107,7 @@ public class MendProjector extends Block{
|
|||||||
|
|
||||||
Draw.color(baseColor, phaseColor, entity.phaseHeat);
|
Draw.color(baseColor, phaseColor, entity.phaseHeat);
|
||||||
Draw.alpha(entity.heat * Mathf.absin(Time.time(), 10f, 1f) * 0.5f);
|
Draw.alpha(entity.heat * Mathf.absin(Time.time(), 10f, 1f) * 0.5f);
|
||||||
//Draw.blend(Blending.additive);
|
|
||||||
Draw.rect(topRegion, tile.drawx(), tile.drawy());
|
Draw.rect(topRegion, tile.drawx(), tile.drawy());
|
||||||
//Draw.blend();
|
|
||||||
|
|
||||||
Draw.alpha(1f);
|
Draw.alpha(1f);
|
||||||
Lines.stroke((2f * f + 0.2f) * entity.heat);
|
Lines.stroke((2f * f + 0.2f) * entity.heat);
|
||||||
|
|||||||
@@ -89,27 +89,7 @@ public class OverdriveProjector extends Block{
|
|||||||
float realBoost = (speedBoost + entity.phaseHeat * speedBoostPhase) * entity.efficiency();
|
float realBoost = (speedBoost + entity.phaseHeat * speedBoostPhase) * entity.efficiency();
|
||||||
|
|
||||||
entity.charge = 0f;
|
entity.charge = 0f;
|
||||||
|
indexer.eachBlock(entity, realRange, other -> other.entity.timeScale <= realBoost, other -> other.entity.applyBoost(realBoost, reload + 1f));
|
||||||
int tileRange = (int)(realRange / tilesize + 1);
|
|
||||||
healed.clear();
|
|
||||||
|
|
||||||
for(int x = -tileRange + tile.x; x <= tileRange + tile.x; x++){
|
|
||||||
for(int y = -tileRange + tile.y; y <= tileRange + tile.y; y++){
|
|
||||||
if(!Mathf.within(x * tilesize, y * tilesize, tile.drawx(), tile.drawy(), realRange)) continue;
|
|
||||||
|
|
||||||
Tile other = world.ltile(x, y);
|
|
||||||
|
|
||||||
if(other == null) continue;
|
|
||||||
|
|
||||||
if(other.getTeamID() == tile.getTeamID() && !healed.contains(other.pos()) && other.entity != null){
|
|
||||||
if(other.entity.timeScale <= realBoost){
|
|
||||||
other.entity.timeScaleDuration = Math.max(other.entity.timeScaleDuration, reload + 1f);
|
|
||||||
other.entity.timeScale = Math.max(other.entity.timeScale, realBoost);
|
|
||||||
}
|
|
||||||
healed.add(other.pos());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import mindustry.entities.*;
|
|||||||
import mindustry.entities.Effects.Effect;
|
import mindustry.entities.Effects.Effect;
|
||||||
import mindustry.entities.type.Bullet;
|
import mindustry.entities.type.Bullet;
|
||||||
import mindustry.entities.bullet.BulletType;
|
import mindustry.entities.bullet.BulletType;
|
||||||
import mindustry.entities.traits.TargetTrait;
|
|
||||||
import mindustry.entities.type.TileEntity;
|
import mindustry.entities.type.TileEntity;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
@@ -25,6 +24,8 @@ import mindustry.world.Block;
|
|||||||
import mindustry.world.Tile;
|
import mindustry.world.Tile;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
import static mindustry.Vars.tilesize;
|
import static mindustry.Vars.tilesize;
|
||||||
|
|
||||||
public abstract class Turret extends Block{
|
public abstract class Turret extends Block{
|
||||||
@@ -320,5 +321,26 @@ public abstract class Turret extends Block{
|
|||||||
public float heat;
|
public float heat;
|
||||||
public int shots;
|
public int shots;
|
||||||
public TargetTrait target;
|
public TargetTrait target;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutput stream) throws IOException{
|
||||||
|
super.write(stream);
|
||||||
|
stream.writeFloat(reload);
|
||||||
|
stream.writeFloat(rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(DataInput stream, byte revision) throws IOException{
|
||||||
|
super.read(stream, revision);
|
||||||
|
if(revision == 1){
|
||||||
|
reload = stream.readFloat();
|
||||||
|
rotation = stream.readFloat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte version(){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||