mirror of
https://github.com/Anuken/Mindustry.git
synced 2026-01-26 22:42:41 -08:00
Merge branch 'master' into cleanup-2
This commit is contained in:
commit
f84e780f3b
106 changed files with 328 additions and 249 deletions
|
|
@ -1,7 +1,7 @@
|
|||

|
||||
|
||||
[](https://travis-ci.org/Anuken/Mindustry)
|
||||
[](https://discord.gg/mindustry)
|
||||
[](https://discord.gg/mindustry)
|
||||
|
||||
A sandbox tower defense game written in Java.
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@ public class Annotations{
|
|||
boolean serialize() default true;
|
||||
/** Whether to generate IO code. This is for advanced usage only. */
|
||||
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. */
|
||||
|
|
|
|||
|
|
@ -240,7 +240,6 @@ public class EntityProcess extends BaseProcessor{
|
|||
//look at each definition
|
||||
for(Selement<?> type : allDefs){
|
||||
EntityDef ann = type.annotation(EntityDef.class);
|
||||
boolean isFinal = ann.isFinal();
|
||||
|
||||
//all component classes (not interfaces)
|
||||
Seq<Stype> components = allComponents(type);
|
||||
|
|
@ -274,6 +273,10 @@ public class EntityProcess extends BaseProcessor{
|
|||
name += "Entity";
|
||||
}
|
||||
|
||||
if(ann.legacy()){
|
||||
name += "Legacy" + Strings.capitalize(type.name());
|
||||
}
|
||||
|
||||
//skip double classes
|
||||
if(usedNames.containsKey(name)){
|
||||
extraNames.get(usedNames.get(name), ObjectSet::new).add(type.name());
|
||||
|
|
|
|||
1
annotations/src/main/resources/revisions/block/3.json
Normal file
1
annotations/src/main/resources/revisions/block/3.json
Normal file
|
|
@ -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}]}
|
||||
1
annotations/src/main/resources/revisions/corvus/3.json
Normal file
1
annotations/src/main/resources/revisions/corvus/3.json
Normal file
|
|
@ -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}]}
|
||||
1
annotations/src/main/resources/revisions/flare/3.json
Normal file
1
annotations/src/main/resources/revisions/flare/3.json
Normal file
|
|
@ -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}]}
|
||||
1
annotations/src/main/resources/revisions/mace/3.json
Normal file
1
annotations/src/main/resources/revisions/mace/3.json
Normal file
|
|
@ -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}]}
|
||||
1
annotations/src/main/resources/revisions/oct/2.json
Normal file
1
annotations/src/main/resources/revisions/oct/2.json
Normal file
|
|
@ -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}]}
|
||||
1
annotations/src/main/resources/revisions/quad/3.json
Normal file
1
annotations/src/main/resources/revisions/quad/3.json
Normal file
|
|
@ -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}]}
|
||||
1
annotations/src/main/resources/revisions/risso/3.json
Normal file
1
annotations/src/main/resources/revisions/risso/3.json
Normal file
|
|
@ -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}]}
|
||||
1
annotations/src/main/resources/revisions/spiroct/3.json
Normal file
1
annotations/src/main/resources/revisions/spiroct/3.json
Normal file
|
|
@ -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
|
||||
LeoDog896
|
||||
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.
BIN
core/assets/sounds/combustion.ogg
Normal file
BIN
core/assets/sounds/combustion.ogg
Normal file
Binary file not shown.
Binary file not shown.
BIN
core/assets/sounds/cutter.ogg
Normal file
BIN
core/assets/sounds/cutter.ogg
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
core/assets/sounds/grinding.ogg
Normal file
BIN
core/assets/sounds/grinding.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/hum.ogg
Normal file
BIN
core/assets/sounds/hum.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/laserblast.ogg
Normal file
BIN
core/assets/sounds/laserblast.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/lasercharge.ogg
Normal file
BIN
core/assets/sounds/lasercharge.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/lasercharge2.ogg
Normal file
BIN
core/assets/sounds/lasercharge2.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/lasershoot.ogg
Normal file
BIN
core/assets/sounds/lasershoot.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/minebeam.ogg
Normal file
BIN
core/assets/sounds/minebeam.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/mud.ogg
Normal file
BIN
core/assets/sounds/mud.ogg
Normal file
Binary file not shown.
Binary file not shown.
BIN
core/assets/sounds/pew_.ogg
Normal file
BIN
core/assets/sounds/pew_.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/pulse.ogg
Normal file
BIN
core/assets/sounds/pulse.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/railgun.ogg
Normal file
BIN
core/assets/sounds/railgun.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/rain.ogg
Normal file
BIN
core/assets/sounds/rain.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/sap.ogg
Normal file
BIN
core/assets/sounds/sap.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/shield.ogg
Normal file
BIN
core/assets/sounds/shield.ogg
Normal file
Binary file not shown.
Binary file not shown.
BIN
core/assets/sounds/smelter.ogg
Normal file
BIN
core/assets/sounds/smelter.ogg
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
core/assets/sounds/steam.ogg
Normal file
BIN
core/assets/sounds/steam.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/swish.ogg
Normal file
BIN
core/assets/sounds/swish.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/techloop.ogg
Normal file
BIN
core/assets/sounds/techloop.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/tractorbeam.ogg
Normal file
BIN
core/assets/sounds/tractorbeam.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/wind.ogg
Normal file
BIN
core/assets/sounds/wind.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/wind2.ogg
Normal file
BIN
core/assets/sounds/wind2.ogg
Normal file
Binary file not shown.
BIN
core/assets/sounds/windhowl.ogg
Normal file
BIN
core/assets/sounds/windhowl.ogg
Normal file
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);
|
||||
|
||||
//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;
|
||||
found = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public class FlyingAI extends AIController{
|
|||
vec.setAngle(Mathf.slerpDelta(unit.vel().angle(), vec.angle(), 0.6f));
|
||||
}
|
||||
|
||||
vec.setLength(unit.type.speed);
|
||||
vec.setLength(unit.speed());
|
||||
|
||||
unit.moveAt(vec);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,17 +2,13 @@ package mindustry.ai.types;
|
|||
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.ai.formations.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.storage.CoreBlock.*;
|
||||
|
||||
public class FormationAI extends AIController implements FormationMember{
|
||||
private static Seq<Tile> tiles = new Seq<>();
|
||||
public Unit leader;
|
||||
|
||||
private Vec3 target = new Vec3();
|
||||
|
|
@ -30,9 +26,8 @@ public class FormationAI extends AIController implements FormationMember{
|
|||
|
||||
@Override
|
||||
public void updateUnit(){
|
||||
UnitType type = unit.type;
|
||||
|
||||
if(leader.dead){
|
||||
if(leader == null || leader.dead){
|
||||
unit.resetController();
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,9 +104,7 @@ public class LogicAI extends AIController{
|
|||
|
||||
//look where moving if there's nothing to aim at
|
||||
if(!shoot){
|
||||
if(unit.moving()){
|
||||
unit.lookAt(unit.vel().angle());
|
||||
}
|
||||
unit.lookAt(unit.prefRotation());
|
||||
}else if(unit.hasWeapons()){ //if there is, look at the object
|
||||
unit.lookAt(unit.mounts[0].aimX, unit.mounts[0].aimY);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ public class SuicideAI extends GroundAI{
|
|||
if(!blocked){
|
||||
moveToTarget = true;
|
||||
//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;
|
||||
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){
|
||||
data.soundID = sound.loop(data.curVolume, 1f, pan);
|
||||
}
|
||||
}else{
|
||||
if(data.curVolume <= 0.01f){
|
||||
if(data.curVolume <= 0.001f){
|
||||
sound.stop();
|
||||
data.soundID = -1;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package mindustry.audio;
|
|||
|
||||
import arc.*;
|
||||
import arc.audio.*;
|
||||
import arc.audio.SoloudAudio.*;
|
||||
import arc.math.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
|
|
@ -25,6 +26,11 @@ public class MusicControl{
|
|||
protected float fade;
|
||||
protected boolean silenced;
|
||||
|
||||
protected boolean wasPaused;
|
||||
protected AudioFilter filter = new BiquadFilter(){{
|
||||
set(0, 500, 1);
|
||||
}};
|
||||
|
||||
public MusicControl(){
|
||||
Events.on(ClientLoadEvent.class, e -> reload());
|
||||
|
||||
|
|
@ -54,6 +60,13 @@ public class MusicControl{
|
|||
|
||||
/** Update and play the right music track.*/
|
||||
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()){
|
||||
silenced = false;
|
||||
if(ui.planet.isShown()){
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public class SoundLoop{
|
|||
}
|
||||
|
||||
public void update(float x, float y, boolean play){
|
||||
if(baseVolume < 0) return;
|
||||
if(baseVolume <= 0) return;
|
||||
|
||||
if(id < 0){
|
||||
if(play){
|
||||
|
|
@ -36,6 +36,7 @@ public class SoundLoop{
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
cacheLayer = CacheLayer.mud;
|
||||
albedo = 0.35f;
|
||||
walkSound = Sounds.mud;
|
||||
walkSoundVolume = 0.08f;
|
||||
walkSoundPitchMin = 0.4f;
|
||||
walkSoundPitchMax = 0.5f;
|
||||
}};
|
||||
|
||||
((ShallowLiquid)darksandTaintedWater).set(Blocks.taintedWater, Blocks.darksand);
|
||||
|
|
@ -592,6 +596,9 @@ public class Blocks implements ContentList{
|
|||
hasPower = true;
|
||||
drawer = new DrawWeave();
|
||||
|
||||
ambientSound = Sounds.techloop;
|
||||
ambientSoundVolume = 0.02f;
|
||||
|
||||
consumes.items(with(Items.thorium, 4, Items.sand, 10));
|
||||
consumes.power(5f);
|
||||
itemCapacity = 20;
|
||||
|
|
@ -720,6 +727,8 @@ public class Blocks implements ContentList{
|
|||
updateEffect = Fx.pulverizeSmall;
|
||||
hasItems = hasPower = true;
|
||||
drawer = new DrawRotator();
|
||||
ambientSound = Sounds.grinding;
|
||||
ambientSoundVolume = 0.02f;
|
||||
|
||||
consumes.item(Items.scrap, 1);
|
||||
consumes.power(0.50f);
|
||||
|
|
@ -1158,6 +1167,9 @@ public class Blocks implements ContentList{
|
|||
requirements(Category.power, with(Items.copper, 25, Items.lead, 15));
|
||||
powerProduction = 1f;
|
||||
itemDuration = 120f;
|
||||
|
||||
ambientSound = Sounds.smelter;
|
||||
ambientSoundVolume = 0.03f;
|
||||
}};
|
||||
|
||||
thermalGenerator = new ThermalGenerator("thermal-generator"){{
|
||||
|
|
@ -1166,6 +1178,8 @@ public class Blocks implements ContentList{
|
|||
generateEffect = Fx.redgeneratespark;
|
||||
size = 2;
|
||||
floating = true;
|
||||
ambientSound = Sounds.hum;
|
||||
ambientSoundVolume = 0.04f;
|
||||
}};
|
||||
|
||||
steamGenerator = new BurnerGenerator("steam-generator"){{
|
||||
|
|
@ -1175,6 +1189,9 @@ public class Blocks implements ContentList{
|
|||
consumes.liquid(Liquids.water, 0.1f);
|
||||
hasLiquids = true;
|
||||
size = 2;
|
||||
|
||||
ambientSound = Sounds.smelter;
|
||||
ambientSoundVolume = 0.05f;
|
||||
}};
|
||||
|
||||
differentialGenerator = new SingleTypeGenerator("differential-generator"){{
|
||||
|
|
@ -1184,6 +1201,8 @@ public class Blocks implements ContentList{
|
|||
hasLiquids = true;
|
||||
hasItems = true;
|
||||
size = 3;
|
||||
ambientSound = Sounds.steam;
|
||||
ambientSoundVolume = 0.03f;
|
||||
|
||||
consumes.item(Items.pyratite).optional(true, false);
|
||||
consumes.liquid(Liquids.cryofluid, 0.1f);
|
||||
|
|
@ -1209,6 +1228,8 @@ public class Blocks implements ContentList{
|
|||
|
||||
thoriumReactor = new NuclearReactor("thorium-reactor"){{
|
||||
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;
|
||||
health = 700;
|
||||
itemDuration = 360f;
|
||||
|
|
@ -1224,6 +1245,9 @@ public class Blocks implements ContentList{
|
|||
health = 900;
|
||||
powerProduction = 130f;
|
||||
itemDuration = 140f;
|
||||
ambientSound = Sounds.pulse;
|
||||
ambientSoundVolume = 0.2f;
|
||||
|
||||
consumes.power(25f);
|
||||
consumes.item(Items.blastCompound);
|
||||
consumes.liquid(Liquids.cryofluid, 0.25f);
|
||||
|
|
@ -1464,7 +1488,7 @@ public class Blocks implements ContentList{
|
|||
inaccuracy = 1f;
|
||||
shootCone = 10f;
|
||||
health = 260;
|
||||
shootSound = Sounds.artillery;
|
||||
shootSound = Sounds.bang;
|
||||
}};
|
||||
|
||||
wave = new LiquidTurret("wave"){{
|
||||
|
|
@ -1484,7 +1508,6 @@ public class Blocks implements ContentList{
|
|||
shootEffect = Fx.shootLiquid;
|
||||
range = 110f;
|
||||
health = 250 * size * size;
|
||||
shootSound = Sounds.splash;
|
||||
}};
|
||||
|
||||
lancer = new ChargeTurret("lancer"){{
|
||||
|
|
@ -1632,7 +1655,6 @@ public class Blocks implements ContentList{
|
|||
shootEffect = Fx.shootLiquid;
|
||||
range = 190f;
|
||||
health = 250 * size * size;
|
||||
shootSound = Sounds.splash;
|
||||
}};
|
||||
|
||||
fuse = new ItemTurret("fuse"){{
|
||||
|
|
@ -1752,13 +1774,13 @@ public class Blocks implements ContentList{
|
|||
shots = 1;
|
||||
size = 4;
|
||||
shootCone = 2f;
|
||||
shootSound = Sounds.shootBig;
|
||||
shootSound = Sounds.railgun;
|
||||
unitSort = (u, x, y) -> -u.maxHealth;
|
||||
|
||||
coolantMultiplier = 0.09f;
|
||||
coolantMultiplier = 0.11f;
|
||||
|
||||
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);
|
||||
}};
|
||||
|
|
@ -1786,7 +1808,7 @@ public class Blocks implements ContentList{
|
|||
shootSound = Sounds.shootBig;
|
||||
|
||||
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"){{
|
||||
|
|
@ -1802,8 +1824,8 @@ public class Blocks implements ContentList{
|
|||
shootDuration = 220f;
|
||||
powerUse = 17f;
|
||||
shootSound = Sounds.laserbig;
|
||||
activeSound = Sounds.beam;
|
||||
activeSoundVolume = 2f;
|
||||
loopSound = Sounds.beam;
|
||||
loopSoundVolume = 2f;
|
||||
|
||||
shootType = new ContinuousLaserBulletType(70){{
|
||||
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;
|
||||
|
||||
//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
|
||||
public static @EntityDef({Unitc.class, Mechc.class}) UnitType vela;
|
||||
|
|
@ -35,23 +35,23 @@ public class UnitTypes implements ContentList{
|
|||
//air (no special traits)
|
||||
public static @EntityDef({Unitc.class}) UnitType flare, eclipse, horizon, zenith, antumbra;
|
||||
|
||||
//air + mining
|
||||
public static @EntityDef({Unitc.class, Minerc.class}) UnitType mono;
|
||||
//air, legacy mining
|
||||
public static @EntityDef(value = {Unitc.class}, legacy = true) UnitType mono;
|
||||
|
||||
//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
|
||||
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
|
||||
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
|
||||
public static @EntityDef({Unitc.class, Builderc.class, Payloadc.class, AmmoDistributec.class}) UnitType oct;
|
||||
|
||||
//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
|
||||
public static @EntityDef({Unitc.class, WaterMovec.class}) UnitType risso, minke, bryde, sei, omura;
|
||||
|
|
@ -166,7 +166,7 @@ public class UnitTypes implements ContentList{
|
|||
recoil = 5f;
|
||||
shake = 2f;
|
||||
ejectEffect = Fx.casing3;
|
||||
shootSound = Sounds.artillery;
|
||||
shootSound = Sounds.bang;
|
||||
shots = 3;
|
||||
inaccuracy = 3f;
|
||||
shotDelay = 4f;
|
||||
|
|
@ -226,7 +226,7 @@ public class UnitTypes implements ContentList{
|
|||
recoil = 5f;
|
||||
shake = 2f;
|
||||
ejectEffect = Fx.casing4;
|
||||
shootSound = Sounds.artillery;
|
||||
shootSound = Sounds.bang;
|
||||
|
||||
bullet = new BasicBulletType(13f, 60){{
|
||||
pierce = true;
|
||||
|
|
@ -287,6 +287,8 @@ public class UnitTypes implements ContentList{
|
|||
alternate = false;
|
||||
ejectEffect = Fx.none;
|
||||
recoil = 2f;
|
||||
shootSound = Sounds.lasershoot;
|
||||
|
||||
bullet = new LaserBoltBulletType(5.2f, 14){{
|
||||
healPercent = 5f;
|
||||
collidesTeam = true;
|
||||
|
|
@ -328,7 +330,7 @@ public class UnitTypes implements ContentList{
|
|||
spacing = 0f;
|
||||
ejectEffect = Fx.none;
|
||||
recoil = 2.5f;
|
||||
shootSound = Sounds.pew;
|
||||
shootSound = Sounds.spark;
|
||||
|
||||
bullet = new LightningBulletType(){{
|
||||
lightningColor = hitColor = Pal.heal;
|
||||
|
|
@ -430,7 +432,8 @@ public class UnitTypes implements ContentList{
|
|||
|
||||
reload = 320f;
|
||||
recoil = 0f;
|
||||
shootSound = Sounds.laser;
|
||||
chargeSound = Sounds.lasercharge2;
|
||||
shootSound = Sounds.beam;
|
||||
continuous = true;
|
||||
cooldownTime = 200f;
|
||||
|
||||
|
|
@ -491,6 +494,9 @@ public class UnitTypes implements ContentList{
|
|||
drawShields = false;
|
||||
|
||||
weapons.add(new Weapon("corvus-weapon"){{
|
||||
shootSound = Sounds.laserblast;
|
||||
chargeSound = Sounds.lasercharge;
|
||||
soundPitchMin = 1f;
|
||||
top = false;
|
||||
mirror = false;
|
||||
shake = 14f;
|
||||
|
|
@ -498,7 +504,6 @@ public class UnitTypes implements ContentList{
|
|||
x = y = 0;
|
||||
reload = 350f;
|
||||
recoil = 0f;
|
||||
shootSound = Sounds.laser;
|
||||
|
||||
cooldownTime = 350f;
|
||||
|
||||
|
|
@ -634,7 +639,7 @@ public class UnitTypes implements ContentList{
|
|||
ejectEffect = Fx.none;
|
||||
recoil = 2f;
|
||||
rotate = true;
|
||||
shootSound = Sounds.flame;
|
||||
shootSound = Sounds.sap;
|
||||
|
||||
x = 8.5f;
|
||||
y = -1.5f;
|
||||
|
|
@ -657,6 +662,7 @@ public class UnitTypes implements ContentList{
|
|||
rotate = true;
|
||||
x = 4f;
|
||||
y = 3f;
|
||||
shootSound = Sounds.sap;
|
||||
|
||||
bullet = new SapBulletType(){{
|
||||
sapStrength = 0.8f;
|
||||
|
|
@ -721,6 +727,7 @@ public class UnitTypes implements ContentList{
|
|||
y = 8f;
|
||||
rotate = true;
|
||||
bullet = sapper;
|
||||
shootSound = Sounds.sap;
|
||||
}},
|
||||
new Weapon("spiroct-weapon"){{
|
||||
reload = 15f;
|
||||
|
|
@ -728,6 +735,7 @@ public class UnitTypes implements ContentList{
|
|||
y = 6f;
|
||||
rotate = true;
|
||||
bullet = sapper;
|
||||
shootSound = Sounds.sap;
|
||||
}},
|
||||
new Weapon("spiroct-weapon"){{
|
||||
reload = 23f;
|
||||
|
|
@ -735,6 +743,7 @@ public class UnitTypes implements ContentList{
|
|||
y = 0f;
|
||||
rotate = true;
|
||||
bullet = sapper;
|
||||
shootSound = Sounds.sap;
|
||||
}},
|
||||
new Weapon("large-purple-mount"){{
|
||||
y = -7f;
|
||||
|
|
@ -744,7 +753,7 @@ public class UnitTypes implements ContentList{
|
|||
shake = 3f;
|
||||
rotateSpeed = 2f;
|
||||
ejectEffect = Fx.casing1;
|
||||
shootSound = Sounds.shootBig;
|
||||
shootSound = Sounds.artillery;
|
||||
rotate = true;
|
||||
occlusion = 8f;
|
||||
recoil = 3f;
|
||||
|
|
@ -842,7 +851,7 @@ public class UnitTypes implements ContentList{
|
|||
recoil = 10f;
|
||||
rotateSpeed = 1f;
|
||||
ejectEffect = Fx.casing3;
|
||||
shootSound = Sounds.shootBig;
|
||||
shootSound = Sounds.artillery;
|
||||
rotate = true;
|
||||
occlusion = 30f;
|
||||
|
||||
|
|
@ -1205,7 +1214,7 @@ public class UnitTypes implements ContentList{
|
|||
reload = 30f;
|
||||
ejectEffect = Fx.none;
|
||||
recoil = 2f;
|
||||
shootSound = Sounds.pew;
|
||||
shootSound = Sounds.missile;
|
||||
shots = 1;
|
||||
velocityRnd = 0.5f;
|
||||
inaccuracy = 15f;
|
||||
|
|
@ -1221,6 +1230,7 @@ public class UnitTypes implements ContentList{
|
|||
smokeEffect = Fx.hitLaser;
|
||||
hitEffect = despawnEffect = Fx.hitLaser;
|
||||
frontColor = Color.white;
|
||||
hitSound = Sounds.none;
|
||||
|
||||
healPercent = 5.5f;
|
||||
collidesTeam = true;
|
||||
|
|
@ -1252,6 +1262,7 @@ public class UnitTypes implements ContentList{
|
|||
|
||||
weapons.add(
|
||||
new Weapon("heal-weapon-mount"){{
|
||||
shootSound = Sounds.lasershoot;
|
||||
reload = 25f;
|
||||
x = 8f;
|
||||
y = -6f;
|
||||
|
|
@ -1259,6 +1270,7 @@ public class UnitTypes implements ContentList{
|
|||
bullet = Bullets.healBulletBig;
|
||||
}},
|
||||
new Weapon("heal-weapon-mount"){{
|
||||
shootSound = Sounds.lasershoot;
|
||||
reload = 15f;
|
||||
x = 4f;
|
||||
y = 5f;
|
||||
|
|
@ -1578,7 +1590,7 @@ public class UnitTypes implements ContentList{
|
|||
inaccuracy = 7f;
|
||||
ejectEffect = Fx.none;
|
||||
shake = 3f;
|
||||
shootSound = Sounds.shootBig;
|
||||
shootSound = Sounds.missile;
|
||||
xRand = 8f;
|
||||
shotDelay = 1f;
|
||||
|
||||
|
|
@ -1659,6 +1671,7 @@ public class UnitTypes implements ContentList{
|
|||
shake = 6f;
|
||||
recoil = 10.5f;
|
||||
occlusion = 50f;
|
||||
shootSound = Sounds.railgun;
|
||||
|
||||
shots = 1;
|
||||
ejectEffect = Fx.none;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package mindustry.content;
|
|||
import arc.graphics.*;
|
||||
import arc.util.*;
|
||||
import mindustry.ctype.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.type.weather.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
|
@ -23,12 +24,20 @@ public class Weathers implements ContentList{
|
|||
sizeMin = 2.6f;
|
||||
density = 1200f;
|
||||
attrs.set(Attribute.light, -0.15f);
|
||||
|
||||
sound = Sounds.windhowl;
|
||||
soundVol = 0f;
|
||||
soundVolOscMag = 1.5f;
|
||||
soundVolOscScl = 1100f;
|
||||
soundVolMin = 0.02f;
|
||||
}};
|
||||
|
||||
rain = new RainWeather("rain"){{
|
||||
attrs.set(Attribute.light, -0.2f);
|
||||
attrs.set(Attribute.water, 0.2f);
|
||||
status = StatusEffects.wet;
|
||||
sound = Sounds.rain;
|
||||
soundVol = 0.25f;
|
||||
}};
|
||||
|
||||
sandstorm = new ParticleWeather("sandstorm"){{
|
||||
|
|
@ -46,6 +55,8 @@ public class Weathers implements ContentList{
|
|||
attrs.set(Attribute.water, -0.1f);
|
||||
opacityMultiplier = 0.8f;
|
||||
force = 0.1f;
|
||||
sound = Sounds.wind;
|
||||
soundVol = 0.3f;
|
||||
}};
|
||||
|
||||
sporestorm = new ParticleWeather("sporestorm"){{
|
||||
|
|
@ -65,6 +76,8 @@ public class Weathers implements ContentList{
|
|||
status = StatusEffects.sporeSlowed;
|
||||
opacityMultiplier = 0.85f;
|
||||
force = 0.1f;
|
||||
sound = Sounds.wind;
|
||||
soundVol = 0.3f;
|
||||
}};
|
||||
|
||||
fog = new ParticleWeather("fog"){{
|
||||
|
|
|
|||
|
|
@ -477,10 +477,6 @@ public class Control implements ApplicationListener, Loadable{
|
|||
dialog.show();
|
||||
}));
|
||||
}
|
||||
|
||||
if(android){
|
||||
Sounds.empty.loop(0f, 1f, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -640,7 +640,7 @@ public class NetServer implements ApplicationListener{
|
|||
Unit unit = player.unit();
|
||||
|
||||
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()){
|
||||
maxSpeed *= unit.floorSpeedMultiplier();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ public abstract class UnlockableContent extends MappableContent{
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ public abstract class BulletType extends Content{
|
|||
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);
|
||||
|
||||
if(status != StatusEffects.none){
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ abstract class BuilderComp implements Unitc{
|
|||
|
||||
@Import float x, y, rotation;
|
||||
|
||||
@SyncLocal Queue<BuildPlan> plans = new Queue<>();
|
||||
@SyncLocal Queue<BuildPlan> plans = new Queue<>(1);
|
||||
@SyncLocal transient boolean updateBuilding = true;
|
||||
|
||||
@Override
|
||||
|
|
@ -35,7 +35,6 @@ abstract class BuilderComp implements Unitc{
|
|||
if(!updateBuilding) return;
|
||||
|
||||
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange;
|
||||
|
||||
boolean infinite = state.rules.infiniteResources || team().rules().infiniteResources;
|
||||
|
||||
Iterator<BuildPlan> it = plans.iterator();
|
||||
|
|
@ -69,10 +68,6 @@ abstract class BuilderComp implements Unitc{
|
|||
|
||||
Tile tile = world.tile(current.x, current.y);
|
||||
|
||||
if(within(tile, finalPlaceDst)){
|
||||
lookAt(angleTo(tile));
|
||||
}
|
||||
|
||||
if(!(tile.block() instanceof ConstructBlock)){
|
||||
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));
|
||||
|
|
@ -188,6 +183,10 @@ abstract class BuilderComp implements Unitc{
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import mindustry.logic.*;
|
|||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.*;
|
||||
import mindustry.world.blocks.ConstructBlock.*;
|
||||
import mindustry.world.blocks.environment.*;
|
||||
import mindustry.world.blocks.payloads.*;
|
||||
|
|
@ -106,8 +107,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||
this.block = block;
|
||||
this.team = team;
|
||||
|
||||
if(block.activeSound != Sounds.none){
|
||||
sound = new SoundLoop(block.activeSound, block.activeSoundVolume);
|
||||
if(block.loopSound != Sounds.none){
|
||||
sound = new SoundLoop(block.loopSound, block.loopSoundVolume);
|
||||
}
|
||||
|
||||
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.*/
|
||||
public boolean shouldIdleSound(){
|
||||
public boolean shouldAmbientSound(){
|
||||
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
|
||||
//region overrides
|
||||
|
||||
|
|
@ -1285,6 +1291,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||
case powerNetStored -> power == null ? 0 : power.graph.getLastPowerStored();
|
||||
case powerNetCapacity -> power == null ? 0 : power.graph.getLastCapacity();
|
||||
case enabled -> enabled ? 1 : 0;
|
||||
case controlled -> this instanceof ControlBlock c ? c.isControlled() ? 1 : 0 : 0;
|
||||
case payloadCount -> getPayload() != null ? 1 : 0;
|
||||
default -> 0;
|
||||
};
|
||||
|
|
@ -1365,8 +1372,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||
sound.update(x, y, shouldActiveSound());
|
||||
}
|
||||
|
||||
if(block.idleSound != Sounds.none && shouldIdleSound()){
|
||||
loops.play(block.idleSound, self(), block.idleSoundVolume);
|
||||
if(block.ambientSound != Sounds.none && shouldAmbientSound()){
|
||||
loops.play(block.ambientSound, self(), block.ambientSoundVolume * ambientVolume());
|
||||
}
|
||||
|
||||
if(enabled || !block.noUpdateDisabled){
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
|
|||
Object data;
|
||||
BulletType type;
|
||||
float fdata;
|
||||
transient boolean absorbed;
|
||||
|
||||
@Override
|
||||
public void getCollisions(Cons<QuadTree> consumer){
|
||||
|
|
@ -67,6 +68,7 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
|
|||
|
||||
@Override
|
||||
public void absorb(){
|
||||
absorbed = true;
|
||||
remove();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,10 +75,14 @@ abstract class FlyingComp implements Posc, Velc, Healthc, Hitboxc{
|
|||
wasFlying = isFlying();
|
||||
}
|
||||
|
||||
if(!hovering && isGrounded() && floor.isLiquid){
|
||||
if(!hovering && isGrounded()){
|
||||
if((splashTimer += Mathf.dst(deltaX(), deltaY())) >= (7f + hitSize()/8f)){
|
||||
floor.walkEffect.at(x, y, hitSize() / 8f, floor.mapColor);
|
||||
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);
|
||||
if(floor.isLiquid){
|
||||
floor.walkEffect.at(l.base.x, l.base.y, type.rippleScale, floor.mapColor);
|
||||
floor.walkSound.at(x, y, 1f, floor.walkSoundVolume);
|
||||
}else{
|
||||
Fx.unitLandSmall.at(l.base.x, l.base.y, type.rippleScale, floor.mapColor);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import mindustry.world.*;
|
|||
import static mindustry.Vars.*;
|
||||
|
||||
@Component
|
||||
abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
||||
@Import float x, y, rotation;
|
||||
abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{
|
||||
@Import float x, y, rotation, hitSize;
|
||||
@Import UnitType type;
|
||||
|
||||
transient float mineTimer;
|
||||
|
|
@ -28,7 +28,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
|||
}
|
||||
|
||||
public boolean offloadImmediately(){
|
||||
return isPlayer();
|
||||
return this.<Unit>self().isPlayer();
|
||||
}
|
||||
|
||||
boolean mining(){
|
||||
|
|
@ -63,7 +63,6 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
|||
mineTimer = 0f;
|
||||
}else if(mining()){
|
||||
Item item = mineTile.drop();
|
||||
lookAt(angleTo(mineTile.worldx(), mineTile.worldy()));
|
||||
mineTimer += Time.delta *type.mineSpeed;
|
||||
|
||||
if(Mathf.chance(0.06 * Time.delta)){
|
||||
|
|
@ -88,13 +87,17 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
|||
mineTimer = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
if(!headless){
|
||||
loops.play(type.mineSound, this, type.mineSoundVolume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
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 flashScl = 0.3f;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import arc.scene.ui.layout.*;
|
|||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.ai.*;
|
||||
import mindustry.ai.types.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.core.*;
|
||||
|
|
@ -30,10 +31,10 @@ import mindustry.world.blocks.payloads.*;
|
|||
import static mindustry.Vars.*;
|
||||
|
||||
@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 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 int id;
|
||||
|
||||
|
|
@ -67,9 +68,14 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||
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. */
|
||||
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. */
|
||||
|
|
@ -78,6 +84,18 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||
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
|
||||
public float range(){
|
||||
return type.range;
|
||||
|
|
@ -105,6 +123,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||
case shootX -> World.conv(aimX());
|
||||
case shootY -> World.conv(aimY());
|
||||
case flag -> flag;
|
||||
case controlled -> controller instanceof LogicAI || controller instanceof Player ? 1 : 0;
|
||||
case payloadCount -> self() instanceof Payloadc pay ? pay.payloads().size : 0;
|
||||
default -> 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import arc.math.*;
|
|||
import arc.math.geom.*;
|
||||
import arc.util.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.audio.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.entities.bullet.*;
|
||||
import mindustry.entities.units.*;
|
||||
|
|
@ -117,10 +118,18 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
|||
mount.bullet.rotation(weaponRotation + 90);
|
||||
mount.bullet.set(shootX, shootY);
|
||||
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{
|
||||
//heat decreases when not firing
|
||||
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
|
||||
|
|
@ -168,7 +177,7 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
|||
float baseX = this.x, baseY = this.y;
|
||||
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;
|
||||
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));
|
||||
Effect.shake(weapon.shake, weapon.shake, x, y);
|
||||
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{
|
||||
vel.add(Tmp.v1.trns(rotation + 180f, ammo.recoil));
|
||||
|
|
|
|||
|
|
@ -64,9 +64,7 @@ public class AIController implements UnitController{
|
|||
if(unit.isFlying()){
|
||||
unit.wobble();
|
||||
|
||||
if(unit.moving()){
|
||||
unit.lookAt(unit.vel.angle());
|
||||
}
|
||||
unit.lookAt(unit.prefRotation());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +92,7 @@ public class AIController implements UnitController{
|
|||
|
||||
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(){
|
||||
|
|
@ -175,7 +173,7 @@ public class AIController implements UnitController{
|
|||
}
|
||||
|
||||
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){
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import mindustry.world.*;
|
|||
import static mindustry.Vars.*;
|
||||
|
||||
/** 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. */
|
||||
public int x, y, rotation;
|
||||
/** Block being placed. If null, this is a breaking request.*/
|
||||
|
|
@ -127,11 +127,11 @@ public class BuildPlan{
|
|||
}
|
||||
|
||||
public float drawx(){
|
||||
return x*tilesize + block.offset;
|
||||
return x*tilesize + (block == null ? 0 : block.offset);
|
||||
}
|
||||
|
||||
public float drawy(){
|
||||
return y*tilesize + block.offset;
|
||||
return y*tilesize + (block == null ? 0 : block.offset);
|
||||
}
|
||||
|
||||
public @Nullable Tile tile(){
|
||||
|
|
@ -142,6 +142,16 @@ public class BuildPlan{
|
|||
return world.build(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getX(){
|
||||
return drawx();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getY(){
|
||||
return drawy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "BuildRequest{" +
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package mindustry.entities.units;
|
||||
|
||||
import arc.util.*;
|
||||
import mindustry.audio.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
|
|
@ -25,6 +26,8 @@ public class WeaponMount{
|
|||
public boolean side;
|
||||
/** current bullet for continuous weapons */
|
||||
public @Nullable Bullet bullet;
|
||||
/** sound loop for continuous weapons */
|
||||
public @Nullable SoundLoop sound;
|
||||
|
||||
public WeaponMount(Weapon weapon){
|
||||
this.weapon = weapon;
|
||||
|
|
|
|||
|
|
@ -481,8 +481,8 @@ public class DesktopInput extends InputHandler{
|
|||
deleting = true;
|
||||
}else if(selected != null){
|
||||
//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 &&
|
||||
!tryBeginMine(selected) && player.miner().mineTile() == null && !Core.scene.hasKeyboard()){
|
||||
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()){
|
||||
player.shooting = shouldShoot;
|
||||
}
|
||||
}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();
|
||||
|
||||
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 xa = Core.input.axis(Binding.move_x);
|
||||
|
|
@ -627,9 +620,7 @@ public class DesktopInput extends InputHandler{
|
|||
if(aimCursor){
|
||||
unit.lookAt(mouseAngle);
|
||||
}else{
|
||||
if(!movement.isZero()){
|
||||
unit.lookAt(unit.vel.isZero() ? movement.angle() : unit.vel.angle());
|
||||
}
|
||||
unit.lookAt(unit.prefRotation());
|
||||
}
|
||||
|
||||
if(omni){
|
||||
|
|
|
|||
|
|
@ -933,11 +933,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||
|
||||
boolean canMine(Tile tile){
|
||||
return !Core.scene.hasMouse()
|
||||
&& tile.drop() != null
|
||||
&& player.miner().validMine(tile)
|
||||
&& !(tile.floor().playerUnmineable && tile.overlay().itemDrop == null)
|
||||
&& player.unit().acceptsItem(tile.drop())
|
||||
&& tile.block() == Blocks.air;
|
||||
&& tile.drop() != null
|
||||
&& player.miner().validMine(tile)
|
||||
&& !(tile.floor().playerUnmineable && tile.overlay().itemDrop == null)
|
||||
&& player.unit().acceptsItem(tile.drop())
|
||||
&& tile.block() == Blocks.air;
|
||||
}
|
||||
|
||||
/** Returns the tile at the specified MOUSE coordinates. */
|
||||
|
|
@ -1044,7 +1044,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -856,14 +856,6 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||
float attractDst = 15f;
|
||||
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 range = unit.hasWeapons() ? unit.range() : 0f;
|
||||
float bulletSpeed = unit.hasWeapons() ? type.weapons.first().bullet.speed : 0f;
|
||||
|
|
@ -873,9 +865,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||
if(aimCursor){
|
||||
unit.lookAt(mouseAngle);
|
||||
}else{
|
||||
if(unit.moving()){
|
||||
unit.lookAt(unit.vel.angle());
|
||||
}
|
||||
unit.lookAt(unit.prefRotation());
|
||||
}
|
||||
|
||||
if(payloadTarget != null && unit instanceof Payloadc pay){
|
||||
|
|
@ -905,7 +895,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||
|
||||
if(player.within(targetPos, attractDst)){
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ public enum LAccess{
|
|||
team,
|
||||
type,
|
||||
flag,
|
||||
controlled,
|
||||
name,
|
||||
config,
|
||||
payloadCount,
|
||||
|
|
|
|||
|
|
@ -96,11 +96,13 @@ public class LAssembler{
|
|||
if(data == null || data.isEmpty()) return new Seq<>();
|
||||
|
||||
Seq<LStatement> statements = new Seq<>();
|
||||
String[] lines = data.split("[;\n]+");
|
||||
String[] lines = data.split("\n");
|
||||
int index = 0;
|
||||
for(String line : lines){
|
||||
//comments
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -469,7 +469,7 @@ public class LExecutor{
|
|||
|
||||
Building build = exec.building(p1);
|
||||
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);
|
||||
if(accepted > 0){
|
||||
Call.transferItemTo(unit, unit.item(), accepted, unit.x, unit.y, build);
|
||||
|
|
@ -483,7 +483,7 @@ public class LExecutor{
|
|||
Building build = exec.building(p1);
|
||||
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)));
|
||||
|
||||
if(taken > 0){
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@ import mindustry.gen.*;
|
|||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
import static mindustry.game.EventType.*;
|
||||
|
||||
|
|
@ -449,111 +447,11 @@ public class Administration{
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void load(){
|
||||
if(!loadLegacy()){
|
||||
//load default data
|
||||
playerInfo = Core.settings.getJson("player-data", ObjectMap.class, ObjectMap::new);
|
||||
bannedIPs = Core.settings.getJson("ip-bans", Seq.class, Seq::new);
|
||||
whitelist = Core.settings.getJson("whitelist-ids", 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;
|
||||
//load default data
|
||||
playerInfo = Core.settings.getJson("player-data", ObjectMap.class, ObjectMap::new);
|
||||
bannedIPs = Core.settings.getJson("ip-bans", Seq.class, Seq::new);
|
||||
whitelist = Core.settings.getJson("whitelist-ids", Seq.class, Seq::new);
|
||||
subnetBans = Core.settings.getJson("banned-subnets", Seq.class, Seq::new);
|
||||
}
|
||||
|
||||
/** 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),
|
||||
autosaveSpacing("Spacing between autosaves in seconds.", 60 * 5),
|
||||
debug("Enable debug logging", false, () -> {
|
||||
LogLevel level = debug() ? LogLevel.debug : LogLevel.info;
|
||||
Log.level = level;
|
||||
Log.level = debug() ? LogLevel.debug : LogLevel.info;
|
||||
});
|
||||
|
||||
public static final Config[] all = values();
|
||||
|
|
|
|||
6
core/src/mindustry/net/ServerGroup.java
Normal file
6
core/src/mindustry/net/ServerGroup.java
Normal file
|
|
@ -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;
|
||||
}
|
||||
|
||||
public void min(int number){
|
||||
for(Item item : Vars.content.items()){
|
||||
set(item, Math.min(get(item), number));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean has(Item item){
|
||||
return values[item.id] > 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ public class UnitType extends UnlockableContent{
|
|||
public AmmoType ammoType = AmmoTypes.copper;
|
||||
public int mineTier = -1;
|
||||
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. */
|
||||
public float dpsEstimate = -1;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ public class Weapon{
|
|||
public float shootCone = 5f;
|
||||
/** ticks to cool down the heat region */
|
||||
public float cooldownTime = 20f;
|
||||
/** random sound pitch range */
|
||||
public float soundPitchMin = 0.8f, soundPitchMax = 1f;
|
||||
/** whether shooter rotation is ignored when shooting. */
|
||||
public boolean ignoreRotation = false;
|
||||
/** min velocity required for this weapon to shoot */
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
package mindustry.type;
|
||||
|
||||
import arc.*;
|
||||
import arc.audio.*;
|
||||
import arc.func.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.util.*;
|
||||
import arc.util.noise.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.ctype.*;
|
||||
|
|
@ -22,6 +24,9 @@ public abstract class Weather extends UnlockableContent{
|
|||
public float duration = 9f * Time.toMinutes;
|
||||
public float opacityMultiplier = 1f;
|
||||
public Attributes attrs = new Attributes();
|
||||
public Sound sound = Sounds.none;
|
||||
public float soundVol = 0.1f, soundVolMin = 0f;
|
||||
public float soundVolOscMag = 0f, soundVolOscScl = 20f;
|
||||
|
||||
//internals
|
||||
public Rand rand = new Rand();
|
||||
|
|
@ -83,6 +88,11 @@ public abstract class Weather extends UnlockableContent{
|
|||
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){
|
||||
|
|
|
|||
|
|
@ -42,6 +42,13 @@ public class LaunchLoadoutDialog extends BaseDialog{
|
|||
|
||||
//updates sum requirements
|
||||
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();
|
||||
selected.requirements().each(total::add);
|
||||
universe.getLaunchResources().each(total::add);
|
||||
|
|
@ -79,7 +86,7 @@ public class LaunchLoadoutDialog extends BaseDialog{
|
|||
ItemSeq stacks = universe.getLaunchResources();
|
||||
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));
|
||||
update.run();
|
||||
rebuildItems.run();
|
||||
|
|
|
|||
|
|
@ -174,14 +174,14 @@ public class Block extends UnlockableContent{
|
|||
public float lightRadius = 60f;
|
||||
|
||||
/** 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. */
|
||||
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.*/
|
||||
public Sound idleSound = Sounds.none;
|
||||
public Sound ambientSound = Sounds.none;
|
||||
/** Idle sound base volume. */
|
||||
public float idleSoundVolume = 0.5f;
|
||||
public float ambientSoundVolume = 0.05f;
|
||||
|
||||
/** Cost of constructing this block. */
|
||||
public ItemStack[] requirements = {};
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ public class ForceProjector extends Block{
|
|||
hasPower = true;
|
||||
hasLiquids = 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);
|
||||
}
|
||||
|
||||
|
|
@ -107,6 +109,11 @@ public class ForceProjector extends Block{
|
|||
drawer.add();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAmbientSound(){
|
||||
return !broken && realRadius() > 1f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoved(){
|
||||
super.onRemoved();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public class LiquidTurret extends Turret{
|
|||
super(name);
|
||||
acceptCoolant = false;
|
||||
hasLiquids = true;
|
||||
activeSound = Sounds.spray;
|
||||
loopSound = Sounds.spray;
|
||||
}
|
||||
|
||||
/** Initializes accepted ammo map. Format: [liquid1, bullet1, liquid2, bullet2...] */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package mindustry.world.blocks.defense.turrets;
|
||||
|
||||
import arc.audio.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
|
|
@ -24,6 +25,8 @@ public class PointDefenseTurret extends ReloadTurret{
|
|||
public Effect hitEffect = Fx.pointHit;
|
||||
public Effect shootEffect = Fx.sparkShoot;
|
||||
|
||||
public Sound shootSound = Sounds.lasershoot;
|
||||
|
||||
public float shootCone = 5f;
|
||||
public float bulletDamage = 10f;
|
||||
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));
|
||||
shootEffect.at(x + Tmp.v1.x, y + Tmp.v1.y, rotation, 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;
|
||||
}
|
||||
}else{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package mindustry.world.blocks.defense.turrets;
|
||||
|
||||
import arc.audio.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
|
|
@ -34,6 +35,9 @@ public class TractorBeamTurret extends BaseTurret{
|
|||
public StatusEffect status = StatusEffects.none;
|
||||
public float statusDuration = 300;
|
||||
|
||||
public Sound shootSound = Sounds.tractorbeam;
|
||||
public float shootSoundVolume = 0.9f;
|
||||
|
||||
public TractorBeamTurret(String name){
|
||||
super(name);
|
||||
|
||||
|
|
@ -91,6 +95,8 @@ public class TractorBeamTurret extends BaseTurret{
|
|||
|
||||
//look at target
|
||||
if(target != null && target.within(this, range) && target.team() != team && target.type.flying && efficiency() > 0.01f){
|
||||
loops.play(shootSound, this, shootSoundVolume);
|
||||
|
||||
any = true;
|
||||
float dest = angleTo(target);
|
||||
rotation = Angles.moveToward(rotation, dest, rotateSpeed * edelta());
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ public abstract class Turret extends ReloadTurret{
|
|||
public float recoilAmount = 1f;
|
||||
public float restitution = 0.02f;
|
||||
public float cooldown = 0.02f;
|
||||
public float coolantUsage = 0.2f;
|
||||
public float shootCone = 8f;
|
||||
public float shootShake = 0f;
|
||||
public float xRand = 0f;
|
||||
|
|
@ -109,7 +110,7 @@ public abstract class Turret extends ReloadTurret{
|
|||
public void init(){
|
||||
if(acceptCoolant && !consumes.has(ConsumeType.liquid)){
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ public class Conveyor extends Block implements Autotiler{
|
|||
itemCapacity = 4;
|
||||
conveyorPlacement = true;
|
||||
|
||||
idleSound = Sounds.conveyor;
|
||||
idleSoundVolume = 0.004f;
|
||||
ambientSound = Sounds.conveyor;
|
||||
ambientSoundVolume = 0.0015f;
|
||||
unloadable = false;
|
||||
noUpdateDisabled = false;
|
||||
}
|
||||
|
|
@ -161,7 +161,7 @@ public class Conveyor extends Block implements Autotiler{
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldIdleSound(){
|
||||
public boolean shouldAmbientSound(){
|
||||
return clogHeat <= 0.5f;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ public class StackConveyor extends Block implements Autotiler{
|
|||
itemCapacity = 10;
|
||||
conveyorPlacement = true;
|
||||
|
||||
idleSound = Sounds.conveyor;
|
||||
idleSoundVolume = 0.004f;
|
||||
ambientSound = Sounds.conveyor;
|
||||
ambientSoundVolume = 0.004f;
|
||||
unloadable = false;
|
||||
}
|
||||
|
||||
|
|
@ -231,7 +231,7 @@ public class StackConveyor extends Block implements Autotiler{
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldIdleSound(){
|
||||
public boolean shouldAmbientSound(){
|
||||
return false; // has no moving parts;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package mindustry.world.blocks.environment;
|
||||
|
||||
import arc.*;
|
||||
import arc.audio.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.graphics.g2d.TextureAtlas.*;
|
||||
|
|
@ -10,6 +11,7 @@ import arc.struct.*;
|
|||
import arc.util.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.graphics.MultiPacker.*;
|
||||
import mindustry.type.*;
|
||||
|
|
@ -33,7 +35,11 @@ public class Floor extends Block{
|
|||
/** How many ticks it takes to drown on this. */
|
||||
public float drownTime = 0f;
|
||||
/** 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. */
|
||||
public Effect drownUpdateEffect = Fx.bubble;
|
||||
/** Status effect applied when walking on. */
|
||||
|
|
@ -115,6 +121,14 @@ public class Floor extends Block{
|
|||
if(decoration == Blocks.air){
|
||||
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
|
||||
|
|
|
|||
|
|
@ -91,6 +91,11 @@ public class ImpactReactor extends PowerGenerator{
|
|||
productionEfficiency = Mathf.pow(warmup, 5f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float ambientVolume(){
|
||||
return warmup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
Draw.rect(bottomRegion, x, y);
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ public class Drill extends Block{
|
|||
hasLiquids = true;
|
||||
liquidCapacity = 5f;
|
||||
hasItems = true;
|
||||
idleSound = Sounds.drill;
|
||||
idleSoundVolume = 0.003f;
|
||||
ambientSound = Sounds.drill;
|
||||
ambientSoundVolume = 0.016f;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -205,8 +205,8 @@ public class Drill extends Block{
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldIdleSound(){
|
||||
return efficiency() > 0.01f;
|
||||
public boolean shouldAmbientSound(){
|
||||
return efficiency() > 0.01f && items.total() < itemCapacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue