From 6bcc103cf7093a6d513937d26a9164371192de6c Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 19 Jun 2020 19:31:14 -0400 Subject: [PATCH] Research system progress --- .../blocks/campaign/data-processor-top.png | Bin 0 -> 1471 bytes .../blocks/campaign/data-processor.png | Bin 2128 -> 2204 bytes core/assets/bundles/bundle.properties | 1 - core/src/mindustry/Vars.java | 4 +- core/src/mindustry/content/Blocks.java | 1 + core/src/mindustry/content/TechTree.java | 27 ++- core/src/mindustry/core/Control.java | 3 - core/src/mindustry/core/Logic.java | 13 +- .../mindustry/ctype/UnlockableContent.java | 17 +- core/src/mindustry/editor/MapRenderer.java | 30 +-- .../src/mindustry/entities/comp/TileComp.java | 12 -- core/src/mindustry/game/CampaignData.java | 47 +++++ core/src/mindustry/game/GlobalData.java | 183 ------------------ core/src/mindustry/game/Schematics.java | 2 +- core/src/mindustry/game/Universe.java | 6 +- core/src/mindustry/input/DesktopInput.java | 2 +- core/src/mindustry/input/InputHandler.java | 2 +- core/src/mindustry/io/SaveVersion.java | 6 + core/src/mindustry/io/TypeIO.java | 8 + core/src/mindustry/maps/Map.java | 1 - core/src/mindustry/type/SectorPreset.java | 6 +- core/src/mindustry/type/Weather.java | 2 +- core/src/mindustry/ui/ItemsDisplay.java | 9 +- .../mindustry/ui/dialogs/LanguageDialog.java | 2 +- .../mindustry/ui/dialogs/PausedDialog.java | 11 +- .../mindustry/ui/dialogs/ResourcesDialog.java | 14 +- .../ui/dialogs/SettingsMenuDialog.java | 50 ++++- .../mindustry/ui/dialogs/TechTreeDialog.java | 44 +++-- .../ui/fragments/PlacementFragment.java | 2 +- core/src/mindustry/world/Block.java | 6 +- .../mindustry/world/blocks/ItemSelection.java | 2 +- .../world/blocks/campaign/LaunchPad.java | 3 +- .../world/blocks/campaign/ResearchBlock.java | 150 ++++++++++---- .../mindustry/world/blocks/defense/Door.java | 11 +- .../blocks/defense/turrets/ItemTurret.java | 2 +- .../world/blocks/distribution/ItemBridge.java | 4 +- .../world/blocks/distribution/MassDriver.java | 4 +- .../world/blocks/distribution/Sorter.java | 4 +- .../world/blocks/experimental/BlockForge.java | 12 +- .../world/blocks/power/ImpactReactor.java | 4 +- .../world/blocks/power/LightBlock.java | 2 +- .../world/blocks/power/NuclearReactor.java | 2 +- .../world/blocks/power/PowerGenerator.java | 4 +- .../world/blocks/production/Cultivator.java | 6 +- .../world/blocks/production/Drill.java | 8 +- .../blocks/production/GenericCrafter.java | 2 - .../blocks/production/LiquidConverter.java | 1 - .../world/blocks/production/Pump.java | 6 - .../world/blocks/production/SolidPump.java | 7 +- .../world/blocks/sandbox/ItemSource.java | 4 +- .../world/blocks/sandbox/LiquidSource.java | 4 +- .../world/blocks/storage/CoreBlock.java | 6 +- .../world/blocks/storage/MessageBlock.java | 8 +- .../world/blocks/storage/Unloader.java | 8 +- .../world/blocks/units/Reconstructor.java | 2 +- .../world/blocks/units/UnitFactory.java | 18 +- .../world/consumers/ConsumeItemDynamic.java | 7 +- .../world/consumers/ConsumeItemFilter.java | 2 +- core/src/mindustry/world/meta/BlockBars.java | 4 +- 59 files changed, 393 insertions(+), 415 deletions(-) create mode 100644 core/assets-raw/sprites/blocks/campaign/data-processor-top.png create mode 100644 core/src/mindustry/game/CampaignData.java delete mode 100644 core/src/mindustry/game/GlobalData.java diff --git a/core/assets-raw/sprites/blocks/campaign/data-processor-top.png b/core/assets-raw/sprites/blocks/campaign/data-processor-top.png new file mode 100644 index 0000000000000000000000000000000000000000..259622195005fd5bc91052af6f36200c89ee4b4a GIT binary patch literal 1471 zcmV;w1wi_VP)Px)c}YY;RCt{2T|IW&FbszL{9dPy&DI;lV=s}b_yXSawB-W1iZ7ATzCky4?9_=J z@~F@h3I2fquZ z9nmg=R`OH7E4q?2oJh!qcJi^`uc|ATLYuGI0@N5Pwb8>?FS|X*t)2aFosQ-@9Zl*7 zC7`fTV@s;t92@2`8dscs$wtZL{D4V$Orf&IuxGF zWi-3xPd;#+j^_6M7ykVI*Tu0%M9unS_dLF#gt{VZf=2QIgaiPP zJK+!{eF^4*xS&AH!v;2>s!w zCl)JV$#9elZQ&#rq1;e#7Nof+V7c|$;ynjqzM%z~e(uyEhhU8&U_LEEkPBagr(fSc zKQm9?N{BU=(Qwx<+=X6Ah^$_SaVF1du4>Mn(85KsB-yKB3Jiy7kgn9Va4;OEVGn>; z!*U#G2}ivuQXK8Hk`Lg7pf&dd2~dy^kWrH4aA<9yA|IflB#AYCJD<$${cq9cM|!vS?A$s9sBkLd|FQMkwf z^$bTLk#iSirKIJCqtN23XM)eq(k=$!UOl13Zp{_ja+UW=Ws8+0xyh&aEwu<@B}pmr zDQr-QfbJg#$S0{ZiPn;sqaG+@V**72uEr)n!5%Sg^q8ec&wPB?f&R{^R8OGj0oug& z5egU7Js?_;*}#ukiJWnOYYgZWE<)pg)EIDA6P8{D`;ge6!HxN8S{V5h@w#PPq3Q`3 z`6cnX7U-i2V*j8TETs$mlm+x2c7g&>&s3yD&_I65-a>$0(?o6&G?9B z8MW?+vMAoMWl%a3Gk9sD*nnJ?@MP+VH{%1)-&jGKx^voQjaT zlI}!T;6p8%1d#5=8qmst`W-S-6|oXD?U3PaumsW-u@cmBQY^rl$nRkbLk%~ReuoS|U9O5VztzG8`m6})B%OOlSaSAOOlkpeADcAOav9rjxGg7I$HvvC#sV@s$fGNqATHzd_K4$%#W*)a)v9M zXbW3595p?#sTCRuI+8xj`vWAPfqV-|Uql3uxNk?py9+{K7eMl+DUBkq3ZUVRHEklW z37~=e+_pGHNR}iyW=Rrh?Upoh2~uy?PL?El=iDW03ccHoy};A`d+q@k(G-ugp{z)0 zwdEr9kn!R@Vj8MXYr%Con$*TV^nJpZ;YQyc9`n1H1Fr)1ftDm=A!idI4xbw<0$Py4 zUf@YJ1ELfyHCA!7Qvy5C$6oBY*r4Hlrf`Cr6m257He3;c5AR+(`O@v?*zg~@UmWLi z!%~jpl(u@?r?3^WQIv|%ctV&R%G+3a-4c`SyhieCkF9C1)mH3xs4;6q!wKZr&?*9U Z{C}s`ZqB|$gC76@002ovPDHLkV1oT9xyk?l literal 0 HcmV?d00001 diff --git a/core/assets-raw/sprites/blocks/campaign/data-processor.png b/core/assets-raw/sprites/blocks/campaign/data-processor.png index 2cd1ca547cca174ac31812917712ed305e271119..92bbec25283d98eb22d4661298429b6b637e22d2 100644 GIT binary patch delta 2178 zcmV-|2z~d^5S$T^F@IJ`L_t(|ob6pdYg|VVpF0G0<3hy=ADqF3(+IhAk>J8=Ogb5V z2&FI>e*;O74-f(=q7PxBF1S&uxNzy?ny3)u;DoPG;U)pYr8w`?-rmgY%4w_0Z(-|fwhu3!KU?9v z?|*px=6G>+Ib{ozk|C+ErLEL!+9V%f`GEV!8v({AuNH^fbC^snASQwo7B*6Bbycp! z#=-D>#bx#ZmVe~C1Dh^F?c_T+5&Ay)4o-yczWknDfv^%KZPi9Tzzyk`ds=)vT5M4l z9&XR!(}(5%2M_L`6}!5eMk{dt;Yd``+hFT#wvQ6c^$q>g>j7*0(}&M6|NGyj08PcD z=iMe-+P{v?(kF9mW6ydwOk8M|3>{Dfy zLf8^G^x1E}LQ6h2!iW*vW=n{bh1FF$YI2bFAyENR$*)y}9P&$uAZh_pgcYn!1dAtM zD?$ur0)J2yt3?D$w__=Si2!cx2m^Jz?M{~iRTs{MSc%Z5#{N=FCKt`WVTEHpum%xg zbtoyq!SH-J3_aYQCyn2tf6V6SR;J+_ngk>$p0R5ix+k9nI#j^W&Gxumnk^@#S=dLW>5x{b(*YZh^0TUsI{Il8q z(gktRuo$#!`Jp=^BT}q$)T2Z>x#RhnG_BmRKaEIB|x(e#XbL?2YE$xG|doVm-wt(EYa0+~(G=EPL zcW$a3>v)9(*&#^_XhkS-PM72Z1QW5;;Jg%=$UCEdMAvGc?%0IU0SnfbT;MYeNotT| zH>I=7=^(9_vN^liA;}O}r`Jvl@aLQdY(tkHJdXGI-sa;?g$C2-`&o>n(2E;S4#`v42_Lpxe@9TD@FB!6-?=y6LM zr~p>vWA?P@Dk6rFRzid|0ZJ{#wJm}*`4+(JuB?WZPD_B<-<`?=GnzN>G&>@(txzQq z=8!OXGcFa{s91?}EZ@MBV(rbiO(0)#ZmOLwMd-bLbIi^GB%QE-GdT-z8iel1V#K7K zlu2A-tmDpJis)*B*tV2Z3$#VYN$3sL&l*;WpR``Eu^<&#mw2WF1(V0!Oe_ zfWtCy9_y>xC`W@I-`ypD9v;mV;gfDriMC0pO$7Jz@Oz;MD;u=|mLhCA`CXUG+3-am zb4C38({V3WsMIY?{ra6cW0Lcqqb*Ha)m1^KcT>RH1NR%; zU8yn@!j&QmjMdi7bsMdY+;0v~#sOGKh?S099M9%O?SI!!J600HW4%V0B7A@UO>W*u z9M9%()*ckIPo-H3VM*XHVSoJ(TJo_TMvUN^B_Wm;mRD)7$wAtNL@=# z4>KIA1AoULLM#s@Md*A%CtJ&;{=OqW{Jyg{BQqXmdb;~3e%@yP=A=Cfj2LM;SQ>t} z5=%=vY6kGUq3(dTB!uMq$EDX9=kYIphNny&zu%s;Y5tq<@!mRruh1>)L>L3^5U6&F@T^tS}bAv?W^u z1HDysi1)feBoD;6ktJ4Qa!NwVQ(dbh0OXC_qajHSSi)R&Wmz2otX#d8PkIcP2sz}R zFMkeKRS*{qi$Uwl533_GBE?pYdXz{fmwW)P3bHN<99&7TjLC8+k&XrV0D_QYjSNw+ z5W#ZxgM$_M0NRjb%O`$3o5Q=sw`e9-y(!sE++4S?yvM7Ln|4K9>~{{`{oKz*gE=ZK zhqLwopq2Od)FH`Q9!$#;RV&=-b5k@VxqnU~3_-p_(U9aih%hAiQe;KM#t={$8o3-~ zha`s*!B2M#c}T^^{PX(g8Ym|bmELEU(c9n0C$J~+EayBGZh8nxgHrFoLL zb5reD$15br4oO--D?*8Lh9n;#7>K0?=cT|z-k$v}x>oyi#|DfJSg^jNgU>W1seeI^ z-IT^Ir-8I~Wpj43Ly{q|M!Poo7T02Aj(^dKe4 z4@pXJdnt9y^VvOa~hWlz*x&uy%l&v|AGXw3)$N5gdkCpivvHs@s@z%bW#z?4EJhK`Zhxds++? z5yMC;Awo}pQe%SJB3P4e0nF|bZ)oWO8D`%f2gE#>(l$Y}A`)8)RTAMI5`QK$<5HoG zij_FWat59hy@A*|kS{qm)y|M2Y<&3miR^{~$Qoh)W^x>G8idu6MUP4An3GhAv4%U_ z6*1HR$4_?*c}PW;0Am|n4uM<_imZ^a#84424YF3q#7@8lR_j2%r40!%P9y_2Q3>!x zSSRvJ*y7-GBONvO)(4QzvwvWfB!;v002;~WeqSDYS201G=89Z%;L_rLkM-i5I6HeY zfCYOh0Ib#=#Ja-VD#>s(oV-;*2<=lQ3G{0x1C+86!g98S$;`Oa48>MdS|OHB%IZxk z5xVVaQjuG~(gU}bS$4JQq%0B~6 z7_3C#?37N!Vk1{_B!8?ezTC~053T7cm*GrNZbnAw#u^f=Gr>hTEc0w`g{(|IKaPvf;2M{!Ypm2 zUL(nag)P4%_)t0H#zy|>-86dB64Vj_pzq3#&Wey4b}y(&zQo>GMDUOKB8cV%jhTFj g-JwOm>^c$t1$(&Om2k!G6#xJL07*qoM6N<$f;QXajsO4v diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index bae4a739b0..541b0d509c 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -582,7 +582,6 @@ blocks.shots = Shots blocks.reload = Shots/Second blocks.ammo = Ammo -bar.corereq = Core Required bar.drilltierreq = Better Drill Required bar.drillspeed = Drill Speed: {0}/s bar.pumpspeed = Pump Speed: {0}/s diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index f35264ef00..3ab9fb3f87 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -170,7 +170,7 @@ public class Vars implements Loadable{ public static Net net; public static ContentLoader content; public static GameState state; - public static GlobalData data; + public static CampaignData data; public static EntityCollisions collisions; public static DefaultWaves defaultWaves; public static mindustry.audio.LoopControl loops; @@ -256,7 +256,7 @@ public class Vars implements Loadable{ bases = new BaseRegistry(); state = new GameState(); - data = new GlobalData(); + data = new CampaignData(); mobile = Core.app.isMobile() || testMobile; ios = Core.app.isIOS(); diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 5e04a2b514..425477539f 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1848,6 +1848,7 @@ public class Blocks implements ContentList{ requirements(Category.effect, BuildVisibility.campaignOnly, ItemStack.with(Items.copper, 200, Items.lead, 100)); size = 3; + alwaysUnlocked = true; }}; //endregion campaign diff --git a/core/src/mindustry/content/TechTree.java b/core/src/mindustry/content/TechTree.java index 45645a5b44..2a4de32157 100644 --- a/core/src/mindustry/content/TechTree.java +++ b/core/src/mindustry/content/TechTree.java @@ -1,5 +1,6 @@ package mindustry.content; +import arc.*; import arc.math.*; import arc.struct.*; import arc.util.ArcAnnotate.*; @@ -11,12 +12,15 @@ import mindustry.world.*; import static mindustry.content.Blocks.*; public class TechTree implements ContentList{ + private static ObjectMap map = new ObjectMap<>(); + public static Seq all; public static TechNode root; @Override public void load(){ TechNode.context = null; + map = new ObjectMap<>(); all = new Seq<>(); root = node(coreShard, () -> { @@ -312,6 +316,14 @@ public class TechTree implements ContentList{ return node(block, () -> {}); } + public static @Nullable TechNode get(UnlockableContent content){ + return map.get(content); + } + + public static TechNode getNotNull(UnlockableContent content){ + return map.getThrow(content, () -> new RuntimeException(content + " does not have a tech node")); + } + public static class TechNode{ private static TechNode context; @@ -325,12 +337,14 @@ public class TechTree implements ContentList{ public ItemStack[] requirements; /** Extra objectives needed to research this. TODO implement */ public Objective[] objectives = {}; - /** Research turns required to research this content. */ - public int turns = 3; //TODO keep track of turns that have been used so far + /** Time required to research this content, in seconds. */ + public float time = 60; //TODO implement /** Nodes that depend on this node. */ public final Seq children = new Seq<>(); + /** Research progress, in seconds. */ + public float progress; - TechNode(TechNode ccontext, UnlockableContent content, ItemStack[] requirements, Runnable children){ + TechNode(@Nullable TechNode ccontext, UnlockableContent content, ItemStack[] requirements, Runnable children){ if(ccontext != null){ ccontext.children.add(this); } @@ -339,7 +353,9 @@ public class TechTree implements ContentList{ this.content = content; this.requirements = requirements; this.depth = parent == null ? 0 : parent.depth + 1; + this.progress = Core.settings.getFloat("research-" + content.name, 0f); + map.put(content, this); context = this; children.run(); context = ccontext; @@ -349,5 +365,10 @@ public class TechTree implements ContentList{ TechNode(UnlockableContent content, ItemStack[] requirements, Runnable children){ this(context, content, requirements, children); } + + /** Flushes research progress to settings. */ + public void save(){ + Core.settings.put("research-" + content.name, progress); + } } } diff --git a/core/src/mindustry/core/Control.java b/core/src/mindustry/core/Control.java index 4b86a0310e..6fb4701eb5 100644 --- a/core/src/mindustry/core/Control.java +++ b/core/src/mindustry/core/Control.java @@ -459,9 +459,6 @@ public class Control implements ApplicationListener, Loadable{ input.updateState(); - //autosave global data if it's modified - data.checkSave(); - music.update(); loops.update(); Time.updateGlobal(); diff --git a/core/src/mindustry/core/Logic.java b/core/src/mindustry/core/Logic.java index b03b7cece3..fc10df0b9b 100644 --- a/core/src/mindustry/core/Logic.java +++ b/core/src/mindustry/core/Logic.java @@ -6,7 +6,6 @@ import arc.util.*; import mindustry.annotations.Annotations.*; import mindustry.content.*; import mindustry.core.GameState.*; -import mindustry.ctype.*; import mindustry.game.EventType.*; import mindustry.game.*; import mindustry.game.Teams.*; @@ -114,13 +113,6 @@ public class Logic implements ApplicationListener{ } - /** Handles the event of content being used by either the player or some block. */ - public void handleContent(UnlockableContent content){ - if(!headless){ - data.unlockContent(content); - } - } - /** Adds starting items, resets wave time, and sets state to playing. */ public void play(){ state.set(State.playing); @@ -251,8 +243,9 @@ public class Logic implements ApplicationListener{ Time.runTask(30f, () -> { for(Tilec entity : state.teams.playerCores()){ for(Item item : content.items()){ - data.addItem(item, entity.items().get(item)); - Events.fire(new LaunchItemEvent(new ItemStack(item, entity.items().get(item)))); + //TODO where do the items go? + //data.addItem(item, entity.items().get(item)); + //Events.fire(new LaunchItemEvent(new ItemStack(item, entity.items().get(item)))); } entity.tile().remove(); } diff --git a/core/src/mindustry/ctype/UnlockableContent.java b/core/src/mindustry/ctype/UnlockableContent.java index 01881c8b64..9e91023172 100644 --- a/core/src/mindustry/ctype/UnlockableContent.java +++ b/core/src/mindustry/ctype/UnlockableContent.java @@ -1,13 +1,14 @@ package mindustry.ctype; import arc.*; -import arc.util.ArcAnnotate.*; -import mindustry.annotations.Annotations.*; import arc.graphics.g2d.*; import arc.scene.ui.layout.*; -import mindustry.*; +import arc.util.ArcAnnotate.*; +import mindustry.annotations.Annotations.*; import mindustry.graphics.*; -import mindustry.ui.Cicon; +import mindustry.ui.*; + +import static mindustry.Vars.*; /** Base interface for an unlockable content type. */ public abstract class UnlockableContent extends MappableContent{ @@ -63,12 +64,12 @@ public abstract class UnlockableContent extends MappableContent{ } public final boolean unlocked(){ - return Vars.data.isUnlocked(this); + return data.isUnlocked(this); } - /** @return whether this content is unlocked, or the player is in a custom game. */ - public final boolean unlockedCur(){ - return Vars.data.isUnlocked(this) || !Vars.state.isCampaign(); + /** @return whether this content is unlocked, or the player is in a custom (non-campaign) game. */ + public final boolean unlockedNow(){ + return data.isUnlocked(this) || !state.isCampaign(); } public final boolean locked(){ diff --git a/core/src/mindustry/editor/MapRenderer.java b/core/src/mindustry/editor/MapRenderer.java index 4dcfacae58..4cf969a5dd 100644 --- a/core/src/mindustry/editor/MapRenderer.java +++ b/core/src/mindustry/editor/MapRenderer.java @@ -1,22 +1,18 @@ package mindustry.editor; import arc.*; -import arc.struct.IntSet; -import arc.struct.IntSet.IntSetIterator; -import arc.graphics.Color; -import arc.graphics.Texture; -import arc.graphics.g2d.Draw; -import arc.graphics.g2d.TextureRegion; -import arc.math.Mathf; +import arc.graphics.*; +import arc.graphics.g2d.*; +import arc.math.*; +import arc.struct.*; import arc.util.*; -import mindustry.content.Blocks; +import mindustry.content.*; import mindustry.game.EventType.*; -import mindustry.game.Team; -import mindustry.graphics.IndexedRenderer; -import mindustry.world.Block; -import mindustry.world.Tile; +import mindustry.game.*; +import mindustry.graphics.*; +import mindustry.world.*; -import static mindustry.Vars.tilesize; +import static mindustry.Vars.*; public class MapRenderer implements Disposable{ private static final int chunkSize = 64; @@ -62,13 +58,7 @@ public class MapRenderer implements Disposable{ public void draw(float tx, float ty, float tw, float th){ Draw.flush(); - IntSetIterator it = updates.iterator(); - while(it.hasNext){ - int i = it.next(); - int x = i % width; - int y = i / width; - render(x, y); - } + updates.each(i -> render(i % width, i / width)); updates.clear(); updates.addAll(delayedUpdates); diff --git a/core/src/mindustry/entities/comp/TileComp.java b/core/src/mindustry/entities/comp/TileComp.java index e540a1a9db..51bcdf8710 100644 --- a/core/src/mindustry/entities/comp/TileComp.java +++ b/core/src/mindustry/entities/comp/TileComp.java @@ -18,7 +18,6 @@ import arc.util.io.*; import mindustry.annotations.Annotations.*; import mindustry.audio.*; import mindustry.content.*; -import mindustry.ctype.*; import mindustry.entities.*; import mindustry.game.EventType.*; import mindustry.game.*; @@ -552,8 +551,6 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree public void offload(Item item){ int dump = this.dump; - useContent(item); - for(int i = 0; i < proximity.size; i++){ incrementDump(proximity.size); Tilec other = proximity.get((i + dump) % proximity.size); @@ -571,7 +568,6 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree */ public boolean put(Item item){ int dump = this.dump; - useContent(item); for(int i = 0; i < proximity.size; i++){ incrementDump(proximity.size); @@ -814,14 +810,6 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree public void unitRemoved(Unitc unit){ } - /** Call when some content is produced. This unlocks the content if it is applicable. */ - public void useContent(UnlockableContent content){ - //only unlocks content in zones - if(!headless && team() == player.team() && state.isCampaign()){ - logic.handleContent(content); - } - } - /** Called when arbitrary configuration is applied to a tile. */ public void configured(@Nullable Playerc player, @Nullable Object value){ //null is of type void.class; anonymous classes use their superclass. diff --git a/core/src/mindustry/game/CampaignData.java b/core/src/mindustry/game/CampaignData.java new file mode 100644 index 0000000000..2620fe8117 --- /dev/null +++ b/core/src/mindustry/game/CampaignData.java @@ -0,0 +1,47 @@ +package mindustry.game; + +import arc.*; +import arc.struct.*; +import mindustry.ctype.*; +import mindustry.game.EventType.*; + +/** Stores unlocks and tech tree state. */ +public class CampaignData{ + private ObjectSet unlocked = new ObjectSet<>(); + + /** @return whether or not this piece of content is unlocked yet. */ + public boolean isUnlocked(UnlockableContent content){ + return content.alwaysUnlocked || unlocked.contains(content.name); + } + + /** + * Makes this piece of content 'unlocked', if possible. + * If this piece of content is already unlocked, nothing changes. + */ + public void unlockContent(UnlockableContent content){ + if(content.alwaysUnlocked) return; + + //fire unlock event so other classes can use it + if(unlocked.add(content.name)){ + content.onUnlock(); + Events.fire(new UnlockEvent(content)); + + save(); + } + } + + /** Clears all unlocked content. Automatically saves. */ + public void reset(){ + save(); + } + + @SuppressWarnings("unchecked") + public void load(){ + unlocked = Core.settings.getJson("unlocked-content", ObjectSet.class, ObjectSet::new); + } + + public void save(){ + Core.settings.putJson("unlocked-content", String.class, unlocked); + } + +} diff --git a/core/src/mindustry/game/GlobalData.java b/core/src/mindustry/game/GlobalData.java deleted file mode 100644 index eec634226d..0000000000 --- a/core/src/mindustry/game/GlobalData.java +++ /dev/null @@ -1,183 +0,0 @@ -package mindustry.game; - -import arc.*; -import arc.files.*; -import arc.math.*; -import arc.struct.*; -import arc.util.io.*; -import mindustry.*; -import mindustry.content.*; -import mindustry.ctype.*; -import mindustry.game.EventType.*; -import mindustry.type.*; - -import java.io.*; -import java.util.zip.*; - -import static mindustry.Vars.*; - -/** Stores player unlocks. Clientside only. */ -public class GlobalData{ - private ObjectSet unlocked = new ObjectSet<>(); - private ObjectIntMap items = new ObjectIntMap<>(); - private boolean modified; - - public void exportData(Fi file) throws IOException{ - Seq files = new Seq<>(); - files.add(Core.settings.getSettingsFile()); - files.addAll(customMapDirectory.list()); - files.addAll(saveDirectory.list()); - files.addAll(screenshotDirectory.list()); - files.addAll(modDirectory.list()); - files.addAll(schematicDirectory.list()); - String base = Core.settings.getDataDirectory().path(); - - try(OutputStream fos = file.write(false, 2048); ZipOutputStream zos = new ZipOutputStream(fos)){ - for(Fi add : files){ - if(add.isDirectory()) continue; - zos.putNextEntry(new ZipEntry(add.path().substring(base.length()))); - Streams.copy(add.read(), zos); - zos.closeEntry(); - } - } - } - - public void importData(Fi file){ - Fi dest = Core.files.local("zipdata.zip"); - file.copyTo(dest); - Fi zipped = new ZipFi(dest); - - Fi base = Core.settings.getDataDirectory(); - if(!zipped.child("settings.bin").exists()){ - throw new IllegalArgumentException("Not valid save data."); - } - - //purge existing tmp data, keep everything else - tmpDirectory.deleteDirectory(); - - zipped.walk(f -> f.copyTo(base.child(f.path()))); - dest.delete(); - } - - public void modified(){ - modified = true; - } - - public int getItem(Item item){ - return items.get(item, 0); - } - - public void addItem(Item item, int amount){ - if(amount > 0){ - unlockContent(item); - } - amount = Math.max(amount, 0); - - items.getAndIncrement(item, 0, amount); - state.stats.itemsDelivered.getAndIncrement(item, 0, amount); - - //clamp to capacity - items.put(item, Mathf.clamp(items.get(item), 0, getItemCapacity())); - - //clamp overflow - if(state.stats.itemsDelivered.get(item, 0) < 0) state.stats.itemsDelivered.put(item, Integer.MAX_VALUE); - - modified = true; - } - - public boolean hasItems(Seq stacks){ - return !stacks.contains(s -> items.get(s.item, 0) < s.amount); - } - - public boolean hasItems(ItemStack[] stacks){ - for(ItemStack stack : stacks){ - if(!has(stack.item, stack.amount)){ - return false; - } - } - - return true; - } - - public void removeItems(ItemStack[] stacks){ - for(ItemStack stack : stacks){ - remove(stack.item, stack.amount); - } - } - - public void removeItems(Seq stacks){ - for(ItemStack stack : stacks){ - remove(stack.item, stack.amount); - } - } - - public void remove(Item item, int amount){ - items.getAndIncrement(item, 0, -amount); - - modified = true; - } - - public boolean has(Item item, int amount){ - return items.get(item, 0) >= amount; - } - - //TODO: make it upgradeable - public int getItemCapacity(){ - return 10000; - } - - /** Returns whether or not this piece of content is unlocked yet. */ - public boolean isUnlocked(UnlockableContent content){ - return content.alwaysUnlocked || unlocked.contains(content.name); - } - - /** - * Makes this piece of content 'unlocked', if possible. - * If this piece of content is already unlocked, nothing changes. - * Results are not saved until you call {@link #save()}. - */ - public void unlockContent(UnlockableContent content){ - if(content.alwaysUnlocked) return; - - //fire unlock event so other classes can use it - if(unlocked.add(content.name)){ - modified = true; - content.onUnlock(); - Events.fire(new UnlockEvent(content)); - } - } - - /** Clears all unlocked content. Automatically saves. */ - public void reset(){ - save(); - } - - public void checkSave(){ - if(modified){ - save(); - modified = false; - } - } - - @SuppressWarnings("unchecked") - public void load(){ - items.clear(); - unlocked = Core.settings.getJson("unlocked-content", ObjectSet.class, ObjectSet::new); - for(Item item : Vars.content.items()){ - items.put(item, Core.settings.getInt("item-" + item.name, 0)); - } - - //set up default values - if(!Core.settings.has("item-" + Items.copper.name)){ - addItem(Items.copper, 50); - } - } - - public void save(){ - Core.settings.putJson("unlocked-content", String.class, unlocked); - for(Item item : Vars.content.items()){ - Core.settings.put("item-" + item.name, items.get(item, 0)); - } - } - -} diff --git a/core/src/mindustry/game/Schematics.java b/core/src/mindustry/game/Schematics.java index f05b189c9c..15aa953a20 100644 --- a/core/src/mindustry/game/Schematics.java +++ b/core/src/mindustry/game/Schematics.java @@ -278,7 +278,7 @@ public class Schematics implements Loadable{ /** Creates an array of build requests from a schematic's data, centered on the provided x+y coordinates. */ public Seq toRequests(Schematic schem, int x, int y){ return schem.tiles.map(t -> new BuildPlan(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block).original(t.x, t.y, schem.width, schem.height).configure(t.config)) - .removeAll(s -> !s.block.isVisible() || !s.block.unlockedCur()); + .removeAll(s -> !s.block.isVisible() || !s.block.unlockedNow()); } /** Adds a schematic to the list, also copying it into the files.*/ diff --git a/core/src/mindustry/game/Universe.java b/core/src/mindustry/game/Universe.java index ce5a2813db..cc80129b5e 100644 --- a/core/src/mindustry/game/Universe.java +++ b/core/src/mindustry/game/Universe.java @@ -24,6 +24,7 @@ public class Universe{ load(); } + /** Update regardless of whether the player is in the campaign. */ public void updateGlobal(){ //currently only updates one solar system updatePlanet(Planets.sun); @@ -40,6 +41,7 @@ public class Universe{ } } + /** Update planet rotations, global time and relevant state. */ public void update(){ secondCounter += Time.delta() / 60f; @@ -119,9 +121,11 @@ public class Universe{ } //calculate passive item generation + //TODO make exports only update for sector with items + //TODO items should be added directly to cores! int[] exports = getTotalExports(); for(int i = 0; i < exports.length; i++){ - data.addItem(content.item(i), exports[i]); + //data.addItem(content.item(i), exports[i]); } Events.fire(new TurnEvent()); diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 566188e2ec..e61390a48d 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -180,7 +180,7 @@ public class DesktopInput extends InputHandler{ } if((player.dead() || state.isPaused()) && !ui.chatfrag.shown()){ - if(!(scene.getKeyboardFocus() instanceof TextField)){ + if(!(scene.getKeyboardFocus() instanceof TextField) && !scene.hasDialog()){ //move camera around float camSpeed = !Core.input.keyDown(Binding.boost) ? 3f : 8f; Core.camera.position.add(Tmp.v1.setZero().add(Core.input.axis(Binding.move_x), Core.input.axis(Binding.move_y)).nor().scl(Time.delta() * camSpeed)); diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index fc42071ca1..4d50e58c4d 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -651,7 +651,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ if(Core.settings.getBool("blockreplace")){ lineRequests.each(req -> { Block replace = req.block.getReplacement(req, lineRequests); - if(replace.unlockedCur()){ + if(replace.unlockedNow()){ req.block = replace; } }); diff --git a/core/src/mindustry/io/SaveVersion.java b/core/src/mindustry/io/SaveVersion.java index 27c7397be6..0e106b4c3a 100644 --- a/core/src/mindustry/io/SaveVersion.java +++ b/core/src/mindustry/io/SaveVersion.java @@ -6,6 +6,7 @@ import arc.struct.*; import arc.util.*; import arc.util.io.*; import mindustry.content.*; +import mindustry.content.TechTree.*; import mindustry.core.*; import mindustry.ctype.*; import mindustry.game.*; @@ -75,6 +76,11 @@ public abstract class SaveVersion extends SaveFileReader{ state.secinfo.prepare(); } + //flush tech node progress + for(TechNode node : TechTree.all){ + node.save(); + } + writeStringMap(stream, StringMap.of( "saved", Time.millis(), "playtime", headless ? 0 : control.saves.getTotalPlaytime(), diff --git a/core/src/mindustry/io/TypeIO.java b/core/src/mindustry/io/TypeIO.java index 42f9d3a2b6..641fc91b95 100644 --- a/core/src/mindustry/io/TypeIO.java +++ b/core/src/mindustry/io/TypeIO.java @@ -7,6 +7,8 @@ import arc.util.io.*; import arc.util.pooling.*; import mindustry.ai.types.*; import mindustry.annotations.Annotations.*; +import mindustry.content.*; +import mindustry.content.TechTree.*; import mindustry.ctype.*; import mindustry.entities.bullet.*; import mindustry.entities.units.*; @@ -67,6 +69,11 @@ public class TypeIO{ for(int i = 0; i < ((Point2[])object).length; i++){ write.i(((Point2[])object)[i].pack()); } + }else if(object instanceof TechNode){ + TechNode map = (TechNode)object; + write.b(9); + write.b((byte)map.content.getContentType().ordinal()); + write.s(map.content.id); }else{ throw new IllegalArgumentException("Unknown object type: " + object.getClass()); } @@ -84,6 +91,7 @@ public class TypeIO{ case 6: short length = read.s(); IntSeq arr = new IntSeq(); for(int i = 0; i < length; i ++) arr.add(read.i()); return arr; case 7: return new Point2(read.i(), read.i()); case 8: byte len = read.b(); Point2[] out = new Point2[len]; for(int i = 0; i < len; i ++) out[i] = Point2.unpack(read.i()); return out; + case 9: return TechTree.getNotNull(content.getByID(ContentType.all[read.b()], read.s())); default: throw new IllegalArgumentException("Unknown object type: " + type); } } diff --git a/core/src/mindustry/maps/Map.java b/core/src/mindustry/maps/Map.java index f23f6d6c0b..a7af96e78c 100644 --- a/core/src/mindustry/maps/Map.java +++ b/core/src/mindustry/maps/Map.java @@ -80,7 +80,6 @@ public class Map implements Comparable, Publishable{ public void setHighScore(int score){ Core.settings.put("hiscore" + file.nameWithoutExtension(), score); - Vars.data.modified(); } /** Returns the result of applying this map's rules to the specified gamemode.*/ diff --git a/core/src/mindustry/type/SectorPreset.java b/core/src/mindustry/type/SectorPreset.java index 6de84e9499..a5fe92e938 100644 --- a/core/src/mindustry/type/SectorPreset.java +++ b/core/src/mindustry/type/SectorPreset.java @@ -48,7 +48,7 @@ public class SectorPreset extends UnlockableContent{ } public boolean canUnlock(){ - return data.isUnlocked(this) || !requirements.contains(r -> !r.complete()); + return unlocked() || !requirements.contains(r -> !r.complete()); } public Seq getLaunchCost(){ @@ -74,7 +74,6 @@ public class SectorPreset extends UnlockableContent{ public void setLaunched(){ updateObjectives(() -> { Core.settings.put(name + "-launched", true); - data.modified(); }); } @@ -84,7 +83,6 @@ public class SectorPreset extends UnlockableContent{ if(value < wave){ updateObjectives(() -> { Core.settings.put(name + "-wave", wave); - data.modified(); }); } } @@ -133,7 +131,6 @@ public class SectorPreset extends UnlockableContent{ stacks.sort(); launchCost = stacks; - data.modified(); } /** Whether this zone has met its condition; if true, the player can leave. */ @@ -148,7 +145,6 @@ public class SectorPreset extends UnlockableContent{ @Override public void init(){ - for(ItemStack stack : startingItems){ defaultStartingItems.add(new ItemStack(stack.item, stack.amount)); } diff --git a/core/src/mindustry/type/Weather.java b/core/src/mindustry/type/Weather.java index 9bb9851c19..3910b22017 100644 --- a/core/src/mindustry/type/Weather.java +++ b/core/src/mindustry/type/Weather.java @@ -113,7 +113,7 @@ public abstract class Weather extends MappableContent{ private static final float fadeTime = 60 * 4; Weather weather; - float intensity = 1f, opacity = 1f, life; + float intensity = 1f, opacity = 0f, life; void init(Weather weather){ this.weather = weather; diff --git a/core/src/mindustry/ui/ItemsDisplay.java b/core/src/mindustry/ui/ItemsDisplay.java index f4db9034cd..4781c4d677 100644 --- a/core/src/mindustry/ui/ItemsDisplay.java +++ b/core/src/mindustry/ui/ItemsDisplay.java @@ -30,7 +30,7 @@ public class ItemsDisplay extends Table{ t.marginRight(30f); t.left(); for(Item item : content.items()){ - if(item.type == ItemType.material && data.isUnlocked(item)){ + if(item.type == ItemType.material && item.unlocked()){ t.label(() -> format(item)).left(); t.image(item.icon(Cicon.small)).size(8 * 3).padLeft(4).padRight(4); t.add(item.localizedName).color(Color.lightGray).left(); @@ -51,10 +51,11 @@ public class ItemsDisplay extends Table{ private String format(Item item){ builder.setLength(0); - builder.append(ui.formatAmount(data.getItem(item))); - if(state.isGame() && player.team().data().hasCore() && player.team().core().items().get(item) > 0){ + builder.append("[TODO implement]"); + //builder.append(ui.formatAmount(data.getItem(item))); + if(state.isGame() && player.team().data().hasCore() && player.team().core().items.get(item) > 0){ builder.append(" [unlaunched]+ "); - builder.append(ui.formatAmount(state.teams.get(player.team()).core().items().get(item))); + builder.append(ui.formatAmount(state.teams.get(player.team()).core().items.get(item))); } return builder.toString(); } diff --git a/core/src/mindustry/ui/dialogs/LanguageDialog.java b/core/src/mindustry/ui/dialogs/LanguageDialog.java index e1d31faa0d..db51900b54 100644 --- a/core/src/mindustry/ui/dialogs/LanguageDialog.java +++ b/core/src/mindustry/ui/dialogs/LanguageDialog.java @@ -30,7 +30,7 @@ public class LanguageDialog extends BaseDialog{ Table langs = new Table(); langs.marginRight(24f).marginLeft(24f); ScrollPane pane = new ScrollPane(langs); - pane.setFadeScrollBars(false); + pane.setScrollingDisabled(true, false); ButtonGroup group = new ButtonGroup<>(); diff --git a/core/src/mindustry/ui/dialogs/PausedDialog.java b/core/src/mindustry/ui/dialogs/PausedDialog.java index d05d15de83..11bfa98e5a 100644 --- a/core/src/mindustry/ui/dialogs/PausedDialog.java +++ b/core/src/mindustry/ui/dialogs/PausedDialog.java @@ -40,11 +40,12 @@ public class PausedDialog extends BaseDialog{ cont.button("$back", Icon.left, this::hide).colspan(2).width(dw * 2 + 20f); cont.row(); - if(state.isCampaign()){ - cont.button("$techtree", Icon.tree, ui.tech::show); - }else{ - cont.button("$database", Icon.book, ui.database::show); - } + //if(state.isCampaign()){ + // cont.button("$techtree", Icon.tree, ui.tech::show); + //}else{ + // cont.button("$database", Icon.book, ui.database::show); + //} + cont.button("placeholder", Icon.warning, () -> ui.showInfo("go away")); cont.button("$settings", Icon.settings, ui.settings::show); if(!state.rules.tutorial){ diff --git a/core/src/mindustry/ui/dialogs/ResourcesDialog.java b/core/src/mindustry/ui/dialogs/ResourcesDialog.java index 53736790cf..e92713f692 100644 --- a/core/src/mindustry/ui/dialogs/ResourcesDialog.java +++ b/core/src/mindustry/ui/dialogs/ResourcesDialog.java @@ -1,6 +1,5 @@ package mindustry.ui.dialogs; -import arc.graphics.*; import mindustry.gen.*; import mindustry.type.*; import mindustry.ui.*; @@ -23,14 +22,15 @@ public class ResourcesDialog extends BaseDialog{ t.margin(10f); int[] exports = universe.getTotalExports(); for(Item item : content.items()){ - if(exports[item.id] > 0 || data.getItem(item) > 0){ + //TODO display total items + if(exports[item.id] > 0){ t.image(item.icon(Cicon.small)).padRight(4); - t.add(ui.formatAmount(data.getItem(item))).color(Color.lightGray); - if(exports[item.id] > 0){ + //t.add(ui.formatAmount(data.getItem(item))).color(Color.lightGray); + //if(exports[item.id] > 0){ t.add("+ [accent]" + ui.formatAmount(exports[item.id]) + " [lightgray]/T"); - }else{ - t.add(); - } + //}else{ + // t.add(); + //} t.row(); } } diff --git a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java index cbd6d1cca5..969106c358 100644 --- a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -13,6 +13,7 @@ import arc.scene.ui.TextButton.*; import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.*; +import arc.util.io.*; import mindustry.core.GameState.*; import mindustry.core.*; import mindustry.game.EventType.*; @@ -21,7 +22,11 @@ import mindustry.graphics.*; import mindustry.input.*; import mindustry.ui.*; -import static arc.Core.bundle; +import java.io.*; +import java.util.zip.*; + +import static arc.Core.*; +import static mindustry.Vars.net; import static mindustry.Vars.*; public class SettingsMenuDialog extends SettingsDialog{ @@ -107,7 +112,7 @@ public class SettingsMenuDialog extends SettingsDialog{ if(ios){ Fi file = Core.files.local("mindustry-data-export.zip"); try{ - data.exportData(file); + exportData(file); }catch(Exception e){ ui.showException(e); } @@ -115,7 +120,7 @@ public class SettingsMenuDialog extends SettingsDialog{ }else{ platform.showFileChooser(false, "zip", file -> { try{ - data.exportData(file); + exportData(file); ui.showInfo("$data.exported"); }catch(Exception e){ e.printStackTrace(); @@ -129,7 +134,7 @@ public class SettingsMenuDialog extends SettingsDialog{ t.button("$data.import", Icon.download, style, () -> ui.showConfirm("$confirm", "$data.import.confirm", () -> platform.showFileChooser(true, "zip", file -> { try{ - data.importData(file); + importData(file); Core.app.exit(); }catch(IllegalArgumentException e){ ui.showErrorMessage("$data.invalid"); @@ -365,6 +370,43 @@ public class SettingsMenuDialog extends SettingsDialog{ graphics.checkPref("flow", true); } + public void exportData(Fi file) throws IOException{ + Seq files = new Seq<>(); + files.add(Core.settings.getSettingsFile()); + files.addAll(customMapDirectory.list()); + files.addAll(saveDirectory.list()); + files.addAll(screenshotDirectory.list()); + files.addAll(modDirectory.list()); + files.addAll(schematicDirectory.list()); + String base = Core.settings.getDataDirectory().path(); + + try(OutputStream fos = file.write(false, 2048); ZipOutputStream zos = new ZipOutputStream(fos)){ + for(Fi add : files){ + if(add.isDirectory()) continue; + zos.putNextEntry(new ZipEntry(add.path().substring(base.length()))); + Streams.copy(add.read(), zos); + zos.closeEntry(); + } + } + } + + public void importData(Fi file){ + Fi dest = Core.files.local("zipdata.zip"); + file.copyTo(dest); + Fi zipped = new ZipFi(dest); + + Fi base = Core.settings.getDataDirectory(); + if(!zipped.child("settings.bin").exists()){ + throw new IllegalArgumentException("Not valid save data."); + } + + //purge existing tmp data, keep everything else + tmpDirectory.deleteDirectory(); + + zipped.walk(f -> f.copyTo(base.child(f.path()))); + dest.delete(); + } + private void back(){ rebuildMenu(); prefs.clearChildren(); diff --git a/core/src/mindustry/ui/dialogs/TechTreeDialog.java b/core/src/mindustry/ui/dialogs/TechTreeDialog.java index 9ce2495bb6..efc7b2881d 100644 --- a/core/src/mindustry/ui/dialogs/TechTreeDialog.java +++ b/core/src/mindustry/ui/dialogs/TechTreeDialog.java @@ -1,6 +1,7 @@ package mindustry.ui.dialogs; import arc.*; +import arc.func.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.input.*; @@ -35,15 +36,17 @@ public class TechTreeDialog extends BaseDialog{ private ObjectSet nodes = new ObjectSet<>(); private TechTreeNode root = new TechTreeNode(TechTree.root, null); private Rect bounds = new Rect(); - private ItemsDisplay items; private View view; + private Cons selector = c -> {}; public TechTreeDialog(){ super(""); titleTable.remove(); margin(0f).marginBottom(8); - Stack stack = cont.stack(view = new View(), items = new ItemsDisplay()).grow().get(); + Stack stack = cont.stack(view = new View()/*, items = new ItemsDisplay()*/).grow().get(); + + shouldPause = true; Events.on(ContentReloadEvent.class, e -> { nodes.clear(); @@ -72,7 +75,7 @@ public class TechTreeDialog extends BaseDialog{ addListener(new InputListener(){ @Override public boolean scrolled(InputEvent event, float x, float y, float amountX, float amountY){ - view.setScale(Mathf.clamp(view.getScaleX() - amountY / 40f, 0.25f, 1f)); + view.setScale(Mathf.clamp(view.getScaleX() - amountY / 10f * view.getScaleX(), 0.25f, 1f)); view.setOrigin(Align.center); view.setTransform(true); return true; @@ -112,6 +115,15 @@ public class TechTreeDialog extends BaseDialog{ }); } + public Dialog show(Cons selector){ + this.selector = selector; + return super.show(); + } + + public Dialog show(){ + return show(c -> {}); + } + void treeLayout(){ float spacing = 20f; LayoutNode node = new LayoutNode(root, null); @@ -163,8 +175,6 @@ public class TechTreeDialog extends BaseDialog{ l.visible = !locked; checkNodes(l); } - - items.rebuild(); } void showToast(String info){ @@ -247,9 +257,13 @@ public class TechTreeDialog extends BaseDialog{ } }); } - }else if(data.hasItems(node.node.requirements) && locked(node.node)){ - unlock(node.node); + }else if(locked(node.node)){ + selector.get(node.node); } + //TODO select it + //else if(data.hasItems(node.node.requirements) && locked(node.node)){ + // unlock(node.node); + //} }); button.hovered(() -> { if(!mobile && hoverNode != button && node.visible){ @@ -269,7 +283,7 @@ public class TechTreeDialog extends BaseDialog{ button.update(() -> { float offset = (Core.graphics.getHeight() % 2) / 2f; button.setPosition(node.x + panX + width / 2f, node.y + panY + height / 2f + offset, Align.center); - button.getStyle().up = !locked(node.node) ? Tex.buttonOver : !data.hasItems(node.node.requirements) ? Tex.buttonRed : Tex.button; + button.getStyle().up = !locked(node.node) ? Tex.buttonOver : Tex.button; ((TextureRegionDrawable)button.getStyle().imageUp) .setRegion(node.visible ? node.node.content.icon(Cicon.medium) : Icon.lock.getRegion()); button.getImage().setColor(!locked(node.node) ? Color.white : Color.gray); @@ -304,9 +318,11 @@ public class TechTreeDialog extends BaseDialog{ panY = ry - bounds.y - oy; } + /* void unlock(TechNode node){ data.unlockContent(node.content); - data.removeItems(node.requirements); + //TODO this should not happen + //data.removeItems(node.requirements); showToast(Core.bundle.format("researched", node.content.localizedName)); checkNodes(root); hoverNode = null; @@ -315,7 +331,7 @@ public class TechTreeDialog extends BaseDialog{ Core.scene.act(); Sounds.unlock.play(); Events.fire(new ResearchEvent(node.content)); - } + }*/ void rebuild(){ ImageButton button = hoverNode; @@ -357,8 +373,8 @@ public class TechTreeDialog extends BaseDialog{ list.left(); list.image(req.item.icon(Cicon.small)).size(8 * 3).padRight(3); list.add(req.item.localizedName).color(Color.lightGray); - list.label(() -> " " + Math.min(data.getItem(req.item), req.amount) + " / " + req.amount) - .update(l -> l.setColor(data.has(req.item, req.amount) ? Color.lightGray : Color.scarlet)); + list.label(() -> " " + (player.team().core() != null ? Math.min(player.team().core().items.get(req.item), req.amount) + " / " : "") + req.amount) + .update(l -> {}/*l.setColor(data.has(req.item, req.amount) ? Color.lightGray : Color.scarlet)*/);//TODO }).fillX().left(); t.row(); } @@ -383,11 +399,13 @@ public class TechTreeDialog extends BaseDialog{ } }).pad(9); + //TODO research select button + /* if(mobile && locked(node)){ b.row(); b.button("$research", Icon.ok, Styles.nodet, () -> unlock(node)) .disabled(i -> !data.hasItems(node.requirements)).growX().height(44f).colspan(3); - } + }*/ }); infoTable.row(); diff --git a/core/src/mindustry/ui/fragments/PlacementFragment.java b/core/src/mindustry/ui/fragments/PlacementFragment.java index 6f040714e8..3ead933791 100644 --- a/core/src/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/mindustry/ui/fragments/PlacementFragment.java @@ -426,7 +426,7 @@ public class PlacementFragment extends Fragment{ } boolean unlocked(Block block){ - return !state.isCampaign() || data.isUnlocked(block); + return block.unlockedNow(); } boolean hasInfoBox(){ diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 593bfceb5c..95b5b4eed7 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -388,12 +388,12 @@ public class Block extends UnlockableContent{ } /** Configure when a null value is passed.*/ - public void configClear(Cons cons){ - configurations.put(void.class, (tile, value) -> cons.get((Tilec)tile)); + public void configClear(Cons cons){ + configurations.put(void.class, (tile, value) -> cons.get((E)tile)); } /** Listen for a config by class type. */ - public void config(Class type, Cons2 config){ + public void config(Class type, Cons2 config){ configurations.put(type, config); } diff --git a/core/src/mindustry/world/blocks/ItemSelection.java b/core/src/mindustry/world/blocks/ItemSelection.java index abd5a1a24a..921808eb08 100644 --- a/core/src/mindustry/world/blocks/ItemSelection.java +++ b/core/src/mindustry/world/blocks/ItemSelection.java @@ -24,7 +24,7 @@ public class ItemSelection{ int i = 0; for(T item : items){ - if(!data.isUnlocked(item) && state.isCampaign()) continue; + if(!item.unlockedNow()) continue; ImageButton button = cont.button(Tex.whiteui, Styles.clearToggleTransi, 24, () -> control.input.frag.config.hideConfig()).group(group).get(); button.changed(() -> consumer.get(button.isChecked() ? item : null)); diff --git a/core/src/mindustry/world/blocks/campaign/LaunchPad.java b/core/src/mindustry/world/blocks/campaign/LaunchPad.java index c8ddfa5855..5b12cb0ab5 100644 --- a/core/src/mindustry/world/blocks/campaign/LaunchPad.java +++ b/core/src/mindustry/world/blocks/campaign/LaunchPad.java @@ -177,7 +177,8 @@ public class LaunchPad extends Block{ //actually launch the items upon removal if(team() == Vars.state.rules.defaultTeam){ for(ItemStack stack : stacks){ - Vars.data.addItem(stack.item, stack.amount); + //TODO where do the items go? + //Vars.data.addItem(stack.item, stack.amount); Events.fire(new LaunchItemEvent(stack)); } } diff --git a/core/src/mindustry/world/blocks/campaign/ResearchBlock.java b/core/src/mindustry/world/blocks/campaign/ResearchBlock.java index 3216b691af..f5332c1d71 100644 --- a/core/src/mindustry/world/blocks/campaign/ResearchBlock.java +++ b/core/src/mindustry/world/blocks/campaign/ResearchBlock.java @@ -1,25 +1,27 @@ package mindustry.world.blocks.campaign; -import arc.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; -import arc.math.geom.*; +import arc.scene.style.*; import arc.scene.ui.layout.*; import arc.util.ArcAnnotate.*; +import arc.util.*; import arc.util.io.*; -import mindustry.*; import mindustry.annotations.Annotations.*; +import mindustry.content.*; +import mindustry.content.TechTree.*; import mindustry.ctype.*; -import mindustry.game.*; import mindustry.gen.*; +import mindustry.graphics.*; import mindustry.type.*; +import mindustry.ui.*; import mindustry.world.*; -import mindustry.world.blocks.storage.*; +import mindustry.world.consumers.*; import static mindustry.Vars.*; -public class ResearchBlock extends StorageBlock{ +public class ResearchBlock extends Block{ public float researchSpeed = 1f; public @Load("@-top") TextureRegion topRegion; @@ -31,7 +33,11 @@ public class ResearchBlock extends StorageBlock{ hasPower = true; hasItems = true; configurable = true; - itemCapacity = 0; + itemCapacity = 100; + + //TODO requirements shrink as time goes on + consumes.add(new ConsumeItemDynamic((ResearchBlockEntity entity) -> entity.researching != null ? entity.researching.requirements : ItemStack.empty)); + config(TechNode.class, ResearchBlockEntity::setTo); } @Override @@ -40,33 +46,100 @@ public class ResearchBlock extends StorageBlock{ } @Override - public boolean canPlaceOn(Tile tile, Team team){ - if(tile == null) return false; + public void setBars(){ + super.setBars(); - //only allow placing next to cores - for(Point2 edge : Edges.getEdges(size)){ - Tile other = tile.getNearby(edge); - if(other != null && other.block() instanceof CoreBlock && other.team() == team){ - return true; - } - } - return false; + bars.add("progress", (ResearchBlockEntity e) -> new Bar("bar.progress", Pal.ammo, () -> e.researching == null ? 0f : e.researching.progress / e.researching.time)); } - @Override - public void drawPlace(int x, int y, int rotation, boolean valid){ - boolean hasCore = canPlaceOn(world.tile(x, y), player.team()); - if(!hasCore){ - drawPlaceText(Core.bundle.get("bar.corereq"), x, y, valid); - } - } + public class ResearchBlockEntity extends TileEntity{ + public @Nullable TechNode researching; - public class ResearchBlockEntity extends StorageBlockEntity{ - public @Nullable UnlockableContent researching; + public double[] accumulator; + public double[] totalAccumulator; @Override public void updateTile(){ + if(researching != null){ + double totalTicks = researching.time * 60.0; + double amount = researchSpeed * edelta() / totalTicks; + double maxProgress = checkRequired(amount, false); + + for(int i = 0; i < researching.requirements.length; i++){ + int reqamount = Math.round(state.rules.buildCostMultiplier * researching.requirements[i].amount); + accumulator[i] += Math.min(reqamount * maxProgress, reqamount - totalAccumulator[i] + 0.00001); //add min amount progressed to the accumulator + totalAccumulator[i] = Math.min(totalAccumulator[i] + reqamount * maxProgress, reqamount); + } + + maxProgress = checkRequired(maxProgress, true); + + float increment = (float)(maxProgress * researching.time); + researching.progress += increment; + + //check if it has been researched + if(researching.progress >= researching.time){ + data.unlockContent(researching.content); + + setTo(null); + } + } + } + + private double checkRequired(double amount, boolean remove){ + double maxProgress = amount; + + for(int i = 0; i < researching.requirements.length; i++){ + int ramount = researching.requirements[i].amount; + int required = (int)(accumulator[i]); //calculate items that are required now + + if(!items.has(researching.requirements[i].item) && ramount > 0){ + maxProgress = 0f; + }else if(required > 0){ //if this amount is positive... + //calculate how many items it can actually use + int maxUse = Math.min(required, items.get(researching.requirements[i].item)); + //get this as a fraction + double fraction = maxUse / (double)required; + + //move max progress down if this fraction is less than 1 + maxProgress = Math.min(maxProgress, maxProgress * fraction); + + accumulator[i] -= maxUse; + + //remove stuff that is actually used + if(remove){ + items.remove(researching.requirements[i].item, maxUse); + } + } + //else, no items are required yet, so just keep going + } + + return maxProgress; + } + + private void setTo(@Nullable TechNode value){ + researching = value; + if(value != null){ + accumulator = new double[researching.requirements.length]; + totalAccumulator = new double[researching.requirements.length]; + } + } + + @Override + public void display(Table table){ + super.display(table); + + TextureRegionDrawable reg = new TextureRegionDrawable(); + + table.row(); + table.table(t -> { + t.image().update(i -> { + i.setDrawable(researching == null ? Icon.cancel : reg.set(researching.content.icon(Cicon.medium))); + i.setScaling(Scaling.fit); + i.setColor(researching == null ? Color.lightGray : Color.white); + }).size(32).pad(3); + t.label(() -> researching == null ? "$none" : researching.content.localizedName).color(Color.lightGray); + }).left().padTop(4); } @Override @@ -85,14 +158,25 @@ public class ResearchBlock extends StorageBlock{ @Override public boolean acceptItem(Tilec source, Item item){ - //research blocks can only transfer items to the core - return linkedCore != null && super.acceptItem(source, item); + return items.get(item) < getMaximumAccepted(item); + } + + @Override + public int getMaximumAccepted(Item item){ + if(researching == null) return 0; + for(int i = 0; i < researching.requirements.length; i++){ + if(researching.requirements[i].item == item) return researching.requirements[i].amount; + } + return 0; } @Override public boolean configTapped(){ - //TODO select target - Vars.ui.tech.show(); + //configure with tech node + ui.tech.show(node -> { + configure(node); + ui.tech.hide(); + }); return false; } @@ -102,8 +186,8 @@ public class ResearchBlock extends StorageBlock{ super.write(write); if(researching != null){ - write.b(researching.getContentType().ordinal()); - write.s(researching.id); + write.b(researching.content.getContentType().ordinal()); + write.s(researching.content.id); }else{ write.b(-1); } @@ -115,7 +199,7 @@ public class ResearchBlock extends StorageBlock{ byte type = read.b(); if(type != -1){ - researching = Vars.content.getByID(ContentType.all[type], read.s()); + setTo(TechTree.get(content.getByID(ContentType.all[type], read.s()))); }else{ researching = null; } diff --git a/core/src/mindustry/world/blocks/defense/Door.java b/core/src/mindustry/world/blocks/defense/Door.java index 24cadf20cc..50624123e1 100644 --- a/core/src/mindustry/world/blocks/defense/Door.java +++ b/core/src/mindustry/world/blocks/defense/Door.java @@ -28,12 +28,11 @@ public class Door extends Wall{ solidifes = true; consumesTap = true; - config(Boolean.class, (entity, open) -> { - DoorEntity door = (DoorEntity)entity; - door.open = open; - pathfinder.updateTile(door.tile()); - (open ? closefx : openfx).at(door); - Sounds.door.at(door); + config(Boolean.class, (DoorEntity entity, Boolean open) -> { + entity.open = open; + pathfinder.updateTile(entity.tile()); + (open ? closefx : openfx).at(entity); + Sounds.door.at(entity); }); } diff --git a/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java b/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java index 5a06857771..4ffdcb4904 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java @@ -42,7 +42,7 @@ public class ItemTurret extends Turret{ @Override public void build(Tilec tile, Table table){ MultiReqImage image = new MultiReqImage(); - content.items().each(i -> filter.get(i) && (!state.isCampaign() || data.isUnlocked(i)), item -> image.add(new ReqImage(new ItemImage(item.icon(Cicon.medium)), + content.items().each(i -> filter.get(i) && i.unlockedNow(), item -> image.add(new ReqImage(new ItemImage(item.icon(Cicon.medium)), () -> tile != null && !((ItemTurretEntity)tile).ammo.isEmpty() && ((ItemEntry)((ItemTurretEntity)tile).ammo.peek()).item == item))); table.add(image).size(8 * 4); diff --git a/core/src/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/mindustry/world/blocks/distribution/ItemBridge.java index 82084f521c..1e8f7087ed 100644 --- a/core/src/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/mindustry/world/blocks/distribution/ItemBridge.java @@ -44,9 +44,9 @@ public class ItemBridge extends Block{ canOverdrive = false; //point2 config is relative - config(Point2.class, (tile, i) -> ((ItemBridgeEntity)tile).link = Point2.pack(i.x + tile.tileX(), i.y + tile.tileY())); + config(Point2.class, (ItemBridgeEntity tile, Point2 i) -> tile.link = Point2.pack(i.x + tile.tileX(), i.y + tile.tileY())); //integer is not - config(Integer.class, (tile, i) -> ((ItemBridgeEntity)tile).link = i); + config(Integer.class, (ItemBridgeEntity tile, Integer i) -> tile.link = i); } @Override diff --git a/core/src/mindustry/world/blocks/distribution/MassDriver.java b/core/src/mindustry/world/blocks/distribution/MassDriver.java index 43358c65b8..3a008a0a75 100644 --- a/core/src/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/mindustry/world/blocks/distribution/MassDriver.java @@ -42,8 +42,8 @@ public class MassDriver extends Block{ hasPower = true; outlineIcon = true; //point2 is relative - config(Point2.class, (tile, point) -> ((MassDriverEntity)tile).link = Point2.pack(point.x + tile.tileX(), point.y + tile.tileY())); - config(Integer.class, (tile, point) -> ((MassDriverEntity)tile).link = point); + config(Point2.class, (MassDriverEntity tile, Point2 point) -> tile.link = Point2.pack(point.x + tile.tileX(), point.y + tile.tileY())); + config(Integer.class, (MassDriverEntity tile, Integer point) -> tile.link = point); } @Override diff --git a/core/src/mindustry/world/blocks/distribution/Sorter.java b/core/src/mindustry/world/blocks/distribution/Sorter.java index ca8c0502b2..9b2529856c 100644 --- a/core/src/mindustry/world/blocks/distribution/Sorter.java +++ b/core/src/mindustry/world/blocks/distribution/Sorter.java @@ -28,8 +28,8 @@ public class Sorter extends Block{ unloadable = false; saveConfig = true; - config(Item.class, (tile, item) -> ((SorterEntity)tile).sortItem = item); - configClear(tile -> ((SorterEntity)tile).sortItem = null); + config(Item.class, (SorterEntity tile, Item item) -> tile.sortItem = item); + configClear((SorterEntity tile) -> tile.sortItem = null); } @Override diff --git a/core/src/mindustry/world/blocks/experimental/BlockForge.java b/core/src/mindustry/world/blocks/experimental/BlockForge.java index 47b86e048f..20036d943f 100644 --- a/core/src/mindustry/world/blocks/experimental/BlockForge.java +++ b/core/src/mindustry/world/blocks/experimental/BlockForge.java @@ -33,17 +33,9 @@ public class BlockForge extends PayloadAcceptor{ hasPower = true; rotate = true; - config(Block.class, (tile, block) -> ((BlockForgeEntity)tile).recipe = block); + config(Block.class, (BlockForgeEntity tile, Block block) -> tile.recipe = block); - consumes.add(new ConsumeItemDynamic(e -> { - BlockForgeEntity entity = (BlockForgeEntity)e; - - if(entity.recipe != null){ - return entity.recipe.requirements; - } - - return ItemStack.empty; - })); + consumes.add(new ConsumeItemDynamic((BlockForgeEntity e) -> e.recipe != null ? e.recipe.requirements : ItemStack.empty)); } @Override diff --git a/core/src/mindustry/world/blocks/power/ImpactReactor.java b/core/src/mindustry/world/blocks/power/ImpactReactor.java index ec95ffd9de..545e07dca0 100644 --- a/core/src/mindustry/world/blocks/power/ImpactReactor.java +++ b/core/src/mindustry/world/blocks/power/ImpactReactor.java @@ -43,11 +43,11 @@ public class ImpactReactor extends PowerGenerator{ public void setBars(){ super.setBars(); - bars.add("poweroutput", entity -> new Bar(() -> + bars.add("poweroutput", (GeneratorEntity entity) -> new Bar(() -> Core.bundle.format("bar.poweroutput", Strings.fixed(Math.max(entity.getPowerProduction() - consumes.getPower().usage, 0) * 60 * entity.timeScale(), 1)), () -> Pal.powerBar, - () -> ((GeneratorEntity)entity).productionEfficiency)); + () -> entity.productionEfficiency)); } @Override diff --git a/core/src/mindustry/world/blocks/power/LightBlock.java b/core/src/mindustry/world/blocks/power/LightBlock.java index aa3a2e577e..7d89bdcdf7 100644 --- a/core/src/mindustry/world/blocks/power/LightBlock.java +++ b/core/src/mindustry/world/blocks/power/LightBlock.java @@ -24,7 +24,7 @@ public class LightBlock extends Block{ configurable = true; saveConfig = true; - config(Integer.class, (tile, value) -> ((LightEntity)tile).color = value); + config(Integer.class, (LightEntity tile, Integer value) -> tile.color = value); } public class LightEntity extends TileEntity{ diff --git a/core/src/mindustry/world/blocks/power/NuclearReactor.java b/core/src/mindustry/world/blocks/power/NuclearReactor.java index 5e08c32b27..51db86567f 100644 --- a/core/src/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/mindustry/world/blocks/power/NuclearReactor.java @@ -60,7 +60,7 @@ public class NuclearReactor extends PowerGenerator{ @Override public void setBars(){ super.setBars(); - bars.add("heat", entity -> new Bar("bar.heat", Pal.lightOrange, () -> ((NuclearReactorEntity)entity).heat)); + bars.add("heat", (NuclearReactorEntity entity) -> new Bar("bar.heat", Pal.lightOrange, () -> entity.heat)); } public class NuclearReactorEntity extends GeneratorEntity{ diff --git a/core/src/mindustry/world/blocks/power/PowerGenerator.java b/core/src/mindustry/world/blocks/power/PowerGenerator.java index cb8e4c6009..804b359f43 100644 --- a/core/src/mindustry/world/blocks/power/PowerGenerator.java +++ b/core/src/mindustry/world/blocks/power/PowerGenerator.java @@ -32,11 +32,11 @@ public class PowerGenerator extends PowerDistributor{ super.setBars(); if(hasPower && outputsPower && !consumes.hasPower()){ - bars.add("power", entity -> new Bar(() -> + bars.add("power", (GeneratorEntity entity) -> new Bar(() -> Core.bundle.format("bar.poweroutput", Strings.fixed(entity.getPowerProduction() * 60 * entity.timeScale(), 1)), () -> Pal.powerBar, - () -> ((GeneratorEntity)entity).productionEfficiency)); + () -> entity.productionEfficiency)); } } diff --git a/core/src/mindustry/world/blocks/production/Cultivator.java b/core/src/mindustry/world/blocks/production/Cultivator.java index 782e47f1e5..f4587a4a82 100644 --- a/core/src/mindustry/world/blocks/production/Cultivator.java +++ b/core/src/mindustry/world/blocks/production/Cultivator.java @@ -31,11 +31,11 @@ public class Cultivator extends GenericCrafter{ @Override public void setBars(){ super.setBars(); - bars.add("multiplier", entity -> new Bar(() -> + bars.add("multiplier", (CultivatorEntity entity) -> new Bar(() -> Core.bundle.formatFloat("bar.efficiency", - ((((CultivatorEntity)entity).boost + 1f) * ((CultivatorEntity)entity).warmup) * 100f, 1), + ((entity.boost + 1f) * entity.warmup) * 100f, 1), () -> Pal.ammo, - () -> ((CultivatorEntity)entity).warmup)); + () -> entity.warmup)); } @Override diff --git a/core/src/mindustry/world/blocks/production/Drill.java b/core/src/mindustry/world/blocks/production/Drill.java index df0d76bf8a..e5f5d7372f 100644 --- a/core/src/mindustry/world/blocks/production/Drill.java +++ b/core/src/mindustry/world/blocks/production/Drill.java @@ -86,11 +86,8 @@ public class Drill extends Block{ public void setBars(){ super.setBars(); - bars.add("drillspeed", e -> { - DrillEntity entity = (DrillEntity)e; - - return new Bar(() -> Core.bundle.format("bar.drillspeed", Strings.fixed(entity.lastDrillSpeed * 60 * entity.timeScale(), 2)), () -> Pal.ammo, () -> entity.warmup); - }); + bars.add("drillspeed", (DrillEntity e) -> + new Bar(() -> Core.bundle.format("bar.drillspeed", Strings.fixed(e.lastDrillSpeed * 60 * e.timeScale(), 2)), () -> Pal.ammo, () -> e.warmup)); } public Item getDrop(Tile tile){ @@ -285,7 +282,6 @@ public class Drill extends Block{ if(dominantItems > 0 && progress >= delay && items.total() < itemCapacity){ offload(dominantItem); - useContent(dominantItem); index ++; progress %= delay; diff --git a/core/src/mindustry/world/blocks/production/GenericCrafter.java b/core/src/mindustry/world/blocks/production/GenericCrafter.java index 243e9982f4..c70c08973c 100644 --- a/core/src/mindustry/world/blocks/production/GenericCrafter.java +++ b/core/src/mindustry/world/blocks/production/GenericCrafter.java @@ -116,14 +116,12 @@ public class GenericCrafter extends Block{ consume(); if(outputItem != null){ - useContent(outputItem.item); for(int i = 0; i < outputItem.amount; i++){ offload(outputItem.item); } } if(outputLiquid != null){ - useContent(outputLiquid.liquid); handleLiquid(this, outputLiquid.liquid, outputLiquid.amount); } diff --git a/core/src/mindustry/world/blocks/production/LiquidConverter.java b/core/src/mindustry/world/blocks/production/LiquidConverter.java index 16ab9751f4..d722d00211 100644 --- a/core/src/mindustry/world/blocks/production/LiquidConverter.java +++ b/core/src/mindustry/world/blocks/production/LiquidConverter.java @@ -45,7 +45,6 @@ public class LiquidConverter extends GenericCrafter{ if(cons.valid()){ float use = Math.min(cl.amount * edelta(), liquidCapacity - liquids.get(outputLiquid.liquid)); - useContent(outputLiquid.liquid); progress += use / cl.amount; liquids.add(outputLiquid.liquid, use); if(progress >= craftTime){ diff --git a/core/src/mindustry/world/blocks/production/Pump.java b/core/src/mindustry/world/blocks/production/Pump.java index f5a2e9efc2..0dff2b248b 100644 --- a/core/src/mindustry/world/blocks/production/Pump.java +++ b/core/src/mindustry/world/blocks/production/Pump.java @@ -13,8 +13,6 @@ import mindustry.world.meta.*; import static mindustry.Vars.*; public class Pump extends LiquidBlock{ - public final int timerContentCheck = timers++; - /** Pump amount, total. */ protected float pumpAmount = 1f; @@ -115,10 +113,6 @@ public class Pump extends LiquidBlock{ liquids.add(liquidDrop, maxPump); } - if(liquids.currentAmount() > 0f && timer(timerContentCheck, 10)){ - useContent(liquids.current()); - } - dumpLiquid(liquids.current()); } } diff --git a/core/src/mindustry/world/blocks/production/SolidPump.java b/core/src/mindustry/world/blocks/production/SolidPump.java index 196e32d6c7..64f6570d63 100644 --- a/core/src/mindustry/world/blocks/production/SolidPump.java +++ b/core/src/mindustry/world/blocks/production/SolidPump.java @@ -43,11 +43,11 @@ public class SolidPump extends Pump{ @Override public void setBars(){ super.setBars(); - bars.add("efficiency", entity -> new Bar(() -> + bars.add("efficiency", (SolidPumpEntity entity) -> new Bar(() -> Core.bundle.formatFloat("bar.pumpspeed", - ((SolidPumpEntity)entity).lastPump / Time.delta() * 60, 1), + entity.lastPump / Time.delta() * 60, 1), () -> Pal.ammo, - () -> ((SolidPumpEntity)entity).warmup)); + () -> entity.warmup)); } @Override @@ -124,7 +124,6 @@ public class SolidPump extends Pump{ liquids.add(result, maxPump); lastPump = maxPump; warmup = Mathf.lerpDelta(warmup, 1f, 0.02f); - if(timer(timerContentCheck, 10)) useContent(result); if(Mathf.chance(delta() * updateEffectChance)) updateEffect.at(getX() + Mathf.range(size * 2f), getY() + Mathf.range(size * 2f)); }else{ diff --git a/core/src/mindustry/world/blocks/sandbox/ItemSource.java b/core/src/mindustry/world/blocks/sandbox/ItemSource.java index 0e08160ef8..c4fa61590a 100644 --- a/core/src/mindustry/world/blocks/sandbox/ItemSource.java +++ b/core/src/mindustry/world/blocks/sandbox/ItemSource.java @@ -24,8 +24,8 @@ public class ItemSource extends Block{ configurable = true; saveConfig = true; - config(Item.class, (tile, item) -> ((ItemSourceEntity)tile).outputItem = item); - configClear(tile -> ((ItemSourceEntity)tile).outputItem = null); + config(Item.class, (ItemSourceEntity tile, Item item) -> tile.outputItem = item); + configClear((ItemSourceEntity tile) -> tile.outputItem = null); } @Override diff --git a/core/src/mindustry/world/blocks/sandbox/LiquidSource.java b/core/src/mindustry/world/blocks/sandbox/LiquidSource.java index 146283fe41..178a41db41 100644 --- a/core/src/mindustry/world/blocks/sandbox/LiquidSource.java +++ b/core/src/mindustry/world/blocks/sandbox/LiquidSource.java @@ -25,8 +25,8 @@ public class LiquidSource extends Block{ outputsLiquid = true; saveConfig = true; - config(Liquid.class, (tile, l) -> ((LiquidSourceEntity)tile).source = l); - configClear(tile -> ((LiquidSourceEntity)tile).source = null); + config(Liquid.class, (LiquidSourceEntity tile, Liquid l) -> tile.source = l); + configClear((LiquidSourceEntity tile) -> tile.source = null); } @Override diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index 64c9b30d07..1e0e660a24 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -69,11 +69,11 @@ public class CoreBlock extends StorageBlock{ public void setStats(){ super.setStats(); - bars.add("capacity", e -> + bars.add("capacity", (CoreEntity e) -> new Bar( - () -> Core.bundle.format("bar.capacity", ui.formatAmount(((CoreEntity)e).storageCapacity)), + () -> Core.bundle.format("bar.capacity", ui.formatAmount(e.storageCapacity)), () -> Pal.items, - () -> e.items().total() / (float)(((CoreEntity)e).storageCapacity * content.items().count(i -> i.type == ItemType.material)) + () -> e.items().total() / ((float)e.storageCapacity * content.items().count(i -> i.type == ItemType.material)) )); bars.add("units", e -> diff --git a/core/src/mindustry/world/blocks/storage/MessageBlock.java b/core/src/mindustry/world/blocks/storage/MessageBlock.java index d3f34b7726..a6adb2e411 100644 --- a/core/src/mindustry/world/blocks/storage/MessageBlock.java +++ b/core/src/mindustry/world/blocks/storage/MessageBlock.java @@ -29,9 +29,7 @@ public class MessageBlock extends Block{ solid = true; destructible = true; - config(String.class, (tile, text) -> { - MessageBlockEntity entity = (MessageBlockEntity)tile; - + config(String.class, (MessageBlockEntity tile, String text) -> { if(net.server() && text.length() > maxTextLength){ throw new ValidateException(player, "Player has gone above text limit."); } @@ -51,8 +49,8 @@ public class MessageBlock extends Block{ } } - entity.message = result.toString(); - entity.lines = entity.message.split("\n"); + tile.message = result.toString(); + tile.lines = tile.message.split("\n"); }); } diff --git a/core/src/mindustry/world/blocks/storage/Unloader.java b/core/src/mindustry/world/blocks/storage/Unloader.java index 560992c40c..2611328563 100644 --- a/core/src/mindustry/world/blocks/storage/Unloader.java +++ b/core/src/mindustry/world/blocks/storage/Unloader.java @@ -27,12 +27,8 @@ public class Unloader extends Block{ saveConfig = true; itemCapacity = 0; - config(Item.class, (tile, item) -> { - tile.items().clear(); - ((UnloaderEntity)tile).sortItem = item; - }); - - configClear(tile -> ((UnloaderEntity)tile).sortItem = null); + config(Item.class, (UnloaderEntity tile, Item item) -> tile.sortItem = item); + configClear((UnloaderEntity tile) -> tile.sortItem = null); } @Override diff --git a/core/src/mindustry/world/blocks/units/Reconstructor.java b/core/src/mindustry/world/blocks/units/Reconstructor.java index 7c102ffff9..5783f9f3d6 100644 --- a/core/src/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/mindustry/world/blocks/units/Reconstructor.java @@ -41,7 +41,7 @@ public class Reconstructor extends UnitBlock{ @Override public void setBars(){ super.setBars(); - bars.add("progress", entity -> new Bar("bar.progress", Pal.ammo, ((ReconstructorEntity)entity)::fraction)); + bars.add("progress", (ReconstructorEntity entity) -> new Bar("bar.progress", Pal.ammo, entity::fraction)); } @Override diff --git a/core/src/mindustry/world/blocks/units/UnitFactory.java b/core/src/mindustry/world/blocks/units/UnitFactory.java index 4648916b1c..6567054ffd 100644 --- a/core/src/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/mindustry/world/blocks/units/UnitFactory.java @@ -37,20 +37,12 @@ public class UnitFactory extends UnitBlock{ outputsPayload = true; rotate = true; - config(Integer.class, (tile, i) -> { - ((UnitFactoryEntity)tile).currentPlan = i < 0 || i >= plans.length ? -1 : i; - ((UnitFactoryEntity)tile).progress = 0; + config(Integer.class, (UnitFactoryEntity tile, Integer i) -> { + tile.currentPlan = i < 0 || i >= plans.length ? -1 : i; + tile.progress = 0; }); - consumes.add(new ConsumeItemDynamic(e -> { - UnitFactoryEntity entity = (UnitFactoryEntity)e; - - if(entity.currentPlan != -1){ - return plans[entity.currentPlan].requirements; - } - - return ItemStack.empty; - })); + consumes.add(new ConsumeItemDynamic((UnitFactoryEntity e) -> e.currentPlan != -1 ? plans[e.currentPlan].requirements : ItemStack.empty)); } @Override @@ -69,7 +61,7 @@ public class UnitFactory extends UnitBlock{ @Override public void setBars(){ super.setBars(); - bars.add("progress", entity -> new Bar("bar.progress", Pal.ammo, ((UnitFactoryEntity)entity)::fraction)); + bars.add("progress", (UnitFactoryEntity entity) -> new Bar("bar.progress", Pal.ammo, entity::fraction)); } @Override diff --git a/core/src/mindustry/world/consumers/ConsumeItemDynamic.java b/core/src/mindustry/world/consumers/ConsumeItemDynamic.java index 75401a6c8e..d85e38ea5d 100644 --- a/core/src/mindustry/world/consumers/ConsumeItemDynamic.java +++ b/core/src/mindustry/world/consumers/ConsumeItemDynamic.java @@ -1,6 +1,7 @@ package mindustry.world.consumers; import arc.func.*; +import arc.math.*; import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.ArcAnnotate.*; @@ -12,8 +13,8 @@ import mindustry.world.meta.*; public class ConsumeItemDynamic extends Consume{ public final @NonNull Func items; - public ConsumeItemDynamic(Func items){ - this.items = items; + public ConsumeItemDynamic(Func items){ + this.items = (Func)items; } @Override @@ -43,7 +44,7 @@ public class ConsumeItemDynamic extends Consume{ private void rebuild(Tilec tile, Table table){ for(ItemStack stack : items.get(tile)){ table.add(new ReqImage(new ItemImage(stack.item.icon(Cicon.medium), stack.amount), - () -> tile.items() != null && tile.items().has(stack.item, stack.amount))).size(8 * 4).padRight(5); + () -> tile.items() != null && tile.items().has(stack.item, stack.amount))).size(8 * 4).padRight(6 * Mathf.digits(stack.amount)); } } diff --git a/core/src/mindustry/world/consumers/ConsumeItemFilter.java b/core/src/mindustry/world/consumers/ConsumeItemFilter.java index e97afbf883..2ff850f843 100644 --- a/core/src/mindustry/world/consumers/ConsumeItemFilter.java +++ b/core/src/mindustry/world/consumers/ConsumeItemFilter.java @@ -33,7 +33,7 @@ public class ConsumeItemFilter extends Consume{ @Override public void build(Tilec tile, Table table){ MultiReqImage image = new MultiReqImage(); - content.items().each(i -> filter.get(i) && (!state.isCampaign() || data.isUnlocked(i)), item -> image.add(new ReqImage(new ItemImage(item.icon(Cicon.medium), 1), + content.items().each(i -> filter.get(i) && i.unlockedNow(), item -> image.add(new ReqImage(new ItemImage(item.icon(Cicon.medium), 1), () -> tile.items() != null && tile.items().has(item)))); table.add(image).size(8 * 4); diff --git a/core/src/mindustry/world/meta/BlockBars.java b/core/src/mindustry/world/meta/BlockBars.java index 25eeba6d1d..eb0e3e88a3 100644 --- a/core/src/mindustry/world/meta/BlockBars.java +++ b/core/src/mindustry/world/meta/BlockBars.java @@ -8,8 +8,8 @@ import mindustry.ui.Bar; public class BlockBars{ private OrderedMap> bars = new OrderedMap<>(); - public void add(String name, Func sup){ - bars.put(name, sup); + public void add(String name, Func sup){ + bars.put(name, (Func)sup); } public void remove(String name){