From 05c9af07e6c8e9771be99c7983764d21b2bf01ed Mon Sep 17 00:00:00 2001 From: AlgorithmX2 Date: Sun, 31 Aug 2014 03:06:06 -0500 Subject: [PATCH] Added Crank Turns Stat Added Inserted Items Stat Added Extracted Items Stat Added Various Achivements --- block/grindstone/BlockCrank.java | 10 +- core/Registration.java | 3 + core/features/AEFeature.java | 2 +- core/stats/AchievementType.java | 8 ++ core/stats/Achievements.java | 141 ++++++++++++++++++++++++ core/stats/PlayerStatsRegistration.java | 140 +++++++++++++++++++++++ core/stats/Stats.java | 40 +++++++ core/sync/GuiBridge.java | 29 ++++- spatial/StorageHelper.java | 4 + tile/grindstone/TileCrank.java | 10 +- util/Platform.java | 20 ++++ 11 files changed, 401 insertions(+), 6 deletions(-) create mode 100644 core/stats/AchievementType.java create mode 100644 core/stats/Achievements.java create mode 100644 core/stats/PlayerStatsRegistration.java create mode 100644 core/stats/Stats.java diff --git a/block/grindstone/BlockCrank.java b/block/grindstone/BlockCrank.java index 50efb70d9..578a1338f 100644 --- a/block/grindstone/BlockCrank.java +++ b/block/grindstone/BlockCrank.java @@ -16,6 +16,7 @@ import appeng.block.AEBaseBlock; import appeng.client.render.BaseBlockRender; import appeng.client.render.blocks.RenderBlockCrank; import appeng.core.features.AEFeature; +import appeng.core.stats.Stats; import appeng.tile.AEBaseTile; import appeng.tile.grindstone.TileCrank; @@ -33,12 +34,17 @@ public class BlockCrank extends AEBaseBlock @Override public boolean onActivated(World w, int x, int y, int z, EntityPlayer p, int side, float hitX, float hitY, float hitZ) { - if ( p instanceof FakePlayer ) + if ( p instanceof FakePlayer || p == null ) return true; AEBaseTile tile = getTileEntity( w, x, y, z ); if ( tile instanceof TileCrank ) - ((TileCrank) tile).power(); + { + if ( ((TileCrank) tile).power() ) + { + Stats.TurnedCranks.addToPlayer( p, 1 ); + } + } return true; } diff --git a/core/Registration.java b/core/Registration.java index 63a391735..f2f84f918 100644 --- a/core/Registration.java +++ b/core/Registration.java @@ -90,6 +90,7 @@ import appeng.core.features.registries.entries.BasicCellHandler; import appeng.core.features.registries.entries.CreativeCellHandler; import appeng.core.localization.GuiText; import appeng.core.localization.PlayerMessages; +import appeng.core.stats.PlayerStatsRegistration; import appeng.debug.BlockChunkloader; import appeng.debug.BlockItemGen; import appeng.debug.BlockPhantomNode; @@ -570,6 +571,8 @@ public class Registration recipeHandler.injectRecipes(); + PlayerStatsRegistration.instance.init(); + if ( AEConfig.instance.isFeatureEnabled( AEFeature.enableDisassemblyCrafting ) ) CraftingManager.getInstance().getRecipeList().add( new DisassembleRecipe() ); diff --git a/core/features/AEFeature.java b/core/features/AEFeature.java index 9aa092c99..c251b38c0 100644 --- a/core/features/AEFeature.java +++ b/core/features/AEFeature.java @@ -54,7 +54,7 @@ public enum AEFeature enableDisassemblyCrafting("Crafting"), MolecularAssembler("CraftingFeatures"), MeteoriteCompass("Tools"), Patterns("CraftingFeatures"), - ChunkLoggerTrace("Commands", false); + ChunkLoggerTrace("Commands", false), Achievements("Misc"); String Category; boolean visible = true; diff --git a/core/stats/AchievementType.java b/core/stats/AchievementType.java new file mode 100644 index 000000000..aef76873f --- /dev/null +++ b/core/stats/AchievementType.java @@ -0,0 +1,8 @@ +package appeng.core.stats; + +public enum AchievementType +{ + + Craft, CraftItem, Pickup, Custom + +} diff --git a/core/stats/Achievements.java b/core/stats/Achievements.java new file mode 100644 index 000000000..71752b0dd --- /dev/null +++ b/core/stats/Achievements.java @@ -0,0 +1,141 @@ +package appeng.core.stats; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.stats.Achievement; +import appeng.api.AEApi; +import appeng.api.util.AEColor; +import appeng.api.util.AEColoredItemDefinition; +import appeng.api.util.AEItemDefinition; +import appeng.items.parts.ItemFacade; + +public enum Achievements +{ + + // done + Compass(-2, -4, AEApi.instance().blocks().blockSkyCompass, AchievementType.Craft), + + // done + Presses(-2, -2, AEApi.instance().materials().materialLogicProcessorPress, AchievementType.Custom), + + // done + SpatialIO(-4, -4, AEApi.instance().blocks().blockSpatialIOPort, AchievementType.Craft), + + // done + SpatialIOExplorerer(-4, -2, AEApi.instance().items().itemSpatialCell128, AchievementType.Custom), + + // done + StorageCell(-6, -4, AEApi.instance().items().itemCell64k, AchievementType.CraftItem), + + // done + IOPort(-6, -2, AEApi.instance().blocks().blockIOPort, AchievementType.Craft), + + // done + CraftingTerminal(-8, -4, AEApi.instance().parts().partCraftingTerminal, AchievementType.Craft), + + // done + PatternTerminal(-8, -2, AEApi.instance().parts().partPatternTerminal, AchievementType.Craft), + + // done + ChargedQuartz(0, -4, AEApi.instance().materials().materialCertusQuartzCrystalCharged, AchievementType.Pickup), + + // done + Fluix(0, -2, AEApi.instance().materials().materialFluixCrystal, AchievementType.Pickup), + + // done + Charger(0, 0, AEApi.instance().blocks().blockCharger, AchievementType.Craft), + + // done + CrystalGrowthAccelerator(-2, 0, AEApi.instance().blocks().blockQuartzGrowthAccelerator, AchievementType.Craft), + + // done + GlassCable(2, 0, AEApi.instance().parts().partCableGlass, AchievementType.Craft), + + // TODO: detect stuff + Networking1(4, -6, AEApi.instance().parts().partCableCovered, AchievementType.Custom), + + // done + Controller(4, -4, AEApi.instance().blocks().blockController, AchievementType.Craft), + + // TODO: detect stuff + Networking2(4, 0, AEApi.instance().parts().partCableSmart, AchievementType.Custom), + + // TODO: detect stuff + Networking3(4, 2, AEApi.instance().parts().partCableDense, AchievementType.Custom), + + // done + P2P(2, -2, AEApi.instance().parts().partP2PTunnelME, AchievementType.Craft), + + // TODO: detect stuff + Recursive(6, -2, AEApi.instance().blocks().blockInterface, AchievementType.Craft), + + // done + CraftingCPU(6, 0, AEApi.instance().blocks().blockCraftingStorage64k, AchievementType.CraftItem), + + // done + Facade(6, 2, ((ItemFacade) AEApi.instance().items().itemFacade.item()).createFacadeForItem( new ItemStack( Blocks.iron_block ), false ), + AchievementType.CraftItem), + + // done + NetworkTool(8, 0, AEApi.instance().items().itemNetworkTool, AchievementType.Craft), + + // done + PortableCell(8, 2, AEApi.instance().items().itemPortableCell, AchievementType.Craft), + + // done + StorageBus(10, 0, AEApi.instance().parts().partStorageBus, AchievementType.Craft), + + // done + QNB(10, 2, AEApi.instance().blocks().blockQuantumLink, AchievementType.Craft); + + public final ItemStack stack; + public final AchievementType type; + private final int x, y; + + private Achievement parent; + private Achievement stat; + + public void setParent(Achievements parent) + { + this.parent = parent.getAchivement(); + } + + public Achievement getAchivement() + { + if ( stat == null && stack != null ) + { + stat = new Achievement( "achievement.ae2." + name(), "ae2." + name(), x, y, stack, parent ); + stat.registerStat(); + } + + return stat; + } + + private Achievements(int x, int y, AEColoredItemDefinition which, AchievementType type) { + stack = which.stack( AEColor.Transparent, 1 ); + this.type = type; + this.x = x; + this.y = y; + } + + private Achievements(int x, int y, AEItemDefinition which, AchievementType type) { + stack = which.stack( 1 ); + this.type = type; + this.x = x; + this.y = y; + } + + private Achievements(int x, int y, ItemStack which, AchievementType type) { + stack = which; + this.type = type; + this.x = x; + this.y = y; + } + + public void addToPlayer(EntityPlayer player) + { + player.addStat( getAchivement(), 1 ); + } + +} diff --git a/core/stats/PlayerStatsRegistration.java b/core/stats/PlayerStatsRegistration.java new file mode 100644 index 000000000..ef1c0af91 --- /dev/null +++ b/core/stats/PlayerStatsRegistration.java @@ -0,0 +1,140 @@ +package appeng.core.stats; + +import java.util.ArrayList; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.stats.Achievement; +import net.minecraftforge.common.AchievementPage; +import net.minecraftforge.common.util.FakePlayer; +import appeng.core.AEConfig; +import appeng.core.features.AEFeature; +import appeng.util.Platform; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.PlayerEvent; + +public class PlayerStatsRegistration +{ + + public final static PlayerStatsRegistration instance = new PlayerStatsRegistration(); + + AchievementPage ae2AchievementPage; + + @SubscribeEvent + public void onCrafting(PlayerEvent.ItemCraftedEvent event) + { + if ( notPlayer( event.player ) || event.crafting == null ) + return; + + for (Achievements a : Achievements.values()) + { + switch (a.type) + { + case Craft: + if ( Platform.isSameItemPrecise( a.stack, event.crafting ) ) + { + a.addToPlayer( event.player ); + return; + } + break; + case CraftItem: + if ( a.stack.getItem().getClass() == event.crafting.getItem().getClass() ) + { + a.addToPlayer( event.player ); + return; + } + default: + } + } + } + + @SubscribeEvent + public void onCrafting(PlayerEvent.ItemPickupEvent event) + { + if ( notPlayer( event.player ) || event.pickedUp == null || event.pickedUp.getEntityItem() == null ) + return; + + ItemStack is = event.pickedUp.getEntityItem(); + + for (Achievements a : Achievements.values()) + { + switch (a.type) + { + case Pickup: + if ( Platform.isSameItemPrecise( a.stack, is ) ) + { + a.addToPlayer( event.player ); + return; + } + default: + } + } + } + + private boolean notPlayer(EntityPlayer player) + { + if ( player == null || player.isDead || player instanceof FakePlayer ) + return true; + return false; + } + + /** + * Assign Parents and hierarchy. + */ + private void initHierarchy() + { + Achievements.Presses.setParent( Achievements.Compass ); + + Achievements.Fluix.setParent( Achievements.ChargedQuartz ); + + Achievements.Charger.setParent( Achievements.Fluix ); + + Achievements.CrystalGrowthAccelerator.setParent( Achievements.Charger ); + + Achievements.GlassCable.setParent( Achievements.Charger ); + + Achievements.SpatialIOExplorerer.setParent( Achievements.SpatialIO ); + + Achievements.IOPort.setParent( Achievements.StorageCell ); + + Achievements.PatternTerminal.setParent( Achievements.CraftingTerminal ); + + Achievements.Controller.setParent( Achievements.Networking1 ); + + Achievements.Networking2.setParent( Achievements.Controller ); + + Achievements.Networking3.setParent( Achievements.Networking2 ); + + Achievements.P2P.setParent( Achievements.Controller ); + + Achievements.Recursive.setParent( Achievements.Controller ); + } + + public void init() + { + if ( AEConfig.instance.isFeatureEnabled( AEFeature.Achievements ) ) + { + FMLCommonHandler.instance().bus().register( this ); + initHierarchy(); + + for (Stats s : Stats.values()) + s.getStat(); + + /** + * register + */ + ArrayList list = new ArrayList(); + + for (Achievements a : Achievements.values()) + { + Achievement ach = a.getAchivement(); + if ( ach != null ) + list.add( ach ); + } + + ae2AchievementPage = new AchievementPage( "Applied Energistics 2", list.toArray( new Achievement[list.size()] ) ); + AchievementPage.registerAchievementPage( ae2AchievementPage ); + } + } +} diff --git a/core/stats/Stats.java b/core/stats/Stats.java new file mode 100644 index 000000000..29aee9728 --- /dev/null +++ b/core/stats/Stats.java @@ -0,0 +1,40 @@ +package appeng.core.stats; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.stats.StatBasic; +import net.minecraft.util.ChatComponentTranslation; + +public enum Stats +{ + + // done + ItemsInserted, + + // done + ItemsExtracted, + + // done + TurnedCranks; + + private StatBasic stat; + + public StatBasic getStat() + { + if ( stat == null ) + { + stat = new StatBasic( "stat.ae2." + name(), new ChatComponentTranslation( "stat.ae2." + name(), new Object[0] ) ); + stat.registerStat(); + } + + return stat; + } + + private Stats() { + } + + public void addToPlayer(EntityPlayer player, int howMany) + { + player.addStat( getStat(), howMany ); + } + +} diff --git a/core/sync/GuiBridge.java b/core/sync/GuiBridge.java index be61bb29a..a4985529b 100644 --- a/core/sync/GuiBridge.java +++ b/core/sync/GuiBridge.java @@ -8,12 +8,14 @@ import java.lang.reflect.Constructor; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import appeng.api.AEApi; import appeng.api.config.SecurityPermissions; +import appeng.api.definitions.Materials; import appeng.api.exceptions.AppEngException; import appeng.api.features.IWirelessTermHandler; import appeng.api.implementations.IUpgradeableHost; @@ -66,6 +68,7 @@ import appeng.container.implementations.ContainerUpgradeable; import appeng.container.implementations.ContainerVibrationChamber; import appeng.container.implementations.ContainerWireless; import appeng.container.implementations.ContainerWirelessTerm; +import appeng.core.stats.Achievements; import appeng.helpers.IInterfaceHost; import appeng.helpers.IPriorityHost; import appeng.helpers.WirelessTerminalGuiObject; @@ -234,7 +237,31 @@ public enum GuiBridge implements IGuiHandler throw new RuntimeException( "Cannot find " + Container.getName() + "( " + typeName( inventory ) + ", " + typeName( tE ) + " )" ); } - return target.newInstance( inventory, tE ); + Object o = target.newInstance( inventory, tE ); + + /** + * triggers achivemnet when the player sees presses. + */ + if ( o instanceof AEBaseContainer ) + { + AEBaseContainer bc = (AEBaseContainer) o; + for (Object so : bc.inventorySlots) + { + if ( so instanceof Slot ) + { + ItemStack is = ((Slot) so).getStack(); + + Materials m = AEApi.instance().materials(); + if ( m.materialLogicProcessorPress.sameAsStack( is ) || m.materialEngProcessorPress.sameAsStack( is ) + || m.materialCalcProcessorPress.sameAsStack( is ) || m.materialSiliconPress.sameAsStack( is ) ) + { + Achievements.Presses.addToPlayer( inventory.player ); + } + } + } + } + + return o; } catch (Throwable t) { diff --git a/spatial/StorageHelper.java b/spatial/StorageHelper.java index 128137945..26ddd807e 100644 --- a/spatial/StorageHelper.java +++ b/spatial/StorageHelper.java @@ -16,6 +16,7 @@ import net.minecraft.world.WorldServer; import appeng.api.AEApi; import appeng.api.util.WorldCoord; import appeng.block.spatial.BlockMatrixFrame; +import appeng.core.stats.Achievements; import appeng.util.Platform; public class StorageHelper @@ -180,6 +181,9 @@ public class StorageHelper { if ( player != null ) { + if ( link.dim.provider instanceof StorageWorldProvider ) + Achievements.SpatialIOExplorerer.addToPlayer( player ); + player.mcServer.getConfigurationManager().transferPlayerToDimension( player, link.dim.provider.dimensionId, new METeleporter( newWorld, link ) ); } else diff --git a/tile/grindstone/TileCrank.java b/tile/grindstone/TileCrank.java index cb53ef575..58d81a1bc 100644 --- a/tile/grindstone/TileCrank.java +++ b/tile/grindstone/TileCrank.java @@ -80,10 +80,13 @@ public class TileCrank extends AEBaseTile implements ICustomCollision getBlockType().onNeighborBlockChange( worldObj, xCoord, yCoord, zCoord, Platform.air ); } - public void power() + /** + * return true if this should count towards stats. + */ + public boolean power() { if ( Platform.isClient() ) - return; + return false; if ( rotation < 3 ) { @@ -95,6 +98,7 @@ public class TileCrank extends AEBaseTile implements ICustomCollision hits = 0; rotation += ticksPerRoation; this.markForUpdate(); + return true; } else { @@ -107,6 +111,8 @@ public class TileCrank extends AEBaseTile implements ICustomCollision } } } + + return false; } @Override diff --git a/util/Platform.java b/util/Platform.java index 64a7c8cbb..f5876445c 100644 --- a/util/Platform.java +++ b/util/Platform.java @@ -92,6 +92,7 @@ import appeng.core.AEConfig; import appeng.core.AELog; import appeng.core.AppEng; import appeng.core.features.AEFeature; +import appeng.core.stats.Stats; import appeng.core.sync.GuiBridge; import appeng.core.sync.GuiHostType; import appeng.hooks.TickHandler; @@ -1337,6 +1338,11 @@ public class Platform possible.setStackSize( itemToExtract ); StackType ret = cell.extractItems( possible, Actionable.MODULATE, src ); + if ( ret != null && src.isPlayer() ) + { + Stats.ItemsExtracted.addToPlayer( ((PlayerSource) src).player, (int) ret.getStackSize() ); + } + return ret; } @@ -1361,15 +1367,29 @@ public class Platform if ( itemToAdd < input.getStackSize() ) { + long original = input.getStackSize(); StackType split = (StackType) input.copy(); split.decStackSize( itemToAdd ); input.setStackSize( itemToAdd ); split.add( cell.injectItems( input, Actionable.MODULATE, src ) ); + + if ( src.isPlayer() ) + { + long diff = original - split.getStackSize(); + Stats.ItemsInserted.addToPlayer( ((PlayerSource) src).player, (int) diff ); + } + return split; } StackType ret = cell.injectItems( input, Actionable.MODULATE, src ); + if ( src.isPlayer() ) + { + long diff = ret == null ? input.getStackSize() : input.getStackSize() - ret.getStackSize(); + Stats.ItemsInserted.addToPlayer( ((PlayerSource) src).player, (int) diff ); + } + return ret; }