New WIP achievement definitions
This commit is contained in:
@@ -11,7 +11,13 @@ import mindustry.game.SectorInfo.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.defense.*;
|
||||
import mindustry.world.blocks.defense.Wall.*;
|
||||
import mindustry.world.blocks.defense.turrets.Turret.*;
|
||||
import mindustry.world.blocks.distribution.*;
|
||||
import mindustry.world.blocks.production.AttributeCrafter.*;
|
||||
import mindustry.world.blocks.production.SolidPump.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
import static mindustry.service.Achievement.*;
|
||||
@@ -21,16 +27,17 @@ import static mindustry.service.Achievement.*;
|
||||
*
|
||||
* This includes:
|
||||
* - Desktop (Steam)
|
||||
* - iOS (Game Center)
|
||||
* - Android (Google Play Games)
|
||||
*
|
||||
* The default implementation does nothing.
|
||||
* */
|
||||
public class GameService{
|
||||
private Seq<Tile> tmpTiles = new Seq<>();
|
||||
private ObjectSet<String> blocksBuilt = new ObjectSet<>(), unitsBuilt = new ObjectSet<>();
|
||||
private ObjectSet<UnitType> t5s = new ObjectSet<>();
|
||||
private IntSet checked = new IntSet();
|
||||
|
||||
private Block[] allTransportSerpulo, allTransportErekir, allErekirBlocks, allSerpuloBlocks;
|
||||
|
||||
/** Begin listening for new achievement events, once the game service is activated. This can be called at any time, but only once. */
|
||||
public void init(){
|
||||
if(clientLoaded){
|
||||
@@ -64,11 +71,26 @@ public class GameService{
|
||||
|
||||
}
|
||||
|
||||
private void checkAllBlocks(Achievement ach, Block[] blocks){
|
||||
if(!Structs.contains(blocks, t -> !blocksBuilt.contains(t.name))){
|
||||
ach.complete();
|
||||
}
|
||||
}
|
||||
|
||||
private void registerEvents(){
|
||||
allTransportSerpulo = content.blocks().select(b -> b.category == Category.distribution && b.isVisibleOn(Planets.serpulo) && b.isVanilla() && b.buildVisibility == BuildVisibility.shown).toArray(Block.class);
|
||||
allTransportErekir = content.blocks().select(b -> b.category == Category.distribution && b.isVisibleOn(Planets.erekir) && b.isVanilla() && b.buildVisibility == BuildVisibility.shown).toArray(Block.class);
|
||||
|
||||
allSerpuloBlocks = content.blocks().select(b -> b.synthetic() && b.isVisibleOn(Planets.serpulo) && b.isVanilla() && b.buildVisibility == BuildVisibility.shown).toArray(Block.class);
|
||||
allErekirBlocks = content.blocks().select(b -> b.synthetic() && b.isVisibleOn(Planets.erekir) && b.isVanilla() && b.buildVisibility == BuildVisibility.shown).toArray(Block.class);
|
||||
|
||||
unitsBuilt = Core.settings.getJson("units-built" , ObjectSet.class, String.class, ObjectSet::new);
|
||||
blocksBuilt = Core.settings.getJson("blocks-built" , ObjectSet.class, String.class, ObjectSet::new);
|
||||
t5s = ObjectSet.with(UnitTypes.omura, UnitTypes.reign, UnitTypes.toxopid, UnitTypes.eclipse, UnitTypes.oct, UnitTypes.corvus);
|
||||
|
||||
checkAllBlocks(allBlocksErekir, allErekirBlocks);
|
||||
checkAllBlocks(allBlocksSerpulo, allSerpuloBlocks);
|
||||
|
||||
//periodically check for various conditions
|
||||
float updateInterval = 2f;
|
||||
Timer.schedule(this::checkUpdate, updateInterval, updateInterval);
|
||||
@@ -79,6 +101,14 @@ public class GameService{
|
||||
unlockAllZones.complete();
|
||||
}
|
||||
|
||||
if(mods.list().size > 0){
|
||||
installMod.complete();
|
||||
}
|
||||
|
||||
if(Core.bundle.get("yes").equals("router")){
|
||||
routerLanguage.complete();
|
||||
}
|
||||
|
||||
Events.on(UnitDestroyEvent.class, e -> {
|
||||
if(campaign()){
|
||||
if(e.unit.team != Vars.player.team()){
|
||||
@@ -106,12 +136,43 @@ public class GameService{
|
||||
SStat.maxProduction.max(Math.round(total));
|
||||
});
|
||||
|
||||
Events.run(Trigger.update, () -> {
|
||||
//extremely lazy timer, I just don't care
|
||||
if(campaign() && !hoverUnitLiquid.isAchieved() && Core.graphics.getFrameId() % 20 == 0){
|
||||
var units = state.rules.defaultTeam.data().getUnits(UnitTypes.elude);
|
||||
if(units != null){
|
||||
for(var unit : units){
|
||||
if(unit.floorOn().isLiquid){
|
||||
hoverUnitLiquid.complete();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(campaign() && player.unit().type.canBoost && player.unit().elevation >= 0.25f){
|
||||
boostUnit.complete();
|
||||
}
|
||||
});
|
||||
|
||||
Events.run(Trigger.newGame, () -> Core.app.post(() -> {
|
||||
if(campaign() && player.core() != null && player.core().items.total() >= 10 * 1000){
|
||||
drop10kitems.complete();
|
||||
}
|
||||
}));
|
||||
|
||||
Events.on(BuildingBulletDestroyEvent.class, e -> {
|
||||
if(campaign() && e.build.block == Blocks.scatter && e.build.team == state.rules.waveTeam && e.bullet.owner instanceof Unit u && u.type == UnitTypes.flare && u.team == player.team()){
|
||||
destroyScatterFlare.complete();
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(BlockBuildBeginEvent.class, e -> {
|
||||
if(campaign() && state.rules.sector == SectorPresets.groundZero.sector && e.tile.block() == Blocks.coreNucleus){
|
||||
nucleusGroundZero.complete();
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(BlockBuildEndEvent.class, e -> {
|
||||
if(campaign() && e.unit != null && e.unit.isLocal() && !e.breaking){
|
||||
SStat.blocksBuilt.add();
|
||||
@@ -124,7 +185,40 @@ public class GameService{
|
||||
buildGroundFactory.complete();
|
||||
}
|
||||
|
||||
if((e.tile.build instanceof AttributeCrafterBuild a && a.attrsum > 0) || (e.tile.build instanceof SolidPumpBuild sp && sp.boost > 0)){
|
||||
boostBuildingFloor.complete();
|
||||
}
|
||||
|
||||
if(!allTransportOneMap.isAchieved()){
|
||||
Block[] allTransports = state.rules.sector.planet == Planets.erekir ? allTransportErekir : allTransportSerpulo;
|
||||
boolean all = true;
|
||||
for(var block : allTransports){
|
||||
if(state.rules.defaultTeam.data().getCount(block) == 0){
|
||||
all = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(all){
|
||||
allTransportOneMap.complete();
|
||||
}
|
||||
}
|
||||
|
||||
if(e.tile.block() instanceof MendProjector || e.tile.block() instanceof RegenProjector) buildMendProjector.complete();
|
||||
if(e.tile.block() instanceof OverdriveProjector) buildOverdrive.complete();
|
||||
|
||||
if(e.tile.block() == Blocks.waterExtractor){
|
||||
if(e.tile.getLinkedTiles(tmpTiles).contains(t -> t.floor().liquidDrop == Liquids.water)){
|
||||
buildWexWater.complete();
|
||||
}
|
||||
}
|
||||
|
||||
if(blocksBuilt.add(e.tile.block().name)){
|
||||
if(state.rules.sector.planet == Planets.erekir){
|
||||
checkAllBlocks(allBlocksErekir, allErekirBlocks);
|
||||
}else{
|
||||
checkAllBlocks(allBlocksSerpulo, allSerpuloBlocks);
|
||||
}
|
||||
|
||||
if(blocksBuilt.contains("meltdown") && blocksBuilt.contains("spectre") && blocksBuilt.contains("foreshadow")){
|
||||
buildMeltdownSpectre.complete();
|
||||
}
|
||||
@@ -153,6 +247,32 @@ public class GameService{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(campaign() && e.unit != null && e.unit.isLocal() && e.breaking){
|
||||
//hacky way of testing for boulders without string contains/endsWith
|
||||
if(e.tile.block().breakSound == Sounds.rockBreak){
|
||||
SStat.bouldersDeconstructed.add();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(TurnEvent.class, e -> {
|
||||
int total = 0;
|
||||
for(var planet : content.planets()){
|
||||
for(var sector : planet.sectors){
|
||||
if(sector.hasBase()){
|
||||
total += sector.items().total;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SStat.totalCampaignItems.max(total);
|
||||
});
|
||||
|
||||
Events.on(SectorLaunchLoadoutEvent.class, e -> {
|
||||
if(!schematics.isDefaultLoadout(e.loadout)){
|
||||
launchCoreSchematic.complete();
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(UnitCreateEvent.class, e -> {
|
||||
@@ -172,6 +292,10 @@ public class GameService{
|
||||
if(e.unit instanceof BlockUnitc unit && unit.tile().block == Blocks.router){
|
||||
becomeRouter.complete();
|
||||
}
|
||||
|
||||
if(e.unit instanceof BlockUnitc unit && unit.tile() instanceof TurretBuild){
|
||||
controlTurret.complete();
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(SchematicCreateEvent.class, e -> {
|
||||
@@ -198,6 +322,8 @@ public class GameService{
|
||||
|
||||
Events.run(Trigger.openWiki, openWiki::complete);
|
||||
|
||||
Events.run(Trigger.importMod, installMod::complete);
|
||||
|
||||
Events.run(Trigger.exclusionDeath, dieExclusion::complete);
|
||||
|
||||
Events.on(UnitDrownEvent.class, e -> {
|
||||
@@ -216,6 +342,14 @@ public class GameService{
|
||||
|
||||
trigger(Trigger.suicideBomb, suicideBomb);
|
||||
|
||||
trigger(Trigger.blastGenerator, blastGenerator);
|
||||
|
||||
trigger(Trigger.forceProjectorBreak, breakForceProjector);
|
||||
|
||||
trigger(Trigger.neoplasmReact, neoplasmWater);
|
||||
|
||||
trigger(Trigger.shockwaveTowerUse, shockwaveTowerUse);
|
||||
|
||||
Events.run(Trigger.enablePixelation, enablePixelation::complete);
|
||||
|
||||
Events.run(Trigger.thoriumReactorOverheat, () -> {
|
||||
@@ -224,9 +358,28 @@ public class GameService{
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(GeneratorPressureExplodeEvent.class, e -> {
|
||||
if(campaign() && e.build.block == Blocks.neoplasiaReactor){
|
||||
neoplasiaExplosion.complete();
|
||||
}
|
||||
});
|
||||
|
||||
trigger(Trigger.shock, shockWetEnemy);
|
||||
|
||||
trigger(Trigger.phaseDeflectHit, killEnemyPhaseWall);
|
||||
trigger(Trigger.blastFreeze, blastFrozenUnit);
|
||||
|
||||
Events.on(UnitBulletDestroyEvent.class, e -> {
|
||||
if(state.isCampaign() && player != null && player.team() == e.bullet.team){
|
||||
|
||||
if(e.bullet.owner instanceof WallBuild){
|
||||
killEnemyPhaseWall.complete();
|
||||
}
|
||||
|
||||
if(e.unit.type == UnitTypes.eclipse && e.bullet.owner instanceof TurretBuild turret && turret.block == Blocks.duo){
|
||||
killEclipseDuo.complete();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(LaunchItemEvent.class, e -> {
|
||||
if(campaign()){
|
||||
@@ -276,6 +429,8 @@ public class GameService{
|
||||
if(!TechTree.all.contains(t -> t.content.locked())){
|
||||
researchAll.complete();
|
||||
}
|
||||
|
||||
if(Blocks.logicProcessor.unlocked()) researchLogic.complete();
|
||||
};
|
||||
|
||||
//check unlocked stuff on load as well
|
||||
@@ -289,6 +444,12 @@ public class GameService{
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(ClientPreConnectEvent.class, e -> {
|
||||
if(e.host != null && !e.host.address.startsWith("steam:") && !e.host.address.startsWith("192.")){
|
||||
joinCommunityServer.complete();
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(SectorCaptureEvent.class, e -> {
|
||||
if(e.sector.isBeingPlayed() || net.client()){
|
||||
if(Vars.state.wave <= 5 && state.rules.attackMode){
|
||||
@@ -312,8 +473,18 @@ public class GameService{
|
||||
captureAllSectors.complete();
|
||||
}
|
||||
|
||||
if(!e.sector.planet.sectors.contains(s -> s.preset != null && !s.hasBase())){
|
||||
allPresetsErekir.complete();
|
||||
}
|
||||
|
||||
SStat.sectorsControlled.set(e.sector.planet.sectors.count(Sector::hasBase));
|
||||
});
|
||||
|
||||
Events.on(PayloadDropEvent.class, e -> {
|
||||
if(e.unit != null && e.carrier.team == state.rules.defaultTeam && state.rules.waveTeam.cores().contains(c -> c.within(e.unit, state.rules.enemyCoreBuildRadius))){
|
||||
dropUnitsCoreZone.complete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void checkUpdate(){
|
||||
@@ -330,6 +501,20 @@ public class GameService{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(var up : Groups.powerGraph){
|
||||
var graph = up.graph();
|
||||
if(graph.all.size > 0 && graph.all.first().team == player.team()){
|
||||
float balance = graph.getPowerBalance();
|
||||
if(balance < 10_000) negative10kPower.complete();
|
||||
if(balance > 100_000) positive100kPower.complete();
|
||||
if(graph.getBatteryStored() > 1_000_000) store1milPower.complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ui.consolefrag.shown()){
|
||||
openConsole.complete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user