Merge branch 'master' into cleanup-2
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||

|

|
||||||
|
|
||||||
[](https://travis-ci.org/Anuken/Mindustry)
|
[](https://travis-ci.org/Anuken/Mindustry)
|
||||||
[](https://discord.gg/mindustry)
|
[](https://discord.gg/mindustry)
|
||||||
|
|
||||||
A sandbox tower defense game written in Java.
|
A sandbox tower defense game written in Java.
|
||||||
|
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ public class Annotations{
|
|||||||
boolean serialize() default true;
|
boolean serialize() default true;
|
||||||
/** Whether to generate IO code. This is for advanced usage only. */
|
/** Whether to generate IO code. This is for advanced usage only. */
|
||||||
boolean genio() default true;
|
boolean genio() default true;
|
||||||
|
/** Whether I made a massive mistake by merging two different class branches */
|
||||||
|
boolean legacy() default false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Indicates an internal interface for entity components. */
|
/** Indicates an internal interface for entity components. */
|
||||||
|
|||||||
@@ -240,7 +240,6 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
//look at each definition
|
//look at each definition
|
||||||
for(Selement<?> type : allDefs){
|
for(Selement<?> type : allDefs){
|
||||||
EntityDef ann = type.annotation(EntityDef.class);
|
EntityDef ann = type.annotation(EntityDef.class);
|
||||||
boolean isFinal = ann.isFinal();
|
|
||||||
|
|
||||||
//all component classes (not interfaces)
|
//all component classes (not interfaces)
|
||||||
Seq<Stype> components = allComponents(type);
|
Seq<Stype> components = allComponents(type);
|
||||||
@@ -274,6 +273,10 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
name += "Entity";
|
name += "Entity";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(ann.legacy()){
|
||||||
|
name += "Legacy" + Strings.capitalize(type.name());
|
||||||
|
}
|
||||||
|
|
||||||
//skip double classes
|
//skip double classes
|
||||||
if(usedNames.containsKey(name)){
|
if(usedNames.containsKey(name)){
|
||||||
extraNames.get(usedNames.get(name), ObjectSet::new).add(type.name());
|
extraNames.get(usedNames.get(name), ObjectSet::new).add(type.name());
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:3,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:3,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:3,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:3,fields:[{name:ammo,type:float},{name:armor,type:float},{name:baseRotation,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:2,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:payloads,type:arc.struct.Seq<mindustry.world.blocks.payloads.Payload>},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:3,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:payloads,type:arc.struct.Seq<mindustry.world.blocks.payloads.Payload>},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:3,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:3,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||||
@@ -96,3 +96,7 @@ YellOw139
|
|||||||
PetrGasparik
|
PetrGasparik
|
||||||
LeoDog896
|
LeoDog896
|
||||||
Summet
|
Summet
|
||||||
|
jalastram (freesound.org)
|
||||||
|
newlocknew (freesound.org)
|
||||||
|
dsmolenaers (freesound.org)
|
||||||
|
Headphaze (freesound.org)
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 826 B After Width: | Height: | Size: 825 B |
Binary file not shown.
|
Before Width: | Height: | Size: 190 KiB After Width: | Height: | Size: 184 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 185 KiB |
@@ -79,7 +79,7 @@ public class BuilderAI extends AIController{
|
|||||||
float dist = Math.min(cons.dst(unit) - buildingRange, 0);
|
float dist = Math.min(cons.dst(unit) - buildingRange, 0);
|
||||||
|
|
||||||
//make sure you can reach the request in time
|
//make sure you can reach the request in time
|
||||||
if(dist / unit.type.speed < cons.buildCost * 0.9f){
|
if(dist / unit.speed() < cons.buildCost * 0.9f){
|
||||||
following = b;
|
following = b;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class FlyingAI extends AIController{
|
|||||||
vec.setAngle(Mathf.slerpDelta(unit.vel().angle(), vec.angle(), 0.6f));
|
vec.setAngle(Mathf.slerpDelta(unit.vel().angle(), vec.angle(), 0.6f));
|
||||||
}
|
}
|
||||||
|
|
||||||
vec.setLength(unit.type.speed);
|
vec.setLength(unit.speed());
|
||||||
|
|
||||||
unit.moveAt(vec);
|
unit.moveAt(vec);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,13 @@ package mindustry.ai.types;
|
|||||||
|
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.ai.formations.*;
|
import mindustry.ai.formations.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
|
||||||
import mindustry.world.*;
|
|
||||||
import mindustry.world.blocks.storage.CoreBlock.*;
|
import mindustry.world.blocks.storage.CoreBlock.*;
|
||||||
|
|
||||||
public class FormationAI extends AIController implements FormationMember{
|
public class FormationAI extends AIController implements FormationMember{
|
||||||
private static Seq<Tile> tiles = new Seq<>();
|
|
||||||
public Unit leader;
|
public Unit leader;
|
||||||
|
|
||||||
private Vec3 target = new Vec3();
|
private Vec3 target = new Vec3();
|
||||||
@@ -30,9 +26,8 @@ public class FormationAI extends AIController implements FormationMember{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateUnit(){
|
public void updateUnit(){
|
||||||
UnitType type = unit.type;
|
|
||||||
|
|
||||||
if(leader.dead){
|
if(leader == null || leader.dead){
|
||||||
unit.resetController();
|
unit.resetController();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,9 +104,7 @@ public class LogicAI extends AIController{
|
|||||||
|
|
||||||
//look where moving if there's nothing to aim at
|
//look where moving if there's nothing to aim at
|
||||||
if(!shoot){
|
if(!shoot){
|
||||||
if(unit.moving()){
|
unit.lookAt(unit.prefRotation());
|
||||||
unit.lookAt(unit.vel().angle());
|
|
||||||
}
|
|
||||||
}else if(unit.hasWeapons()){ //if there is, look at the object
|
}else if(unit.hasWeapons()){ //if there is, look at the object
|
||||||
unit.lookAt(unit.mounts[0].aimX, unit.mounts[0].aimY);
|
unit.lookAt(unit.mounts[0].aimX, unit.mounts[0].aimY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class SuicideAI extends GroundAI{
|
|||||||
if(!blocked){
|
if(!blocked){
|
||||||
moveToTarget = true;
|
moveToTarget = true;
|
||||||
//move towards target directly
|
//move towards target directly
|
||||||
unit.moveAt(vec.set(target).sub(unit).limit(unit.type.speed));
|
unit.moveAt(vec.set(target).sub(unit).limit(unit.speed()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,12 +31,12 @@ public class LoopControl{
|
|||||||
|
|
||||||
boolean play = data.curVolume > 0.01f;
|
boolean play = data.curVolume > 0.01f;
|
||||||
float pan = Mathf.zero(data.total, 0.0001f) ? 0f : sound.calcPan(data.sum.x / data.total, data.sum.y / data.total);
|
float pan = Mathf.zero(data.total, 0.0001f) ? 0f : sound.calcPan(data.sum.x / data.total, data.sum.y / data.total);
|
||||||
if(data.soundID <= 0){
|
if(data.soundID <= 0 || !sound.isPlaying(data.soundID)){
|
||||||
if(play){
|
if(play){
|
||||||
data.soundID = sound.loop(data.curVolume, 1f, pan);
|
data.soundID = sound.loop(data.curVolume, 1f, pan);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(data.curVolume <= 0.01f){
|
if(data.curVolume <= 0.001f){
|
||||||
sound.stop();
|
sound.stop();
|
||||||
data.soundID = -1;
|
data.soundID = -1;
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package mindustry.audio;
|
|||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.audio.*;
|
import arc.audio.*;
|
||||||
|
import arc.audio.SoloudAudio.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
@@ -25,6 +26,11 @@ public class MusicControl{
|
|||||||
protected float fade;
|
protected float fade;
|
||||||
protected boolean silenced;
|
protected boolean silenced;
|
||||||
|
|
||||||
|
protected boolean wasPaused;
|
||||||
|
protected AudioFilter filter = new BiquadFilter(){{
|
||||||
|
set(0, 500, 1);
|
||||||
|
}};
|
||||||
|
|
||||||
public MusicControl(){
|
public MusicControl(){
|
||||||
Events.on(ClientLoadEvent.class, e -> reload());
|
Events.on(ClientLoadEvent.class, e -> reload());
|
||||||
|
|
||||||
@@ -54,6 +60,13 @@ public class MusicControl{
|
|||||||
|
|
||||||
/** Update and play the right music track.*/
|
/** Update and play the right music track.*/
|
||||||
public void update(){
|
public void update(){
|
||||||
|
boolean paused = state.isGame() && Core.scene.hasDialog();
|
||||||
|
|
||||||
|
if(paused != wasPaused){
|
||||||
|
Core.audio.setFilter(0, paused ? filter : null);
|
||||||
|
wasPaused = paused;
|
||||||
|
}
|
||||||
|
|
||||||
if(state.isMenu()){
|
if(state.isMenu()){
|
||||||
silenced = false;
|
silenced = false;
|
||||||
if(ui.planet.isShown()){
|
if(ui.planet.isShown()){
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class SoundLoop{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void update(float x, float y, boolean play){
|
public void update(float x, float y, boolean play){
|
||||||
if(baseVolume < 0) return;
|
if(baseVolume <= 0) return;
|
||||||
|
|
||||||
if(id < 0){
|
if(id < 0){
|
||||||
if(play){
|
if(play){
|
||||||
@@ -36,6 +36,7 @@ public class SoundLoop{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sound.setPan(id, sound.calcPan(x, y), sound.calcVolume(x, y) * volume * baseVolume);
|
sound.setPan(id, sound.calcPan(x, y), sound.calcVolume(x, y) * volume * baseVolume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -288,6 +288,10 @@ public class Blocks implements ContentList{
|
|||||||
attributes.set(Attribute.water, 1f);
|
attributes.set(Attribute.water, 1f);
|
||||||
cacheLayer = CacheLayer.mud;
|
cacheLayer = CacheLayer.mud;
|
||||||
albedo = 0.35f;
|
albedo = 0.35f;
|
||||||
|
walkSound = Sounds.mud;
|
||||||
|
walkSoundVolume = 0.08f;
|
||||||
|
walkSoundPitchMin = 0.4f;
|
||||||
|
walkSoundPitchMax = 0.5f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
((ShallowLiquid)darksandTaintedWater).set(Blocks.taintedWater, Blocks.darksand);
|
((ShallowLiquid)darksandTaintedWater).set(Blocks.taintedWater, Blocks.darksand);
|
||||||
@@ -592,6 +596,9 @@ public class Blocks implements ContentList{
|
|||||||
hasPower = true;
|
hasPower = true;
|
||||||
drawer = new DrawWeave();
|
drawer = new DrawWeave();
|
||||||
|
|
||||||
|
ambientSound = Sounds.techloop;
|
||||||
|
ambientSoundVolume = 0.02f;
|
||||||
|
|
||||||
consumes.items(with(Items.thorium, 4, Items.sand, 10));
|
consumes.items(with(Items.thorium, 4, Items.sand, 10));
|
||||||
consumes.power(5f);
|
consumes.power(5f);
|
||||||
itemCapacity = 20;
|
itemCapacity = 20;
|
||||||
@@ -720,6 +727,8 @@ public class Blocks implements ContentList{
|
|||||||
updateEffect = Fx.pulverizeSmall;
|
updateEffect = Fx.pulverizeSmall;
|
||||||
hasItems = hasPower = true;
|
hasItems = hasPower = true;
|
||||||
drawer = new DrawRotator();
|
drawer = new DrawRotator();
|
||||||
|
ambientSound = Sounds.grinding;
|
||||||
|
ambientSoundVolume = 0.02f;
|
||||||
|
|
||||||
consumes.item(Items.scrap, 1);
|
consumes.item(Items.scrap, 1);
|
||||||
consumes.power(0.50f);
|
consumes.power(0.50f);
|
||||||
@@ -1158,6 +1167,9 @@ public class Blocks implements ContentList{
|
|||||||
requirements(Category.power, with(Items.copper, 25, Items.lead, 15));
|
requirements(Category.power, with(Items.copper, 25, Items.lead, 15));
|
||||||
powerProduction = 1f;
|
powerProduction = 1f;
|
||||||
itemDuration = 120f;
|
itemDuration = 120f;
|
||||||
|
|
||||||
|
ambientSound = Sounds.smelter;
|
||||||
|
ambientSoundVolume = 0.03f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
thermalGenerator = new ThermalGenerator("thermal-generator"){{
|
thermalGenerator = new ThermalGenerator("thermal-generator"){{
|
||||||
@@ -1166,6 +1178,8 @@ public class Blocks implements ContentList{
|
|||||||
generateEffect = Fx.redgeneratespark;
|
generateEffect = Fx.redgeneratespark;
|
||||||
size = 2;
|
size = 2;
|
||||||
floating = true;
|
floating = true;
|
||||||
|
ambientSound = Sounds.hum;
|
||||||
|
ambientSoundVolume = 0.04f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
steamGenerator = new BurnerGenerator("steam-generator"){{
|
steamGenerator = new BurnerGenerator("steam-generator"){{
|
||||||
@@ -1175,6 +1189,9 @@ public class Blocks implements ContentList{
|
|||||||
consumes.liquid(Liquids.water, 0.1f);
|
consumes.liquid(Liquids.water, 0.1f);
|
||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
size = 2;
|
size = 2;
|
||||||
|
|
||||||
|
ambientSound = Sounds.smelter;
|
||||||
|
ambientSoundVolume = 0.05f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
differentialGenerator = new SingleTypeGenerator("differential-generator"){{
|
differentialGenerator = new SingleTypeGenerator("differential-generator"){{
|
||||||
@@ -1184,6 +1201,8 @@ public class Blocks implements ContentList{
|
|||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
size = 3;
|
size = 3;
|
||||||
|
ambientSound = Sounds.steam;
|
||||||
|
ambientSoundVolume = 0.03f;
|
||||||
|
|
||||||
consumes.item(Items.pyratite).optional(true, false);
|
consumes.item(Items.pyratite).optional(true, false);
|
||||||
consumes.liquid(Liquids.cryofluid, 0.1f);
|
consumes.liquid(Liquids.cryofluid, 0.1f);
|
||||||
@@ -1209,6 +1228,8 @@ public class Blocks implements ContentList{
|
|||||||
|
|
||||||
thoriumReactor = new NuclearReactor("thorium-reactor"){{
|
thoriumReactor = new NuclearReactor("thorium-reactor"){{
|
||||||
requirements(Category.power, with(Items.lead, 300, Items.silicon, 200, Items.graphite, 150, Items.thorium, 150, Items.metaglass, 50));
|
requirements(Category.power, with(Items.lead, 300, Items.silicon, 200, Items.graphite, 150, Items.thorium, 150, Items.metaglass, 50));
|
||||||
|
ambientSound = Sounds.hum;
|
||||||
|
ambientSoundVolume = 0.2f;
|
||||||
size = 3;
|
size = 3;
|
||||||
health = 700;
|
health = 700;
|
||||||
itemDuration = 360f;
|
itemDuration = 360f;
|
||||||
@@ -1224,6 +1245,9 @@ public class Blocks implements ContentList{
|
|||||||
health = 900;
|
health = 900;
|
||||||
powerProduction = 130f;
|
powerProduction = 130f;
|
||||||
itemDuration = 140f;
|
itemDuration = 140f;
|
||||||
|
ambientSound = Sounds.pulse;
|
||||||
|
ambientSoundVolume = 0.2f;
|
||||||
|
|
||||||
consumes.power(25f);
|
consumes.power(25f);
|
||||||
consumes.item(Items.blastCompound);
|
consumes.item(Items.blastCompound);
|
||||||
consumes.liquid(Liquids.cryofluid, 0.25f);
|
consumes.liquid(Liquids.cryofluid, 0.25f);
|
||||||
@@ -1464,7 +1488,7 @@ public class Blocks implements ContentList{
|
|||||||
inaccuracy = 1f;
|
inaccuracy = 1f;
|
||||||
shootCone = 10f;
|
shootCone = 10f;
|
||||||
health = 260;
|
health = 260;
|
||||||
shootSound = Sounds.artillery;
|
shootSound = Sounds.bang;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
wave = new LiquidTurret("wave"){{
|
wave = new LiquidTurret("wave"){{
|
||||||
@@ -1484,7 +1508,6 @@ public class Blocks implements ContentList{
|
|||||||
shootEffect = Fx.shootLiquid;
|
shootEffect = Fx.shootLiquid;
|
||||||
range = 110f;
|
range = 110f;
|
||||||
health = 250 * size * size;
|
health = 250 * size * size;
|
||||||
shootSound = Sounds.splash;
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
lancer = new ChargeTurret("lancer"){{
|
lancer = new ChargeTurret("lancer"){{
|
||||||
@@ -1632,7 +1655,6 @@ public class Blocks implements ContentList{
|
|||||||
shootEffect = Fx.shootLiquid;
|
shootEffect = Fx.shootLiquid;
|
||||||
range = 190f;
|
range = 190f;
|
||||||
health = 250 * size * size;
|
health = 250 * size * size;
|
||||||
shootSound = Sounds.splash;
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
fuse = new ItemTurret("fuse"){{
|
fuse = new ItemTurret("fuse"){{
|
||||||
@@ -1752,13 +1774,13 @@ public class Blocks implements ContentList{
|
|||||||
shots = 1;
|
shots = 1;
|
||||||
size = 4;
|
size = 4;
|
||||||
shootCone = 2f;
|
shootCone = 2f;
|
||||||
shootSound = Sounds.shootBig;
|
shootSound = Sounds.railgun;
|
||||||
unitSort = (u, x, y) -> -u.maxHealth;
|
unitSort = (u, x, y) -> -u.maxHealth;
|
||||||
|
|
||||||
coolantMultiplier = 0.09f;
|
coolantMultiplier = 0.11f;
|
||||||
|
|
||||||
health = 150 * size * size;
|
health = 150 * size * size;
|
||||||
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 2f)).update(false).optional(true, true);
|
coolantUsage = 1f;
|
||||||
|
|
||||||
consumes.powerCond(10f, TurretBuild::isActive);
|
consumes.powerCond(10f, TurretBuild::isActive);
|
||||||
}};
|
}};
|
||||||
@@ -1786,7 +1808,7 @@ public class Blocks implements ContentList{
|
|||||||
shootSound = Sounds.shootBig;
|
shootSound = Sounds.shootBig;
|
||||||
|
|
||||||
health = 160 * size * size;
|
health = 160 * size * size;
|
||||||
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 2f)).update(false).optional(true, true);
|
coolantUsage = 1f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
meltdown = new LaserTurret("meltdown"){{
|
meltdown = new LaserTurret("meltdown"){{
|
||||||
@@ -1802,8 +1824,8 @@ public class Blocks implements ContentList{
|
|||||||
shootDuration = 220f;
|
shootDuration = 220f;
|
||||||
powerUse = 17f;
|
powerUse = 17f;
|
||||||
shootSound = Sounds.laserbig;
|
shootSound = Sounds.laserbig;
|
||||||
activeSound = Sounds.beam;
|
loopSound = Sounds.beam;
|
||||||
activeSoundVolume = 2f;
|
loopSoundVolume = 2f;
|
||||||
|
|
||||||
shootType = new ContinuousLaserBulletType(70){{
|
shootType = new ContinuousLaserBulletType(70){{
|
||||||
length = 200f;
|
length = 200f;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class UnitTypes implements ContentList{
|
|||||||
public static @EntityDef({Unitc.class, Mechc.class}) UnitType mace, dagger, crawler, fortress, scepter, reign;
|
public static @EntityDef({Unitc.class, Mechc.class}) UnitType mace, dagger, crawler, fortress, scepter, reign;
|
||||||
|
|
||||||
//mech + builder + miner
|
//mech + builder + miner
|
||||||
public static @EntityDef({Unitc.class, Mechc.class, Builderc.class, Minerc.class}) UnitType nova, pulsar, quasar;
|
public static @EntityDef({Unitc.class, Mechc.class, Builderc.class}) UnitType nova, pulsar, quasar;
|
||||||
|
|
||||||
//mech
|
//mech
|
||||||
public static @EntityDef({Unitc.class, Mechc.class}) UnitType vela;
|
public static @EntityDef({Unitc.class, Mechc.class}) UnitType vela;
|
||||||
@@ -35,23 +35,23 @@ public class UnitTypes implements ContentList{
|
|||||||
//air (no special traits)
|
//air (no special traits)
|
||||||
public static @EntityDef({Unitc.class}) UnitType flare, eclipse, horizon, zenith, antumbra;
|
public static @EntityDef({Unitc.class}) UnitType flare, eclipse, horizon, zenith, antumbra;
|
||||||
|
|
||||||
//air + mining
|
//air, legacy mining
|
||||||
public static @EntityDef({Unitc.class, Minerc.class}) UnitType mono;
|
public static @EntityDef(value = {Unitc.class}, legacy = true) UnitType mono;
|
||||||
|
|
||||||
//air + building + mining
|
//air + building + mining
|
||||||
public static @EntityDef({Unitc.class, Builderc.class, Minerc.class}) UnitType poly;
|
public static @EntityDef({Unitc.class, Builderc.class}) UnitType poly;
|
||||||
|
|
||||||
//air + building + mining + payload
|
//air + building + mining + payload
|
||||||
public static @EntityDef({Unitc.class, Builderc.class, Minerc.class, Payloadc.class}) UnitType mega;
|
public static @EntityDef({Unitc.class, Builderc.class, Payloadc.class}) UnitType mega;
|
||||||
|
|
||||||
//air + building + payload
|
//air + building + payload
|
||||||
public static @EntityDef({Unitc.class, Builderc.class, Payloadc.class}) UnitType quad;
|
public static @EntityDef(value = {Unitc.class, Builderc.class, Payloadc.class}, legacy = true) UnitType quad;
|
||||||
|
|
||||||
//air + building + payload
|
//air + building + payload
|
||||||
public static @EntityDef({Unitc.class, Builderc.class, Payloadc.class, AmmoDistributec.class}) UnitType oct;
|
public static @EntityDef({Unitc.class, Builderc.class, Payloadc.class, AmmoDistributec.class}) UnitType oct;
|
||||||
|
|
||||||
//air + building + mining
|
//air + building + mining
|
||||||
public static @EntityDef({Unitc.class, Builderc.class, Minerc.class}) UnitType alpha, beta, gamma;
|
public static @EntityDef({Unitc.class, Builderc.class}) UnitType alpha, beta, gamma;
|
||||||
|
|
||||||
//water
|
//water
|
||||||
public static @EntityDef({Unitc.class, WaterMovec.class}) UnitType risso, minke, bryde, sei, omura;
|
public static @EntityDef({Unitc.class, WaterMovec.class}) UnitType risso, minke, bryde, sei, omura;
|
||||||
@@ -166,7 +166,7 @@ public class UnitTypes implements ContentList{
|
|||||||
recoil = 5f;
|
recoil = 5f;
|
||||||
shake = 2f;
|
shake = 2f;
|
||||||
ejectEffect = Fx.casing3;
|
ejectEffect = Fx.casing3;
|
||||||
shootSound = Sounds.artillery;
|
shootSound = Sounds.bang;
|
||||||
shots = 3;
|
shots = 3;
|
||||||
inaccuracy = 3f;
|
inaccuracy = 3f;
|
||||||
shotDelay = 4f;
|
shotDelay = 4f;
|
||||||
@@ -226,7 +226,7 @@ public class UnitTypes implements ContentList{
|
|||||||
recoil = 5f;
|
recoil = 5f;
|
||||||
shake = 2f;
|
shake = 2f;
|
||||||
ejectEffect = Fx.casing4;
|
ejectEffect = Fx.casing4;
|
||||||
shootSound = Sounds.artillery;
|
shootSound = Sounds.bang;
|
||||||
|
|
||||||
bullet = new BasicBulletType(13f, 60){{
|
bullet = new BasicBulletType(13f, 60){{
|
||||||
pierce = true;
|
pierce = true;
|
||||||
@@ -287,6 +287,8 @@ public class UnitTypes implements ContentList{
|
|||||||
alternate = false;
|
alternate = false;
|
||||||
ejectEffect = Fx.none;
|
ejectEffect = Fx.none;
|
||||||
recoil = 2f;
|
recoil = 2f;
|
||||||
|
shootSound = Sounds.lasershoot;
|
||||||
|
|
||||||
bullet = new LaserBoltBulletType(5.2f, 14){{
|
bullet = new LaserBoltBulletType(5.2f, 14){{
|
||||||
healPercent = 5f;
|
healPercent = 5f;
|
||||||
collidesTeam = true;
|
collidesTeam = true;
|
||||||
@@ -328,7 +330,7 @@ public class UnitTypes implements ContentList{
|
|||||||
spacing = 0f;
|
spacing = 0f;
|
||||||
ejectEffect = Fx.none;
|
ejectEffect = Fx.none;
|
||||||
recoil = 2.5f;
|
recoil = 2.5f;
|
||||||
shootSound = Sounds.pew;
|
shootSound = Sounds.spark;
|
||||||
|
|
||||||
bullet = new LightningBulletType(){{
|
bullet = new LightningBulletType(){{
|
||||||
lightningColor = hitColor = Pal.heal;
|
lightningColor = hitColor = Pal.heal;
|
||||||
@@ -430,7 +432,8 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
reload = 320f;
|
reload = 320f;
|
||||||
recoil = 0f;
|
recoil = 0f;
|
||||||
shootSound = Sounds.laser;
|
chargeSound = Sounds.lasercharge2;
|
||||||
|
shootSound = Sounds.beam;
|
||||||
continuous = true;
|
continuous = true;
|
||||||
cooldownTime = 200f;
|
cooldownTime = 200f;
|
||||||
|
|
||||||
@@ -491,6 +494,9 @@ public class UnitTypes implements ContentList{
|
|||||||
drawShields = false;
|
drawShields = false;
|
||||||
|
|
||||||
weapons.add(new Weapon("corvus-weapon"){{
|
weapons.add(new Weapon("corvus-weapon"){{
|
||||||
|
shootSound = Sounds.laserblast;
|
||||||
|
chargeSound = Sounds.lasercharge;
|
||||||
|
soundPitchMin = 1f;
|
||||||
top = false;
|
top = false;
|
||||||
mirror = false;
|
mirror = false;
|
||||||
shake = 14f;
|
shake = 14f;
|
||||||
@@ -498,7 +504,6 @@ public class UnitTypes implements ContentList{
|
|||||||
x = y = 0;
|
x = y = 0;
|
||||||
reload = 350f;
|
reload = 350f;
|
||||||
recoil = 0f;
|
recoil = 0f;
|
||||||
shootSound = Sounds.laser;
|
|
||||||
|
|
||||||
cooldownTime = 350f;
|
cooldownTime = 350f;
|
||||||
|
|
||||||
@@ -634,7 +639,7 @@ public class UnitTypes implements ContentList{
|
|||||||
ejectEffect = Fx.none;
|
ejectEffect = Fx.none;
|
||||||
recoil = 2f;
|
recoil = 2f;
|
||||||
rotate = true;
|
rotate = true;
|
||||||
shootSound = Sounds.flame;
|
shootSound = Sounds.sap;
|
||||||
|
|
||||||
x = 8.5f;
|
x = 8.5f;
|
||||||
y = -1.5f;
|
y = -1.5f;
|
||||||
@@ -657,6 +662,7 @@ public class UnitTypes implements ContentList{
|
|||||||
rotate = true;
|
rotate = true;
|
||||||
x = 4f;
|
x = 4f;
|
||||||
y = 3f;
|
y = 3f;
|
||||||
|
shootSound = Sounds.sap;
|
||||||
|
|
||||||
bullet = new SapBulletType(){{
|
bullet = new SapBulletType(){{
|
||||||
sapStrength = 0.8f;
|
sapStrength = 0.8f;
|
||||||
@@ -721,6 +727,7 @@ public class UnitTypes implements ContentList{
|
|||||||
y = 8f;
|
y = 8f;
|
||||||
rotate = true;
|
rotate = true;
|
||||||
bullet = sapper;
|
bullet = sapper;
|
||||||
|
shootSound = Sounds.sap;
|
||||||
}},
|
}},
|
||||||
new Weapon("spiroct-weapon"){{
|
new Weapon("spiroct-weapon"){{
|
||||||
reload = 15f;
|
reload = 15f;
|
||||||
@@ -728,6 +735,7 @@ public class UnitTypes implements ContentList{
|
|||||||
y = 6f;
|
y = 6f;
|
||||||
rotate = true;
|
rotate = true;
|
||||||
bullet = sapper;
|
bullet = sapper;
|
||||||
|
shootSound = Sounds.sap;
|
||||||
}},
|
}},
|
||||||
new Weapon("spiroct-weapon"){{
|
new Weapon("spiroct-weapon"){{
|
||||||
reload = 23f;
|
reload = 23f;
|
||||||
@@ -735,6 +743,7 @@ public class UnitTypes implements ContentList{
|
|||||||
y = 0f;
|
y = 0f;
|
||||||
rotate = true;
|
rotate = true;
|
||||||
bullet = sapper;
|
bullet = sapper;
|
||||||
|
shootSound = Sounds.sap;
|
||||||
}},
|
}},
|
||||||
new Weapon("large-purple-mount"){{
|
new Weapon("large-purple-mount"){{
|
||||||
y = -7f;
|
y = -7f;
|
||||||
@@ -744,7 +753,7 @@ public class UnitTypes implements ContentList{
|
|||||||
shake = 3f;
|
shake = 3f;
|
||||||
rotateSpeed = 2f;
|
rotateSpeed = 2f;
|
||||||
ejectEffect = Fx.casing1;
|
ejectEffect = Fx.casing1;
|
||||||
shootSound = Sounds.shootBig;
|
shootSound = Sounds.artillery;
|
||||||
rotate = true;
|
rotate = true;
|
||||||
occlusion = 8f;
|
occlusion = 8f;
|
||||||
recoil = 3f;
|
recoil = 3f;
|
||||||
@@ -842,7 +851,7 @@ public class UnitTypes implements ContentList{
|
|||||||
recoil = 10f;
|
recoil = 10f;
|
||||||
rotateSpeed = 1f;
|
rotateSpeed = 1f;
|
||||||
ejectEffect = Fx.casing3;
|
ejectEffect = Fx.casing3;
|
||||||
shootSound = Sounds.shootBig;
|
shootSound = Sounds.artillery;
|
||||||
rotate = true;
|
rotate = true;
|
||||||
occlusion = 30f;
|
occlusion = 30f;
|
||||||
|
|
||||||
@@ -1205,7 +1214,7 @@ public class UnitTypes implements ContentList{
|
|||||||
reload = 30f;
|
reload = 30f;
|
||||||
ejectEffect = Fx.none;
|
ejectEffect = Fx.none;
|
||||||
recoil = 2f;
|
recoil = 2f;
|
||||||
shootSound = Sounds.pew;
|
shootSound = Sounds.missile;
|
||||||
shots = 1;
|
shots = 1;
|
||||||
velocityRnd = 0.5f;
|
velocityRnd = 0.5f;
|
||||||
inaccuracy = 15f;
|
inaccuracy = 15f;
|
||||||
@@ -1221,6 +1230,7 @@ public class UnitTypes implements ContentList{
|
|||||||
smokeEffect = Fx.hitLaser;
|
smokeEffect = Fx.hitLaser;
|
||||||
hitEffect = despawnEffect = Fx.hitLaser;
|
hitEffect = despawnEffect = Fx.hitLaser;
|
||||||
frontColor = Color.white;
|
frontColor = Color.white;
|
||||||
|
hitSound = Sounds.none;
|
||||||
|
|
||||||
healPercent = 5.5f;
|
healPercent = 5.5f;
|
||||||
collidesTeam = true;
|
collidesTeam = true;
|
||||||
@@ -1252,6 +1262,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
weapons.add(
|
weapons.add(
|
||||||
new Weapon("heal-weapon-mount"){{
|
new Weapon("heal-weapon-mount"){{
|
||||||
|
shootSound = Sounds.lasershoot;
|
||||||
reload = 25f;
|
reload = 25f;
|
||||||
x = 8f;
|
x = 8f;
|
||||||
y = -6f;
|
y = -6f;
|
||||||
@@ -1259,6 +1270,7 @@ public class UnitTypes implements ContentList{
|
|||||||
bullet = Bullets.healBulletBig;
|
bullet = Bullets.healBulletBig;
|
||||||
}},
|
}},
|
||||||
new Weapon("heal-weapon-mount"){{
|
new Weapon("heal-weapon-mount"){{
|
||||||
|
shootSound = Sounds.lasershoot;
|
||||||
reload = 15f;
|
reload = 15f;
|
||||||
x = 4f;
|
x = 4f;
|
||||||
y = 5f;
|
y = 5f;
|
||||||
@@ -1578,7 +1590,7 @@ public class UnitTypes implements ContentList{
|
|||||||
inaccuracy = 7f;
|
inaccuracy = 7f;
|
||||||
ejectEffect = Fx.none;
|
ejectEffect = Fx.none;
|
||||||
shake = 3f;
|
shake = 3f;
|
||||||
shootSound = Sounds.shootBig;
|
shootSound = Sounds.missile;
|
||||||
xRand = 8f;
|
xRand = 8f;
|
||||||
shotDelay = 1f;
|
shotDelay = 1f;
|
||||||
|
|
||||||
@@ -1659,6 +1671,7 @@ public class UnitTypes implements ContentList{
|
|||||||
shake = 6f;
|
shake = 6f;
|
||||||
recoil = 10.5f;
|
recoil = 10.5f;
|
||||||
occlusion = 50f;
|
occlusion = 50f;
|
||||||
|
shootSound = Sounds.railgun;
|
||||||
|
|
||||||
shots = 1;
|
shots = 1;
|
||||||
ejectEffect = Fx.none;
|
ejectEffect = Fx.none;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package mindustry.content;
|
|||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.type.weather.*;
|
import mindustry.type.weather.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
@@ -23,12 +24,20 @@ public class Weathers implements ContentList{
|
|||||||
sizeMin = 2.6f;
|
sizeMin = 2.6f;
|
||||||
density = 1200f;
|
density = 1200f;
|
||||||
attrs.set(Attribute.light, -0.15f);
|
attrs.set(Attribute.light, -0.15f);
|
||||||
|
|
||||||
|
sound = Sounds.windhowl;
|
||||||
|
soundVol = 0f;
|
||||||
|
soundVolOscMag = 1.5f;
|
||||||
|
soundVolOscScl = 1100f;
|
||||||
|
soundVolMin = 0.02f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
rain = new RainWeather("rain"){{
|
rain = new RainWeather("rain"){{
|
||||||
attrs.set(Attribute.light, -0.2f);
|
attrs.set(Attribute.light, -0.2f);
|
||||||
attrs.set(Attribute.water, 0.2f);
|
attrs.set(Attribute.water, 0.2f);
|
||||||
status = StatusEffects.wet;
|
status = StatusEffects.wet;
|
||||||
|
sound = Sounds.rain;
|
||||||
|
soundVol = 0.25f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
sandstorm = new ParticleWeather("sandstorm"){{
|
sandstorm = new ParticleWeather("sandstorm"){{
|
||||||
@@ -46,6 +55,8 @@ public class Weathers implements ContentList{
|
|||||||
attrs.set(Attribute.water, -0.1f);
|
attrs.set(Attribute.water, -0.1f);
|
||||||
opacityMultiplier = 0.8f;
|
opacityMultiplier = 0.8f;
|
||||||
force = 0.1f;
|
force = 0.1f;
|
||||||
|
sound = Sounds.wind;
|
||||||
|
soundVol = 0.3f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
sporestorm = new ParticleWeather("sporestorm"){{
|
sporestorm = new ParticleWeather("sporestorm"){{
|
||||||
@@ -65,6 +76,8 @@ public class Weathers implements ContentList{
|
|||||||
status = StatusEffects.sporeSlowed;
|
status = StatusEffects.sporeSlowed;
|
||||||
opacityMultiplier = 0.85f;
|
opacityMultiplier = 0.85f;
|
||||||
force = 0.1f;
|
force = 0.1f;
|
||||||
|
sound = Sounds.wind;
|
||||||
|
soundVol = 0.3f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
fog = new ParticleWeather("fog"){{
|
fog = new ParticleWeather("fog"){{
|
||||||
|
|||||||
@@ -477,10 +477,6 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
dialog.show();
|
dialog.show();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(android){
|
|
||||||
Sounds.empty.loop(0f, 1f, 0f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -640,7 +640,7 @@ public class NetServer implements ApplicationListener{
|
|||||||
Unit unit = player.unit();
|
Unit unit = player.unit();
|
||||||
|
|
||||||
long elapsed = Time.timeSinceMillis(con.lastReceivedClientTime);
|
long elapsed = Time.timeSinceMillis(con.lastReceivedClientTime);
|
||||||
float maxSpeed = ((player.unit().type.canBoost && player.unit().isFlying()) ? player.unit().type.boostMultiplier : 1f) * player.unit().type.speed;
|
float maxSpeed = ((player.unit().type.canBoost && player.unit().isFlying()) ? player.unit().type.boostMultiplier : 1f) * player.unit().speed();
|
||||||
if(unit.isGrounded()){
|
if(unit.isGrounded()){
|
||||||
maxSpeed *= unit.floorSpeedMultiplier();
|
maxSpeed *= unit.floorSpeedMultiplier();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ public abstract class UnlockableContent extends MappableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean unlocked(){
|
public boolean unlocked(){
|
||||||
if(net != null && net.client()) return state.rules.researched.contains(name);
|
if(net != null && net.client()) return alwaysUnlocked || state.rules.researched.contains(name);
|
||||||
return unlocked || alwaysUnlocked;
|
return unlocked || alwaysUnlocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ public abstract class BulletType extends Content{
|
|||||||
Damage.createIncend(x, y, incendSpread, incendAmount);
|
Damage.createIncend(x, y, incendSpread, incendAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(splashDamageRadius > 0){
|
if(splashDamageRadius > 0 && !b.absorbed){
|
||||||
Damage.damage(b.team, x, y, splashDamageRadius, splashDamage * b.damageMultiplier(), collidesAir, collidesGround);
|
Damage.damage(b.team, x, y, splashDamageRadius, splashDamage * b.damageMultiplier(), collidesAir, collidesGround);
|
||||||
|
|
||||||
if(status != StatusEffects.none){
|
if(status != StatusEffects.none){
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ abstract class BuilderComp implements Unitc{
|
|||||||
|
|
||||||
@Import float x, y, rotation;
|
@Import float x, y, rotation;
|
||||||
|
|
||||||
@SyncLocal Queue<BuildPlan> plans = new Queue<>();
|
@SyncLocal Queue<BuildPlan> plans = new Queue<>(1);
|
||||||
@SyncLocal transient boolean updateBuilding = true;
|
@SyncLocal transient boolean updateBuilding = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -35,7 +35,6 @@ abstract class BuilderComp implements Unitc{
|
|||||||
if(!updateBuilding) return;
|
if(!updateBuilding) return;
|
||||||
|
|
||||||
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange;
|
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange;
|
||||||
|
|
||||||
boolean infinite = state.rules.infiniteResources || team().rules().infiniteResources;
|
boolean infinite = state.rules.infiniteResources || team().rules().infiniteResources;
|
||||||
|
|
||||||
Iterator<BuildPlan> it = plans.iterator();
|
Iterator<BuildPlan> it = plans.iterator();
|
||||||
@@ -69,10 +68,6 @@ abstract class BuilderComp implements Unitc{
|
|||||||
|
|
||||||
Tile tile = world.tile(current.x, current.y);
|
Tile tile = world.tile(current.x, current.y);
|
||||||
|
|
||||||
if(within(tile, finalPlaceDst)){
|
|
||||||
lookAt(angleTo(tile));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!(tile.block() instanceof ConstructBlock)){
|
if(!(tile.block() instanceof ConstructBlock)){
|
||||||
if(!current.initialized && !current.breaking && Build.validPlace(current.block, team(), current.x, current.y, current.rotation)){
|
if(!current.initialized && !current.breaking && Build.validPlace(current.block, team(), current.x, current.y, current.rotation)){
|
||||||
boolean hasAll = infinite || !Structs.contains(current.block.requirements, i -> core != null && !core.items.has(i.item));
|
boolean hasAll = infinite || !Structs.contains(current.block.requirements, i -> core != null && !core.items.has(i.item));
|
||||||
@@ -188,6 +183,10 @@ abstract class BuilderComp implements Unitc{
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean activelyBuilding(){
|
boolean activelyBuilding(){
|
||||||
|
//not actively building when not near the build plan
|
||||||
|
if(isBuilding() && !within(buildPlan(), state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return isBuilding() && updateBuilding;
|
return isBuilding() && updateBuilding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import mindustry.logic.*;
|
|||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
import mindustry.world.blocks.*;
|
||||||
import mindustry.world.blocks.ConstructBlock.*;
|
import mindustry.world.blocks.ConstructBlock.*;
|
||||||
import mindustry.world.blocks.environment.*;
|
import mindustry.world.blocks.environment.*;
|
||||||
import mindustry.world.blocks.payloads.*;
|
import mindustry.world.blocks.payloads.*;
|
||||||
@@ -106,8 +107,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
this.block = block;
|
this.block = block;
|
||||||
this.team = team;
|
this.team = team;
|
||||||
|
|
||||||
if(block.activeSound != Sounds.none){
|
if(block.loopSound != Sounds.none){
|
||||||
sound = new SoundLoop(block.activeSound, block.activeSoundVolume);
|
sound = new SoundLoop(block.loopSound, block.loopSoundVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
health = block.health;
|
health = block.health;
|
||||||
@@ -780,7 +781,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @return whether this block should play its idle sound.*/
|
/** @return whether this block should play its idle sound.*/
|
||||||
public boolean shouldIdleSound(){
|
public boolean shouldAmbientSound(){
|
||||||
return shouldConsume();
|
return shouldConsume();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1225,6 +1226,11 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return ambient sound volume scale. */
|
||||||
|
public float ambientVolume(){
|
||||||
|
return efficiency();
|
||||||
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
//region overrides
|
//region overrides
|
||||||
|
|
||||||
@@ -1285,6 +1291,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
case powerNetStored -> power == null ? 0 : power.graph.getLastPowerStored();
|
case powerNetStored -> power == null ? 0 : power.graph.getLastPowerStored();
|
||||||
case powerNetCapacity -> power == null ? 0 : power.graph.getLastCapacity();
|
case powerNetCapacity -> power == null ? 0 : power.graph.getLastCapacity();
|
||||||
case enabled -> enabled ? 1 : 0;
|
case enabled -> enabled ? 1 : 0;
|
||||||
|
case controlled -> this instanceof ControlBlock c ? c.isControlled() ? 1 : 0 : 0;
|
||||||
case payloadCount -> getPayload() != null ? 1 : 0;
|
case payloadCount -> getPayload() != null ? 1 : 0;
|
||||||
default -> 0;
|
default -> 0;
|
||||||
};
|
};
|
||||||
@@ -1365,8 +1372,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
sound.update(x, y, shouldActiveSound());
|
sound.update(x, y, shouldActiveSound());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(block.idleSound != Sounds.none && shouldIdleSound()){
|
if(block.ambientSound != Sounds.none && shouldAmbientSound()){
|
||||||
loops.play(block.idleSound, self(), block.idleSoundVolume);
|
loops.play(block.ambientSound, self(), block.ambientSoundVolume * ambientVolume());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enabled || !block.noUpdateDisabled){
|
if(enabled || !block.noUpdateDisabled){
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
|
|||||||
Object data;
|
Object data;
|
||||||
BulletType type;
|
BulletType type;
|
||||||
float fdata;
|
float fdata;
|
||||||
|
transient boolean absorbed;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getCollisions(Cons<QuadTree> consumer){
|
public void getCollisions(Cons<QuadTree> consumer){
|
||||||
@@ -67,6 +68,7 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void absorb(){
|
public void absorb(){
|
||||||
|
absorbed = true;
|
||||||
remove();
|
remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,10 +75,14 @@ abstract class FlyingComp implements Posc, Velc, Healthc, Hitboxc{
|
|||||||
wasFlying = isFlying();
|
wasFlying = isFlying();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!hovering && isGrounded() && floor.isLiquid){
|
if(!hovering && isGrounded()){
|
||||||
if((splashTimer += Mathf.dst(deltaX(), deltaY())) >= (7f + hitSize()/8f)){
|
if((splashTimer += Mathf.dst(deltaX(), deltaY())) >= (7f + hitSize()/8f)){
|
||||||
floor.walkEffect.at(x, y, hitSize() / 8f, floor.mapColor);
|
floor.walkEffect.at(x, y, hitSize() / 8f, floor.mapColor);
|
||||||
splashTimer = 0f;
|
splashTimer = 0f;
|
||||||
|
|
||||||
|
if(!(this instanceof WaterMovec)){
|
||||||
|
floor.walkSound.at(x, y, Mathf.random(floor.walkSoundPitchMin, floor.walkSoundPitchMax), floor.walkSoundVolume);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{
|
|||||||
Floor floor = Vars.world.floorWorld(l.base.x, l.base.y);
|
Floor floor = Vars.world.floorWorld(l.base.x, l.base.y);
|
||||||
if(floor.isLiquid){
|
if(floor.isLiquid){
|
||||||
floor.walkEffect.at(l.base.x, l.base.y, type.rippleScale, floor.mapColor);
|
floor.walkEffect.at(l.base.x, l.base.y, type.rippleScale, floor.mapColor);
|
||||||
|
floor.walkSound.at(x, y, 1f, floor.walkSoundVolume);
|
||||||
}else{
|
}else{
|
||||||
Fx.unitLandSmall.at(l.base.x, l.base.y, type.rippleScale, floor.mapColor);
|
Fx.unitLandSmall.at(l.base.x, l.base.y, type.rippleScale, floor.mapColor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ import mindustry.world.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{
|
||||||
@Import float x, y, rotation;
|
@Import float x, y, rotation, hitSize;
|
||||||
@Import UnitType type;
|
@Import UnitType type;
|
||||||
|
|
||||||
transient float mineTimer;
|
transient float mineTimer;
|
||||||
@@ -28,7 +28,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean offloadImmediately(){
|
public boolean offloadImmediately(){
|
||||||
return isPlayer();
|
return this.<Unit>self().isPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean mining(){
|
boolean mining(){
|
||||||
@@ -63,7 +63,6 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
|||||||
mineTimer = 0f;
|
mineTimer = 0f;
|
||||||
}else if(mining()){
|
}else if(mining()){
|
||||||
Item item = mineTile.drop();
|
Item item = mineTile.drop();
|
||||||
lookAt(angleTo(mineTile.worldx(), mineTile.worldy()));
|
|
||||||
mineTimer += Time.delta *type.mineSpeed;
|
mineTimer += Time.delta *type.mineSpeed;
|
||||||
|
|
||||||
if(Mathf.chance(0.06 * Time.delta)){
|
if(Mathf.chance(0.06 * Time.delta)){
|
||||||
@@ -88,13 +87,17 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
|||||||
mineTimer = 0f;
|
mineTimer = 0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!headless){
|
||||||
|
loops.play(type.mineSound, this, type.mineSoundVolume);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
if(!mining()) return;
|
if(!mining()) return;
|
||||||
float focusLen = hitSize() / 2f + Mathf.absin(Time.time(), 1.1f, 0.5f);
|
float focusLen = hitSize / 2f + Mathf.absin(Time.time(), 1.1f, 0.5f);
|
||||||
float swingScl = 12f, swingMag = tilesize / 8f;
|
float swingScl = 12f, swingMag = tilesize / 8f;
|
||||||
float flashScl = 0.3f;
|
float flashScl = 0.3f;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import arc.scene.ui.layout.*;
|
|||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.ai.*;
|
import mindustry.ai.*;
|
||||||
|
import mindustry.ai.types.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.core.*;
|
import mindustry.core.*;
|
||||||
@@ -30,10 +31,10 @@ import mindustry.world.blocks.payloads.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@Component(base = true)
|
@Component(base = true)
|
||||||
abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Commanderc, Displayable, Senseable, Ranged{
|
abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Commanderc, Displayable, Senseable, Ranged, Minerc{
|
||||||
|
|
||||||
@Import boolean hovering, dead;
|
@Import boolean hovering, dead;
|
||||||
@Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health, ammo;
|
@Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health, ammo, minFormationSpeed;
|
||||||
@Import Team team;
|
@Import Team team;
|
||||||
@Import int id;
|
@Import int id;
|
||||||
|
|
||||||
@@ -67,9 +68,14 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
return type.hasWeapons();
|
return type.hasWeapons();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float speed(){
|
||||||
|
//limit speed to minimum formation speed to preserve formation
|
||||||
|
return isCommanding() ? minFormationSpeed * 0.98f : type.speed;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return speed with boost multipliers factored in. */
|
/** @return speed with boost multipliers factored in. */
|
||||||
public float realSpeed(){
|
public float realSpeed(){
|
||||||
return Mathf.lerp(1f, type.canBoost ? type.boostMultiplier : 1f, elevation) * type.speed;
|
return Mathf.lerp(1f, type.canBoost ? type.boostMultiplier : 1f, elevation) * speed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Iterates through this unit and everything it is controlling. */
|
/** Iterates through this unit and everything it is controlling. */
|
||||||
@@ -78,6 +84,18 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
controlling().each(cons);
|
controlling().each(cons);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return where the unit wants to look at. */
|
||||||
|
public float prefRotation(){
|
||||||
|
if(this instanceof Builderc builder && builder.activelyBuilding()){
|
||||||
|
return angleTo(builder.buildPlan());
|
||||||
|
}else if(mineTile() != null){
|
||||||
|
return angleTo(mineTile());
|
||||||
|
}else if(moving()){
|
||||||
|
return vel().angle();
|
||||||
|
}
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float range(){
|
public float range(){
|
||||||
return type.range;
|
return type.range;
|
||||||
@@ -105,6 +123,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
case shootX -> World.conv(aimX());
|
case shootX -> World.conv(aimX());
|
||||||
case shootY -> World.conv(aimY());
|
case shootY -> World.conv(aimY());
|
||||||
case flag -> flag;
|
case flag -> flag;
|
||||||
|
case controlled -> controller instanceof LogicAI || controller instanceof Player ? 1 : 0;
|
||||||
case payloadCount -> self() instanceof Payloadc pay ? pay.payloads().size : 0;
|
case payloadCount -> self() instanceof Payloadc pay ? pay.payloads().size : 0;
|
||||||
default -> 0;
|
default -> 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import arc.math.*;
|
|||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
|
import mindustry.audio.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.bullet.*;
|
import mindustry.entities.bullet.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
@@ -117,10 +118,18 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
|||||||
mount.bullet.rotation(weaponRotation + 90);
|
mount.bullet.rotation(weaponRotation + 90);
|
||||||
mount.bullet.set(shootX, shootY);
|
mount.bullet.set(shootX, shootY);
|
||||||
vel.add(Tmp.v1.trns(rotation + 180f, mount.bullet.type.recoil));
|
vel.add(Tmp.v1.trns(rotation + 180f, mount.bullet.type.recoil));
|
||||||
|
if(weapon.shootSound != Sounds.none && !headless){
|
||||||
|
if(mount.sound == null) mount.sound = new SoundLoop(weapon.shootSound, 1f);
|
||||||
|
mount.sound.update(x, y, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
//heat decreases when not firing
|
//heat decreases when not firing
|
||||||
mount.heat = Math.max(mount.heat - Time.delta * reloadMultiplier / mount.weapon.cooldownTime, 0);
|
mount.heat = Math.max(mount.heat - Time.delta * reloadMultiplier / mount.weapon.cooldownTime, 0);
|
||||||
|
|
||||||
|
if(mount.sound != null){
|
||||||
|
mount.sound.update(x, y, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//flip weapon shoot side for alternating weapons at half reload
|
//flip weapon shoot side for alternating weapons at half reload
|
||||||
@@ -168,7 +177,7 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
|||||||
float baseX = this.x, baseY = this.y;
|
float baseX = this.x, baseY = this.y;
|
||||||
boolean delay = weapon.firstShotDelay + weapon.shotDelay > 0f;
|
boolean delay = weapon.firstShotDelay + weapon.shotDelay > 0f;
|
||||||
|
|
||||||
(delay ? weapon.chargeSound : weapon.shootSound).at(x, y, Mathf.random(0.8f, 1.0f));
|
(delay ? weapon.chargeSound : weapon.continuous ? Sounds.none : weapon.shootSound).at(x, y, Mathf.random(weapon.soundPitchMin, weapon.soundPitchMax));
|
||||||
|
|
||||||
BulletType ammo = weapon.bullet;
|
BulletType ammo = weapon.bullet;
|
||||||
float lifeScl = ammo.scaleVelocity ? Mathf.clamp(Mathf.dst(x, y, aimX, aimY) / ammo.range()) : 1f;
|
float lifeScl = ammo.scaleVelocity ? Mathf.clamp(Mathf.dst(x, y, aimX, aimY) / ammo.range()) : 1f;
|
||||||
@@ -195,7 +204,9 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
|||||||
vel.add(Tmp.v1.trns(rotation + 180f, ammo.recoil));
|
vel.add(Tmp.v1.trns(rotation + 180f, ammo.recoil));
|
||||||
Effect.shake(weapon.shake, weapon.shake, x, y);
|
Effect.shake(weapon.shake, weapon.shake, x, y);
|
||||||
mount.heat = 1f;
|
mount.heat = 1f;
|
||||||
weapon.shootSound.at(x, y, Mathf.random(0.8f, 1.0f));
|
if(!weapon.continuous){
|
||||||
|
weapon.shootSound.at(x, y, Mathf.random(weapon.soundPitchMin, weapon.soundPitchMax));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
vel.add(Tmp.v1.trns(rotation + 180f, ammo.recoil));
|
vel.add(Tmp.v1.trns(rotation + 180f, ammo.recoil));
|
||||||
|
|||||||
@@ -64,9 +64,7 @@ public class AIController implements UnitController{
|
|||||||
if(unit.isFlying()){
|
if(unit.isFlying()){
|
||||||
unit.wobble();
|
unit.wobble();
|
||||||
|
|
||||||
if(unit.moving()){
|
unit.lookAt(unit.prefRotation());
|
||||||
unit.lookAt(unit.vel.angle());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +92,7 @@ public class AIController implements UnitController{
|
|||||||
|
|
||||||
if(tile == targetTile || (costType == Pathfinder.costWater && !targetTile.floor().isLiquid)) return;
|
if(tile == targetTile || (costType == Pathfinder.costWater && !targetTile.floor().isLiquid)) return;
|
||||||
|
|
||||||
unit.moveAt(vec.trns(unit.angleTo(targetTile), unit.type.speed));
|
unit.moveAt(vec.trns(unit.angleTo(targetTile), unit.speed()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateWeapons(){
|
protected void updateWeapons(){
|
||||||
@@ -175,7 +173,7 @@ public class AIController implements UnitController{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void circle(Position target, float circleLength){
|
protected void circle(Position target, float circleLength){
|
||||||
circle(target, circleLength, unit.type.speed);
|
circle(target, circleLength, unit.speed());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void circle(Position target, float circleLength, float speed){
|
protected void circle(Position target, float circleLength, float speed){
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import mindustry.world.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
/** Class for storing build requests. Can be either a place or remove request. */
|
/** Class for storing build requests. Can be either a place or remove request. */
|
||||||
public class BuildPlan{
|
public class BuildPlan implements Position{
|
||||||
/** Position and rotation of this request. */
|
/** Position and rotation of this request. */
|
||||||
public int x, y, rotation;
|
public int x, y, rotation;
|
||||||
/** Block being placed. If null, this is a breaking request.*/
|
/** Block being placed. If null, this is a breaking request.*/
|
||||||
@@ -127,11 +127,11 @@ public class BuildPlan{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public float drawx(){
|
public float drawx(){
|
||||||
return x*tilesize + block.offset;
|
return x*tilesize + (block == null ? 0 : block.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float drawy(){
|
public float drawy(){
|
||||||
return y*tilesize + block.offset;
|
return y*tilesize + (block == null ? 0 : block.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Tile tile(){
|
public @Nullable Tile tile(){
|
||||||
@@ -142,6 +142,16 @@ public class BuildPlan{
|
|||||||
return world.build(x, y);
|
return world.build(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getX(){
|
||||||
|
return drawx();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getY(){
|
||||||
|
return drawy();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return "BuildRequest{" +
|
return "BuildRequest{" +
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.entities.units;
|
package mindustry.entities.units;
|
||||||
|
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
|
import mindustry.audio.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
|
||||||
@@ -25,6 +26,8 @@ public class WeaponMount{
|
|||||||
public boolean side;
|
public boolean side;
|
||||||
/** current bullet for continuous weapons */
|
/** current bullet for continuous weapons */
|
||||||
public @Nullable Bullet bullet;
|
public @Nullable Bullet bullet;
|
||||||
|
/** sound loop for continuous weapons */
|
||||||
|
public @Nullable SoundLoop sound;
|
||||||
|
|
||||||
public WeaponMount(Weapon weapon){
|
public WeaponMount(Weapon weapon){
|
||||||
this.weapon = weapon;
|
this.weapon = weapon;
|
||||||
|
|||||||
@@ -481,8 +481,8 @@ public class DesktopInput extends InputHandler{
|
|||||||
deleting = true;
|
deleting = true;
|
||||||
}else if(selected != null){
|
}else if(selected != null){
|
||||||
//only begin shooting if there's no cursor event
|
//only begin shooting if there's no cursor event
|
||||||
if(!tileTapped(selected.build) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && (player.builder().plans().size == 0 || !player.builder().updateBuilding()) && !droppingItem &&
|
if(!tileTapped(selected.build) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !player.builder().activelyBuilding() && !droppingItem &&
|
||||||
!tryBeginMine(selected) && player.miner().mineTile() == null && !Core.scene.hasKeyboard()){
|
!tryBeginMine(selected) && player.miner().mineTile() == null && !Core.scene.hasKeyboard()){
|
||||||
player.shooting = shouldShoot;
|
player.shooting = shouldShoot;
|
||||||
}
|
}
|
||||||
}else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine
|
}else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine
|
||||||
@@ -603,13 +603,6 @@ public class DesktopInput extends InputHandler{
|
|||||||
boolean ground = unit.isGrounded();
|
boolean ground = unit.isGrounded();
|
||||||
|
|
||||||
float strafePenalty = ground ? 1f : Mathf.lerp(1f, unit.type.strafePenalty, Angles.angleDist(unit.vel().angle(), unit.rotation()) / 180f);
|
float strafePenalty = ground ? 1f : Mathf.lerp(1f, unit.type.strafePenalty, Angles.angleDist(unit.vel().angle(), unit.rotation()) / 180f);
|
||||||
float baseSpeed = unit.type.speed;
|
|
||||||
|
|
||||||
//limit speed to minimum formation speed to preserve formation
|
|
||||||
if(unit.isCommanding()){
|
|
||||||
//add a tiny multiplier to let units catch up just in case
|
|
||||||
baseSpeed = unit.minFormationSpeed * 0.95f;
|
|
||||||
}
|
|
||||||
|
|
||||||
float speed = unit.realSpeed() * strafePenalty;
|
float speed = unit.realSpeed() * strafePenalty;
|
||||||
float xa = Core.input.axis(Binding.move_x);
|
float xa = Core.input.axis(Binding.move_x);
|
||||||
@@ -627,9 +620,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
if(aimCursor){
|
if(aimCursor){
|
||||||
unit.lookAt(mouseAngle);
|
unit.lookAt(mouseAngle);
|
||||||
}else{
|
}else{
|
||||||
if(!movement.isZero()){
|
unit.lookAt(unit.prefRotation());
|
||||||
unit.lookAt(unit.vel.isZero() ? movement.angle() : unit.vel.angle());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(omni){
|
if(omni){
|
||||||
|
|||||||
@@ -933,11 +933,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
|
|
||||||
boolean canMine(Tile tile){
|
boolean canMine(Tile tile){
|
||||||
return !Core.scene.hasMouse()
|
return !Core.scene.hasMouse()
|
||||||
&& tile.drop() != null
|
&& tile.drop() != null
|
||||||
&& player.miner().validMine(tile)
|
&& player.miner().validMine(tile)
|
||||||
&& !(tile.floor().playerUnmineable && tile.overlay().itemDrop == null)
|
&& !(tile.floor().playerUnmineable && tile.overlay().itemDrop == null)
|
||||||
&& player.unit().acceptsItem(tile.drop())
|
&& player.unit().acceptsItem(tile.drop())
|
||||||
&& tile.block() == Blocks.air;
|
&& tile.block() == Blocks.air;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the tile at the specified MOUSE coordinates. */
|
/** Returns the tile at the specified MOUSE coordinates. */
|
||||||
@@ -1044,7 +1044,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean canShoot(){
|
public boolean canShoot(){
|
||||||
return block == null && !onConfigurable() && !isDroppingItem() && !(player.builder().updateBuilding() && player.builder().isBuilding()) &&
|
return block == null && !onConfigurable() && !isDroppingItem() && !player.builder().activelyBuilding() &&
|
||||||
!(player.unit() instanceof Mechc && player.unit().isFlying());
|
!(player.unit() instanceof Mechc && player.unit().isFlying());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -856,14 +856,6 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
float attractDst = 15f;
|
float attractDst = 15f;
|
||||||
float strafePenalty = legs ? 1f : Mathf.lerp(1f, type.strafePenalty, Angles.angleDist(unit.vel.angle(), unit.rotation) / 180f);
|
float strafePenalty = legs ? 1f : Mathf.lerp(1f, type.strafePenalty, Angles.angleDist(unit.vel.angle(), unit.rotation) / 180f);
|
||||||
|
|
||||||
float baseSpeed = unit.type.speed;
|
|
||||||
|
|
||||||
//limit speed to minimum formation speed to preserve formation
|
|
||||||
if(unit.isCommanding()){
|
|
||||||
//add a tiny multiplier to let units catch up just in case
|
|
||||||
baseSpeed = unit.minFormationSpeed * 0.98f;
|
|
||||||
}
|
|
||||||
|
|
||||||
float speed = unit.realSpeed() * strafePenalty;
|
float speed = unit.realSpeed() * strafePenalty;
|
||||||
float range = unit.hasWeapons() ? unit.range() : 0f;
|
float range = unit.hasWeapons() ? unit.range() : 0f;
|
||||||
float bulletSpeed = unit.hasWeapons() ? type.weapons.first().bullet.speed : 0f;
|
float bulletSpeed = unit.hasWeapons() ? type.weapons.first().bullet.speed : 0f;
|
||||||
@@ -873,9 +865,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
if(aimCursor){
|
if(aimCursor){
|
||||||
unit.lookAt(mouseAngle);
|
unit.lookAt(mouseAngle);
|
||||||
}else{
|
}else{
|
||||||
if(unit.moving()){
|
unit.lookAt(unit.prefRotation());
|
||||||
unit.lookAt(unit.vel.angle());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(payloadTarget != null && unit instanceof Payloadc pay){
|
if(payloadTarget != null && unit instanceof Payloadc pay){
|
||||||
@@ -905,7 +895,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
|
|
||||||
if(player.within(targetPos, attractDst)){
|
if(player.within(targetPos, attractDst)){
|
||||||
movement.setZero();
|
movement.setZero();
|
||||||
unit.vel.approachDelta(Vec2.ZERO, type.speed * type.accel / 2f);
|
unit.vel.approachDelta(Vec2.ZERO, unit.speed() * type.accel / 2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float expansion = 3f;
|
float expansion = 3f;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public enum LAccess{
|
|||||||
team,
|
team,
|
||||||
type,
|
type,
|
||||||
flag,
|
flag,
|
||||||
|
controlled,
|
||||||
name,
|
name,
|
||||||
config,
|
config,
|
||||||
payloadCount,
|
payloadCount,
|
||||||
|
|||||||
@@ -96,11 +96,13 @@ public class LAssembler{
|
|||||||
if(data == null || data.isEmpty()) return new Seq<>();
|
if(data == null || data.isEmpty()) return new Seq<>();
|
||||||
|
|
||||||
Seq<LStatement> statements = new Seq<>();
|
Seq<LStatement> statements = new Seq<>();
|
||||||
String[] lines = data.split("[;\n]+");
|
String[] lines = data.split("\n");
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for(String line : lines){
|
for(String line : lines){
|
||||||
//comments
|
//comments
|
||||||
if(line.startsWith("#")) continue;
|
if(line.startsWith("#")) continue;
|
||||||
|
//remove trailing semicolons in case someone adds them in for no reason
|
||||||
|
if(line.endsWith(";")) line = line.substring(0, line.length() - 1);
|
||||||
|
|
||||||
if(index++ > max) break;
|
if(index++ > max) break;
|
||||||
|
|
||||||
|
|||||||
@@ -469,7 +469,7 @@ public class LExecutor{
|
|||||||
|
|
||||||
Building build = exec.building(p1);
|
Building build = exec.building(p1);
|
||||||
int dropped = Math.min(unit.stack.amount, exec.numi(p2));
|
int dropped = Math.min(unit.stack.amount, exec.numi(p2));
|
||||||
if(build != null && dropped > 0 && unit.within(build, logicItemTransferRange + build.block.size * tilesize/2f)){
|
if(build != null && build.isValid() && dropped > 0 && unit.within(build, logicItemTransferRange + build.block.size * tilesize/2f)){
|
||||||
int accepted = build.acceptStack(unit.item(), dropped, unit);
|
int accepted = build.acceptStack(unit.item(), dropped, unit);
|
||||||
if(accepted > 0){
|
if(accepted > 0){
|
||||||
Call.transferItemTo(unit, unit.item(), accepted, unit.x, unit.y, build);
|
Call.transferItemTo(unit, unit.item(), accepted, unit.x, unit.y, build);
|
||||||
@@ -483,7 +483,7 @@ public class LExecutor{
|
|||||||
Building build = exec.building(p1);
|
Building build = exec.building(p1);
|
||||||
int amount = exec.numi(p3);
|
int amount = exec.numi(p3);
|
||||||
|
|
||||||
if(build != null && build.items != null && exec.obj(p2) instanceof Item item && unit.within(build, logicItemTransferRange + build.block.size * tilesize/2f)){
|
if(build != null && build.isValid() && build.items != null && exec.obj(p2) instanceof Item item && unit.within(build, logicItemTransferRange + build.block.size * tilesize/2f)){
|
||||||
int taken = Math.min(build.items.get(item), Math.min(amount, unit.maxAccepted(item)));
|
int taken = Math.min(build.items.get(item), Math.min(amount, unit.maxAccepted(item)));
|
||||||
|
|
||||||
if(taken > 0){
|
if(taken > 0){
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ import mindustry.gen.*;
|
|||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
import static mindustry.game.EventType.*;
|
import static mindustry.game.EventType.*;
|
||||||
|
|
||||||
@@ -449,111 +447,11 @@ public class Administration{
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void load(){
|
private void load(){
|
||||||
if(!loadLegacy()){
|
//load default data
|
||||||
//load default data
|
playerInfo = Core.settings.getJson("player-data", ObjectMap.class, ObjectMap::new);
|
||||||
playerInfo = Core.settings.getJson("player-data", ObjectMap.class, ObjectMap::new);
|
bannedIPs = Core.settings.getJson("ip-bans", Seq.class, Seq::new);
|
||||||
bannedIPs = Core.settings.getJson("ip-bans", Seq.class, Seq::new);
|
whitelist = Core.settings.getJson("whitelist-ids", Seq.class, Seq::new);
|
||||||
whitelist = Core.settings.getJson("whitelist-ids", Seq.class, Seq::new);
|
subnetBans = Core.settings.getJson("banned-subnets", Seq.class, Seq::new);
|
||||||
subnetBans = Core.settings.getJson("banned-subnets", Seq.class, Seq::new);
|
|
||||||
}else{
|
|
||||||
//save over loaded legacy data
|
|
||||||
save();
|
|
||||||
Log.info("Loaded legacy (5.0) server data.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean loadLegacy(){
|
|
||||||
try{
|
|
||||||
byte[] info = Core.settings.getBytes("player-info");
|
|
||||||
byte[] ips = Core.settings.getBytes("banned-ips");
|
|
||||||
byte[] whitelist = Core.settings.getBytes("whitelisted");
|
|
||||||
byte[] subnet = Core.settings.getBytes("subnet-bans");
|
|
||||||
|
|
||||||
if(info != null){
|
|
||||||
DataInputStream d = new DataInputStream(new ByteArrayInputStream(info));
|
|
||||||
int size = d.readInt();
|
|
||||||
if(size != 0){
|
|
||||||
d.readUTF();
|
|
||||||
d.readUTF();
|
|
||||||
|
|
||||||
for(int i = 0; i < size; i++){
|
|
||||||
String mapKey = d.readUTF();
|
|
||||||
|
|
||||||
PlayerInfo data = new PlayerInfo();
|
|
||||||
|
|
||||||
data.id = d.readUTF();
|
|
||||||
data.lastName = d.readUTF();
|
|
||||||
data.lastIP = d.readUTF();
|
|
||||||
int ipsize = d.readInt();
|
|
||||||
if(ipsize != 0){
|
|
||||||
d.readUTF();
|
|
||||||
for(int j = 0; j < ipsize; j++){
|
|
||||||
data.ips.add(d.readUTF());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int namesize = d.readInt();
|
|
||||||
if(namesize != 0){
|
|
||||||
d.readUTF();
|
|
||||||
for(int j = 0; j < ipsize; j++){
|
|
||||||
data.names.add(d.readUTF());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//ips, names...
|
|
||||||
data.adminUsid = d.readUTF();
|
|
||||||
data.timesKicked = d.readInt();
|
|
||||||
data.timesJoined = d.readInt();
|
|
||||||
data.banned = d.readBoolean();
|
|
||||||
data.admin = d.readBoolean();
|
|
||||||
data.lastKicked = d.readLong();
|
|
||||||
|
|
||||||
playerInfo.put(mapKey, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Core.settings.remove("player-info");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ips != null){
|
|
||||||
DataInputStream d = new DataInputStream(new ByteArrayInputStream(ips));
|
|
||||||
int size = d.readInt();
|
|
||||||
if(size != 0){
|
|
||||||
d.readUTF();
|
|
||||||
for(int i = 0; i < size; i++){
|
|
||||||
bannedIPs.add(d.readUTF());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Core.settings.remove("banned-ips");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(whitelist != null){
|
|
||||||
DataInputStream d = new DataInputStream(new ByteArrayInputStream(whitelist));
|
|
||||||
int size = d.readInt();
|
|
||||||
if(size != 0){
|
|
||||||
d.readUTF();
|
|
||||||
for(int i = 0; i < size; i++){
|
|
||||||
this.whitelist.add(d.readUTF());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Core.settings.remove("whitelisted");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(subnet != null){
|
|
||||||
DataInputStream d = new DataInputStream(new ByteArrayInputStream(subnet));
|
|
||||||
int size = d.readInt();
|
|
||||||
if(size != 0){
|
|
||||||
d.readUTF();
|
|
||||||
for(int i = 0; i < size; i++){
|
|
||||||
subnetBans.add(d.readUTF());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Core.settings.remove("subnet-bans");
|
|
||||||
}
|
|
||||||
|
|
||||||
return info != null || ips != null || whitelist != null || subnet != null;
|
|
||||||
}catch(Throwable t){
|
|
||||||
Log.err(t);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Server configuration definition. Each config value can be a string, boolean or number. */
|
/** Server configuration definition. Each config value can be a string, boolean or number. */
|
||||||
@@ -584,8 +482,7 @@ public class Administration{
|
|||||||
autosaveAmount("The maximum amount of autosaves. Older ones get replaced.", 10),
|
autosaveAmount("The maximum amount of autosaves. Older ones get replaced.", 10),
|
||||||
autosaveSpacing("Spacing between autosaves in seconds.", 60 * 5),
|
autosaveSpacing("Spacing between autosaves in seconds.", 60 * 5),
|
||||||
debug("Enable debug logging", false, () -> {
|
debug("Enable debug logging", false, () -> {
|
||||||
LogLevel level = debug() ? LogLevel.debug : LogLevel.info;
|
Log.level = debug() ? LogLevel.debug : LogLevel.info;
|
||||||
Log.level = level;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
public static final Config[] all = values();
|
public static final Config[] all = values();
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package mindustry.net;
|
||||||
|
|
||||||
|
public class ServerGroup{
|
||||||
|
public String[] addresses;
|
||||||
|
public String name;
|
||||||
|
}
|
||||||
@@ -55,6 +55,12 @@ public class ItemSeq implements Iterable<ItemStack>, Serializable{
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void min(int number){
|
||||||
|
for(Item item : Vars.content.items()){
|
||||||
|
set(item, Math.min(get(item), number));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean has(Item item){
|
public boolean has(Item item){
|
||||||
return values[item.id] > 0;
|
return values[item.id] > 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ public class UnitType extends UnlockableContent{
|
|||||||
public AmmoType ammoType = AmmoTypes.copper;
|
public AmmoType ammoType = AmmoTypes.copper;
|
||||||
public int mineTier = -1;
|
public int mineTier = -1;
|
||||||
public float buildSpeed = 1f, mineSpeed = 1f;
|
public float buildSpeed = 1f, mineSpeed = 1f;
|
||||||
|
public Sound mineSound = Sounds.minebeam;
|
||||||
|
public float mineSoundVolume = 0.6f;
|
||||||
|
|
||||||
/** This is a VERY ROUGH estimate of unit DPS. */
|
/** This is a VERY ROUGH estimate of unit DPS. */
|
||||||
public float dpsEstimate = -1;
|
public float dpsEstimate = -1;
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ public class Weapon{
|
|||||||
public float shootCone = 5f;
|
public float shootCone = 5f;
|
||||||
/** ticks to cool down the heat region */
|
/** ticks to cool down the heat region */
|
||||||
public float cooldownTime = 20f;
|
public float cooldownTime = 20f;
|
||||||
|
/** random sound pitch range */
|
||||||
|
public float soundPitchMin = 0.8f, soundPitchMax = 1f;
|
||||||
/** whether shooter rotation is ignored when shooting. */
|
/** whether shooter rotation is ignored when shooting. */
|
||||||
public boolean ignoreRotation = false;
|
public boolean ignoreRotation = false;
|
||||||
/** min velocity required for this weapon to shoot */
|
/** min velocity required for this weapon to shoot */
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package mindustry.type;
|
package mindustry.type;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
|
import arc.audio.*;
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
|
import arc.util.noise.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
@@ -22,6 +24,9 @@ public abstract class Weather extends UnlockableContent{
|
|||||||
public float duration = 9f * Time.toMinutes;
|
public float duration = 9f * Time.toMinutes;
|
||||||
public float opacityMultiplier = 1f;
|
public float opacityMultiplier = 1f;
|
||||||
public Attributes attrs = new Attributes();
|
public Attributes attrs = new Attributes();
|
||||||
|
public Sound sound = Sounds.none;
|
||||||
|
public float soundVol = 0.1f, soundVolMin = 0f;
|
||||||
|
public float soundVolOscMag = 0f, soundVolOscScl = 20f;
|
||||||
|
|
||||||
//internals
|
//internals
|
||||||
public Rand rand = new Rand();
|
public Rand rand = new Rand();
|
||||||
@@ -83,6 +88,11 @@ public abstract class Weather extends UnlockableContent{
|
|||||||
state.effectTimer -= Time.delta;
|
state.effectTimer -= Time.delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(sound != Sounds.none){
|
||||||
|
float noise = soundVolOscMag > 0 ? (float)Math.abs(Noise.rawNoise(Time.time() / soundVolOscScl)) * soundVolOscMag : 0;
|
||||||
|
loops.play(sound, Core.camera.position, Math.max((soundVol + noise) * state.opacity, soundVolMin));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawOver(WeatherState state){
|
public void drawOver(WeatherState state){
|
||||||
|
|||||||
@@ -42,6 +42,13 @@ public class LaunchLoadoutDialog extends BaseDialog{
|
|||||||
|
|
||||||
//updates sum requirements
|
//updates sum requirements
|
||||||
Runnable update = () -> {
|
Runnable update = () -> {
|
||||||
|
int cap = selected.findCore().itemCapacity;
|
||||||
|
|
||||||
|
//cap resources based on core type
|
||||||
|
ItemSeq resources = universe.getLaunchResources();
|
||||||
|
resources.min(cap);
|
||||||
|
universe.updateLaunchResources(resources);
|
||||||
|
|
||||||
total.clear();
|
total.clear();
|
||||||
selected.requirements().each(total::add);
|
selected.requirements().each(total::add);
|
||||||
universe.getLaunchResources().each(total::add);
|
universe.getLaunchResources().each(total::add);
|
||||||
@@ -79,7 +86,7 @@ public class LaunchLoadoutDialog extends BaseDialog{
|
|||||||
ItemSeq stacks = universe.getLaunchResources();
|
ItemSeq stacks = universe.getLaunchResources();
|
||||||
Seq<ItemStack> out = stacks.toSeq();
|
Seq<ItemStack> out = stacks.toSeq();
|
||||||
|
|
||||||
loadout.show(core.itemCapacity, out, UnlockableContent::unlocked, out::clear, () -> {}, () -> {
|
loadout.show(selected.findCore().itemCapacity, out, UnlockableContent::unlocked, out::clear, () -> {}, () -> {
|
||||||
universe.updateLaunchResources(new ItemSeq(out));
|
universe.updateLaunchResources(new ItemSeq(out));
|
||||||
update.run();
|
update.run();
|
||||||
rebuildItems.run();
|
rebuildItems.run();
|
||||||
|
|||||||
@@ -174,14 +174,14 @@ public class Block extends UnlockableContent{
|
|||||||
public float lightRadius = 60f;
|
public float lightRadius = 60f;
|
||||||
|
|
||||||
/** The sound that this block makes while active. One sound loop. Do not overuse.*/
|
/** The sound that this block makes while active. One sound loop. Do not overuse.*/
|
||||||
public Sound activeSound = Sounds.none;
|
public Sound loopSound = Sounds.none;
|
||||||
/** Active sound base volume. */
|
/** Active sound base volume. */
|
||||||
public float activeSoundVolume = 0.5f;
|
public float loopSoundVolume = 0.5f;
|
||||||
|
|
||||||
/** The sound that this block makes while idle. Uses one sound loop for all blocks.*/
|
/** The sound that this block makes while idle. Uses one sound loop for all blocks.*/
|
||||||
public Sound idleSound = Sounds.none;
|
public Sound ambientSound = Sounds.none;
|
||||||
/** Idle sound base volume. */
|
/** Idle sound base volume. */
|
||||||
public float idleSoundVolume = 0.5f;
|
public float ambientSoundVolume = 0.05f;
|
||||||
|
|
||||||
/** Cost of constructing this block. */
|
/** Cost of constructing this block. */
|
||||||
public ItemStack[] requirements = {};
|
public ItemStack[] requirements = {};
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ public class ForceProjector extends Block{
|
|||||||
hasPower = true;
|
hasPower = true;
|
||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
|
ambientSound = Sounds.shield;
|
||||||
|
ambientSoundVolume = 0.08f;
|
||||||
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.1f)).boost().update(false);
|
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.1f)).boost().update(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,6 +109,11 @@ public class ForceProjector extends Block{
|
|||||||
drawer.add();
|
drawer.add();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldAmbientSound(){
|
||||||
|
return !broken && realRadius() > 1f;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRemoved(){
|
public void onRemoved(){
|
||||||
super.onRemoved();
|
super.onRemoved();
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public class LiquidTurret extends Turret{
|
|||||||
super(name);
|
super(name);
|
||||||
acceptCoolant = false;
|
acceptCoolant = false;
|
||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
activeSound = Sounds.spray;
|
loopSound = Sounds.spray;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initializes accepted ammo map. Format: [liquid1, bullet1, liquid2, bullet2...] */
|
/** Initializes accepted ammo map. Format: [liquid1, bullet1, liquid2, bullet2...] */
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.world.blocks.defense.turrets;
|
package mindustry.world.blocks.defense.turrets;
|
||||||
|
|
||||||
|
import arc.audio.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
@@ -24,6 +25,8 @@ public class PointDefenseTurret extends ReloadTurret{
|
|||||||
public Effect hitEffect = Fx.pointHit;
|
public Effect hitEffect = Fx.pointHit;
|
||||||
public Effect shootEffect = Fx.sparkShoot;
|
public Effect shootEffect = Fx.sparkShoot;
|
||||||
|
|
||||||
|
public Sound shootSound = Sounds.lasershoot;
|
||||||
|
|
||||||
public float shootCone = 5f;
|
public float shootCone = 5f;
|
||||||
public float bulletDamage = 10f;
|
public float bulletDamage = 10f;
|
||||||
public float shootLength = 3f;
|
public float shootLength = 3f;
|
||||||
@@ -90,6 +93,7 @@ public class PointDefenseTurret extends ReloadTurret{
|
|||||||
beamEffect.at(x + Tmp.v1.x, y + Tmp.v1.y, rotation, color, new Vec2().set(target));
|
beamEffect.at(x + Tmp.v1.x, y + Tmp.v1.y, rotation, color, new Vec2().set(target));
|
||||||
shootEffect.at(x + Tmp.v1.x, y + Tmp.v1.y, rotation, color);
|
shootEffect.at(x + Tmp.v1.x, y + Tmp.v1.y, rotation, color);
|
||||||
hitEffect.at(target.x, target.y, color);
|
hitEffect.at(target.x, target.y, color);
|
||||||
|
shootSound.at(x + Tmp.v1.x, y + Tmp.v1.y, Mathf.random(0.9f, 1.1f));
|
||||||
reload = 0;
|
reload = 0;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.world.blocks.defense.turrets;
|
package mindustry.world.blocks.defense.turrets;
|
||||||
|
|
||||||
|
import arc.audio.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
@@ -34,6 +35,9 @@ public class TractorBeamTurret extends BaseTurret{
|
|||||||
public StatusEffect status = StatusEffects.none;
|
public StatusEffect status = StatusEffects.none;
|
||||||
public float statusDuration = 300;
|
public float statusDuration = 300;
|
||||||
|
|
||||||
|
public Sound shootSound = Sounds.tractorbeam;
|
||||||
|
public float shootSoundVolume = 0.9f;
|
||||||
|
|
||||||
public TractorBeamTurret(String name){
|
public TractorBeamTurret(String name){
|
||||||
super(name);
|
super(name);
|
||||||
|
|
||||||
@@ -91,6 +95,8 @@ public class TractorBeamTurret extends BaseTurret{
|
|||||||
|
|
||||||
//look at target
|
//look at target
|
||||||
if(target != null && target.within(this, range) && target.team() != team && target.type.flying && efficiency() > 0.01f){
|
if(target != null && target.within(this, range) && target.team() != team && target.type.flying && efficiency() > 0.01f){
|
||||||
|
loops.play(shootSound, this, shootSoundVolume);
|
||||||
|
|
||||||
any = true;
|
any = true;
|
||||||
float dest = angleTo(target);
|
float dest = angleTo(target);
|
||||||
rotation = Angles.moveToward(rotation, dest, rotateSpeed * edelta());
|
rotation = Angles.moveToward(rotation, dest, rotateSpeed * edelta());
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public abstract class Turret extends ReloadTurret{
|
|||||||
public float recoilAmount = 1f;
|
public float recoilAmount = 1f;
|
||||||
public float restitution = 0.02f;
|
public float restitution = 0.02f;
|
||||||
public float cooldown = 0.02f;
|
public float cooldown = 0.02f;
|
||||||
|
public float coolantUsage = 0.2f;
|
||||||
public float shootCone = 8f;
|
public float shootCone = 8f;
|
||||||
public float shootShake = 0f;
|
public float shootShake = 0f;
|
||||||
public float xRand = 0f;
|
public float xRand = 0f;
|
||||||
@@ -109,7 +110,7 @@ public abstract class Turret extends ReloadTurret{
|
|||||||
public void init(){
|
public void init(){
|
||||||
if(acceptCoolant && !consumes.has(ConsumeType.liquid)){
|
if(acceptCoolant && !consumes.has(ConsumeType.liquid)){
|
||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.2f)).update(false).boost();
|
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, coolantUsage)).update(false).boost();
|
||||||
}
|
}
|
||||||
|
|
||||||
super.init();
|
super.init();
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
itemCapacity = 4;
|
itemCapacity = 4;
|
||||||
conveyorPlacement = true;
|
conveyorPlacement = true;
|
||||||
|
|
||||||
idleSound = Sounds.conveyor;
|
ambientSound = Sounds.conveyor;
|
||||||
idleSoundVolume = 0.004f;
|
ambientSoundVolume = 0.0015f;
|
||||||
unloadable = false;
|
unloadable = false;
|
||||||
noUpdateDisabled = false;
|
noUpdateDisabled = false;
|
||||||
}
|
}
|
||||||
@@ -161,7 +161,7 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldIdleSound(){
|
public boolean shouldAmbientSound(){
|
||||||
return clogHeat <= 0.5f;
|
return clogHeat <= 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ public class StackConveyor extends Block implements Autotiler{
|
|||||||
itemCapacity = 10;
|
itemCapacity = 10;
|
||||||
conveyorPlacement = true;
|
conveyorPlacement = true;
|
||||||
|
|
||||||
idleSound = Sounds.conveyor;
|
ambientSound = Sounds.conveyor;
|
||||||
idleSoundVolume = 0.004f;
|
ambientSoundVolume = 0.004f;
|
||||||
unloadable = false;
|
unloadable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +231,7 @@ public class StackConveyor extends Block implements Autotiler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldIdleSound(){
|
public boolean shouldAmbientSound(){
|
||||||
return false; // has no moving parts;
|
return false; // has no moving parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.world.blocks.environment;
|
package mindustry.world.blocks.environment;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
|
import arc.audio.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.graphics.g2d.TextureAtlas.*;
|
import arc.graphics.g2d.TextureAtlas.*;
|
||||||
@@ -10,6 +11,7 @@ import arc.struct.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.graphics.MultiPacker.*;
|
import mindustry.graphics.MultiPacker.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
@@ -33,7 +35,11 @@ public class Floor extends Block{
|
|||||||
/** How many ticks it takes to drown on this. */
|
/** How many ticks it takes to drown on this. */
|
||||||
public float drownTime = 0f;
|
public float drownTime = 0f;
|
||||||
/** Effect when walking on this floor. */
|
/** Effect when walking on this floor. */
|
||||||
public Effect walkEffect = Fx.ripple;
|
public Effect walkEffect = Fx.none;
|
||||||
|
/** Sound made when walking. */
|
||||||
|
public Sound walkSound = Sounds.none;
|
||||||
|
/** Volume of sound made when walking. */
|
||||||
|
public float walkSoundVolume = 0.1f, walkSoundPitchMin = 0.8f, walkSoundPitchMax = 1.2f;
|
||||||
/** Effect displayed when drowning on this floor. */
|
/** Effect displayed when drowning on this floor. */
|
||||||
public Effect drownUpdateEffect = Fx.bubble;
|
public Effect drownUpdateEffect = Fx.bubble;
|
||||||
/** Status effect applied when walking on. */
|
/** Status effect applied when walking on. */
|
||||||
@@ -115,6 +121,14 @@ public class Floor extends Block{
|
|||||||
if(decoration == Blocks.air){
|
if(decoration == Blocks.air){
|
||||||
decoration = content.blocks().min(b -> b instanceof Boulder && b.breakable ? mapColor.diff(b.mapColor) : Float.POSITIVE_INFINITY);
|
decoration = content.blocks().min(b -> b instanceof Boulder && b.breakable ? mapColor.diff(b.mapColor) : Float.POSITIVE_INFINITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isLiquid && walkEffect == Fx.none){
|
||||||
|
walkEffect = Fx.ripple;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isLiquid && walkSound == Sounds.none){
|
||||||
|
walkSound = Sounds.splash;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -91,6 +91,11 @@ public class ImpactReactor extends PowerGenerator{
|
|||||||
productionEfficiency = Mathf.pow(warmup, 5f);
|
productionEfficiency = Mathf.pow(warmup, 5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float ambientVolume(){
|
||||||
|
return warmup;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
Draw.rect(bottomRegion, x, y);
|
Draw.rect(bottomRegion, x, y);
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ public class Drill extends Block{
|
|||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
liquidCapacity = 5f;
|
liquidCapacity = 5f;
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
idleSound = Sounds.drill;
|
ambientSound = Sounds.drill;
|
||||||
idleSoundVolume = 0.003f;
|
ambientSoundVolume = 0.016f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -205,8 +205,8 @@ public class Drill extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldIdleSound(){
|
public boolean shouldAmbientSound(){
|
||||||
return efficiency() > 0.01f;
|
return efficiency() > 0.01f && items.total() < itemCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user