WIP campaign stat tracking (not displayed yet)
This commit is contained in:
@@ -187,7 +187,7 @@ public class Control implements ApplicationListener, Loadable{
|
||||
Events.on(GameOverEvent.class, e -> {
|
||||
if(state.isCampaign() && !net.client() && !headless){
|
||||
|
||||
//save gameover sate immediately
|
||||
//save gameover state immediately
|
||||
if(saves.getCurrent() != null){
|
||||
saves.getCurrent().save();
|
||||
}
|
||||
@@ -285,7 +285,12 @@ public class Control implements ApplicationListener, Loadable{
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(SaveWriteEvent.class, e -> forcePlaceAll());
|
||||
Events.on(SaveWriteEvent.class, e -> {
|
||||
if(!net.client() && state.isCampaign()){
|
||||
state.getPlanet().saveStats();
|
||||
}
|
||||
forcePlaceAll();
|
||||
});
|
||||
Events.on(HostEvent.class, e -> forcePlaceAll());
|
||||
Events.on(HostEvent.class, e -> {
|
||||
state.set(State.playing);
|
||||
|
||||
@@ -135,6 +135,10 @@ public class Logic implements ApplicationListener{
|
||||
if(!net.client() && e.sector.planet.generator != null){
|
||||
e.sector.planet.generator.onSectorCaptured(e.sector);
|
||||
}
|
||||
|
||||
if(checkCampaignStats()){
|
||||
state.getPlanet().stats().sectorsCaptured ++;
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(SectorLoseEvent.class, e -> {
|
||||
@@ -157,38 +161,71 @@ public class Logic implements ApplicationListener{
|
||||
}));
|
||||
|
||||
Events.on(BlockBuildEndEvent.class, e -> {
|
||||
if(e.team == state.rules.defaultTeam){
|
||||
|
||||
if((e.team == state.rules.defaultTeam || e.unit != null && e.unit.team == state.rules.defaultTeam)){
|
||||
if(e.breaking){
|
||||
state.stats.buildingsDeconstructed++;
|
||||
}else{
|
||||
state.stats.buildingsBuilt++;
|
||||
}
|
||||
|
||||
if(checkCampaignStats()){
|
||||
(e.breaking ? state.getPlanet().stats().buildingsDeconstructed : state.getPlanet().stats().buildingsBuilt).increment(e.tile.block());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(BlockDestroyEvent.class, e -> {
|
||||
if(e.tile.team() == state.rules.defaultTeam){
|
||||
state.stats.buildingsDestroyed ++;
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(BlockDestroyEvent.class, e -> {
|
||||
if(e.tile.team() != state.rules.defaultTeam){
|
||||
if(checkCampaignStats()){
|
||||
state.getPlanet().stats().buildingsDestroyed.increment(e.tile.block());
|
||||
}
|
||||
}else{ //...should derelict blocks count as 'destroyed'? technically, they could be destroyed by the enemy, but that is very rare
|
||||
state.stats.destroyedBlockCount.increment(e.tile.block());
|
||||
|
||||
if(checkCampaignStats()){
|
||||
state.getPlanet().stats().enemyBuildingsDestroyed.increment(e.tile.block());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(UnitDestroyEvent.class, e -> {
|
||||
if(e.unit.team() != state.rules.defaultTeam){
|
||||
state.stats.enemyUnitsDestroyed ++;
|
||||
|
||||
if(checkCampaignStats()){
|
||||
state.getPlanet().stats().enemyUnitsDestroyed.increment(e.unit.type);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(UnitCreateEvent.class, e -> {
|
||||
if(e.unit.team == state.rules.defaultTeam){
|
||||
state.stats.unitsCreated++;
|
||||
|
||||
if(checkCampaignStats()){
|
||||
state.getPlanet().stats().unitsProduced.increment(e.unit.type);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(WaveEvent.class, e -> {
|
||||
if(checkCampaignStats()){
|
||||
state.getPlanet().stats().wavesLasted ++;
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(GameOverEvent.class, e -> {
|
||||
if(checkCampaignStats()){
|
||||
state.getPlanet().stats().sectorsLost ++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean checkCampaignStats(){
|
||||
return state.isCampaign() && !net.client();
|
||||
}
|
||||
|
||||
private void checkOverlappingPlans(Team team, Tile tile){
|
||||
|
||||
29
core/src/mindustry/game/CampaignStats.java
Normal file
29
core/src/mindustry/game/CampaignStats.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package mindustry.game;
|
||||
|
||||
import arc.struct.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
/** Statistics for a specific planet's campaign. */
|
||||
public class CampaignStats{
|
||||
/** Enemy units destroyed by type. */
|
||||
public ObjectIntMap<UnitType> enemyUnitsDestroyed = new ObjectIntMap<>();
|
||||
/** Record of enemy blocks that have been destroyed (from any source) by count. */
|
||||
public ObjectIntMap<Block> enemyBuildingsDestroyed = new ObjectIntMap<>();
|
||||
/** Player team units produced by type. */
|
||||
public ObjectIntMap<UnitType> unitsProduced = new ObjectIntMap<>();
|
||||
/** Record of blocks that have been placed by count. */
|
||||
public ObjectIntMap<Block> buildingsBuilt = new ObjectIntMap<>();
|
||||
/** Record of blocks that have been placed by count. */
|
||||
public ObjectIntMap<Block> buildingsDeconstructed = new ObjectIntMap<>();
|
||||
/** Record of blocks that have been placed by count. */
|
||||
public ObjectIntMap<Block> buildingsDestroyed = new ObjectIntMap<>();
|
||||
/** Total campaign playtime in milliseconds. */
|
||||
public long playtime;
|
||||
/** Total game-overs. */
|
||||
public int sectorsLost;
|
||||
/** Total times a sector has been captured. If you lose (or get invaded) and re-capture something, this still counts. */
|
||||
public int sectorsCaptured;
|
||||
/** Total waves lasted. */
|
||||
public int wavesLasted;
|
||||
}
|
||||
@@ -22,7 +22,7 @@ public class GameStats{
|
||||
/** Record of enemy blocks that have been destroyed (from any source) by count. */
|
||||
public ObjectIntMap<Block> destroyedBlockCount = new ObjectIntMap<>();
|
||||
/**
|
||||
* Record of items that have entered the core through transport blocks. Used for objectives only.
|
||||
* Record of items that have entered the core through transport blocks. Used for tutorial objectives only.
|
||||
* This can easily be ""spoofed"" with unloaders, so don't use it for anything remotely important.
|
||||
* */
|
||||
public ObjectIntMap<Item> coreItemCount = new ObjectIntMap<>();
|
||||
|
||||
@@ -187,7 +187,11 @@ public class Saves{
|
||||
if(current != null && state.isGame()
|
||||
&& !(state.isPaused() && Core.scene.hasDialog())){
|
||||
if(lastTimestamp != 0){
|
||||
totalPlaytime += Time.timeSinceMillis(lastTimestamp);
|
||||
long change = Time.timeSinceMillis(lastTimestamp);
|
||||
totalPlaytime += change;
|
||||
if(state.isCampaign()){
|
||||
state.getPlanet().stats().playtime += change;
|
||||
}
|
||||
}
|
||||
lastTimestamp = Time.millis();
|
||||
}
|
||||
|
||||
@@ -162,6 +162,9 @@ public class Planet extends UnlockableContent{
|
||||
/** Loads the planet grid outline mesh. Clientside only. */
|
||||
public Prov<Mesh> gridMeshLoader = () -> MeshBuilder.buildPlanetGrid(grid, outlineColor, outlineRad * radius);
|
||||
|
||||
/** If set, this planet will have the same stats as its parent. Use for shared campaigns. */
|
||||
public @Nullable Planet statParent;
|
||||
|
||||
/** Planets that are allowed to update at the same time as this one for background calculations. */
|
||||
public ObjectSet<Planet> updateGroup = new ObjectSet<>();
|
||||
/** Global difficulty/modifier settings for this planet's campaign. */
|
||||
@@ -178,6 +181,9 @@ public class Planet extends UnlockableContent{
|
||||
/** Data indicating attack sector positions and sector mappings. */
|
||||
public @Nullable PlanetData data;
|
||||
|
||||
/** Statistics of this planet campaign. If statParent is not null, this planet shares the same stats as the parent. */
|
||||
private CampaignStats campaignStats = new CampaignStats();
|
||||
|
||||
public Planet(String name, Planet parent, float radius){
|
||||
super(name);
|
||||
|
||||
@@ -228,6 +234,34 @@ public class Planet extends UnlockableContent{
|
||||
campaignRules = Core.settings.getJson(name + "-campaign-rules", CampaignRules.class, () -> campaignRules);
|
||||
}
|
||||
|
||||
public CampaignStats stats(){
|
||||
return statParent != null ? statParent.campaignStats : campaignStats;
|
||||
}
|
||||
|
||||
public void loadStats(){
|
||||
//there is no need to load stats if the parent's ones are used
|
||||
if(statParent == null){
|
||||
campaignStats = Core.settings.getJson(name + "-campaign-stats", CampaignStats.class, CampaignStats::new);
|
||||
}
|
||||
}
|
||||
|
||||
public void saveStats(){
|
||||
if(statParent != null && statParent != this){
|
||||
statParent.saveStats();
|
||||
}else{
|
||||
Core.settings.putJson(name + "-campaign-stats", campaignStats);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearStats(){
|
||||
if(statParent != null && statParent != this){
|
||||
statParent.clearStats();
|
||||
}else{
|
||||
campaignStats = new CampaignStats();
|
||||
saveStats();
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable Sector getStartSector(){
|
||||
return sectors.size == 0 ? null : sectors.get(startSector);
|
||||
}
|
||||
@@ -391,6 +425,7 @@ public class Planet extends UnlockableContent{
|
||||
public void init(){
|
||||
applyDefaultRules(campaignRules);
|
||||
loadRules();
|
||||
loadStats();
|
||||
|
||||
if(techTree == null){
|
||||
techTree = TechTree.roots.find(n -> n.planet == this);
|
||||
|
||||
@@ -36,7 +36,13 @@ public class PausedDialog extends BaseDialog{
|
||||
}).size(70f).tooltip("@customize").visible(() -> state.rules.allowEditRules && (net.server() || !net.active()));
|
||||
})).grow().row();
|
||||
|
||||
shown(this::rebuild);
|
||||
shown(() -> {
|
||||
rebuild();
|
||||
|
||||
if(state.isCampaign()){
|
||||
state.getPlanet().saveStats();
|
||||
}
|
||||
});
|
||||
|
||||
addCloseListener();
|
||||
}
|
||||
|
||||
@@ -134,6 +134,7 @@ public class SettingsMenuDialog extends BaseDialog{
|
||||
t.button("@settings.clearcampaignsaves", Icon.trash, style, () -> {
|
||||
ui.showConfirm("@confirm", "@settings.clearcampaignsaves.confirm", () -> {
|
||||
for(var planet : content.planets()){
|
||||
planet.clearStats();
|
||||
for(var sec : planet.sectors){
|
||||
sec.clearInfo();
|
||||
if(sec.save != null){
|
||||
|
||||
Reference in New Issue
Block a user