diff --git a/assets/bundles/bundle.properties b/assets/bundles/bundle.properties index d9add3f..34732a3 100644 --- a/assets/bundles/bundle.properties +++ b/assets/bundles/bundle.properties @@ -27,7 +27,17 @@ block.meld-tantrum.name = Tantrum block.meld-tantrum.description = Compacts and puffs out clouds of [#8872da]Rift[] using a Silver piston, dealing heavy knockback.\n[accent]Reduces target's drag[] block.meld-earthbound-infuser.name = Earthbound Infuser -block.meld-earthbound-infuser.description = Infuses Debris with vent fumes to synthesize Carbolith.\n\nRequires [#cbdbfc]Aspect[] to run. +block.meld-earthbound-infuser.description = Infuses Debris with vent fumes to synthesize Carbolith.\n\nRequires [#cbdbfc]Aspect[] to run, can siphon [#5b4739]Fumes[] from vents. + +block.meld-gas-kiln.name = Gas-fired Kiln +block.meld-gas-kiln.description = Heats materials using [#cbdbfc]Aspect[][accent]\n\nCarbolith + Tenbris -> Shadesteel + [#5b4739]Fumes[]\nClay-Mallows -> Glass-Mallows\nSilver -> Annealed Silver\nDebris + Glass-Mallows -> Crucible Platings\nDebris + Shadesteel -> Crucible Platings + +block.meld-rotary-kiln.name = Rotary Kiln +block.meld-rotary-kiln.description = Constantly burns [#cbdbfc]Aspect[] as fuel, heats materials to process them in bulk. [accent]\n\nTenbris -> Shadesteel\nClay-Mallows -> Glass-Mallows\nSilver -> Annealed Silver\nDebris + Glass-Mallows -> Crucible Platings\nDebris + Shadesteel -> Crucible Platings + +block.meld-pneumatic-extruder.name = Pneumatic Extruder +block.meld-pneumatic-extruder.description = Extrudes insulated pipes, uses[#cbdbfc]Aspect[] to run. [accent]\n\nShadesteel + Elnar -> Aspect Pipe\n\nAnnealed Silver + Debris -> Aspect Pipe + block.meld-heating-basin.name = Heating Basin block.meld-heating-basin.description = Runs [#b89f47]Nectar[] through pipes laced with Carbolith dust over geothermal sources to extract [#89828c]Mercury[], producing loads of Debris as a byproduct. @@ -63,7 +73,11 @@ block.meld-brick-conglomerator.name = Conglomeration Rig block.meld-brick-conglomerator.description = Crushes up Carbolith and mixes it with vent fumes and [#e6c700]Ichor[], then presses the slurry into Bricks. Requires [#cbdbfc]Aspect[] to run. block.meld-silver-husk.name = Silver Husk -block.meld-silver-husk.description = Provides cover against enemy projectiles. Slowly regenerates when fed [#cbdbfc]Aspect[].\n\n[accent]Plated[] +block.meld-silver-husk.description = Buildable, [accent]insulated[] protection. Slowly regenerates when fed [#cbdbfc]Aspect[].\n\n[accent]Plated[] + +block.meld-shadesteel-shingles.name = Shadesteel Shingles +block.meld-shadesteel-shingles.description = Mundane and bulky. +block.meld-shadesteel-shingles.details = Brick of Shadesteel bricks of Shadesteel ingots. block.meld-barricade.name = Barricade block.meld-barricade.description = Provides cover against enemy projectiles.\nQuick to build.\n\nEasy way to store Compacted Bricks/Stony Gloop outside of the core for onsite use.\n\n[accent]Armored.[] @@ -83,6 +97,12 @@ block.meld-sonar-spire.details = Initially an aether flarestack build to help tr block.meld-movement-anchor.name = Movement Anchor block.meld-movement-anchor.description = Targets and [accent]Anchor[]s enemy units. +block.meld-gauze.name = Gauze +block.meld-gauze.description = Weaves a [accent]Resonarum[] thread using [#5b4739]Fumes[], automatically applying it to connected blocks. + +block.meld-bruisekit.name = Bruisekit +block.meld-bruisekit.description = Regenerates target block's health.\n\nPrioritises large, functional blocks and can't target 1x1s. + block.meld-mercurial-diffuser.name = Mercurial Diffuser block.meld-mercurial-diffuser.description = Puffs clouds which intoxicate [#ea9ad6]Meld[] units. Applies a coating of [#89828c]Mercury[] to allied units. @@ -114,7 +134,7 @@ block.meld-chute-crossing.name = Chute Crossing block.meld-chute-crossing.description = Lets items cross through without intersecting with eachother. block.meld-chute-overflow.name = Chute Overflow -block.meld-chute-overflow.description = Routes items to the front, or to the sides if blocked. +block.meld-chute-overflow.description = Routes items to the front, or to the sides if blocked. \n\nAccepts items from the back, or the sides if empty. block.meld-chute-bridge.name = Chute Bridge block.meld-chute-bridge.description = Moves items over a single tile. Bypasses structures and terrain. @@ -130,16 +150,33 @@ block.meld-channel-face.name = Channel Face block.meld-channel-face.description = Acts as a fluid junction. Transmits fluid without storing it. No risk of explosion. block.meld-channel-node.name = Channel Node -block.meld-channel-node.description = Acts as a fluid router. Liquid can be input or output from any side. Stores a small amount of fluid. +block.meld-channel-node.description = Acts as a fluid router. Fluids can be input or output from any side. Stores a small amount of fluid. block.meld-aspect-outlet.name = Aspect Outlet -block.meld-aspect-outlet.description = Decompresses [#cb8650]Aether[] into highly volatile [#cbdbfc]Aspect[].\n\nWorks as an output terminal for a fluid network. +block.meld-aspect-outlet.description = Decompresses [#cb8650]Aether[] into highly volatile [#cbdbfc]Aspect[] at a ratio of 1:10.\n\nWorks as an output terminal for a fluid network. + +block.meld-aspect-channel.name = Aspect Channel +block.meld-aspect-channel.description = Acts as a directional router.\n\nWhen transporting [#cb8650]Aether[], fills nearby buildings with highly volatile [#cbdbfc]Aspect[].\n\nWorks as an insulated input/output terminal for a fluid network.\n\n[accent]Plated![] + +block.meld-pressure-vent.name = Pressure Vent +block.meld-pressure-vent.description = Acts as a fluid router. Releases stored vapor into the atmosphere. + +block.meld-manual-valve.name = Manual Valve +block.meld-manual-valve.description = Acts as a fluid junction. Can be toggled to control if fluids can pass through. -block.meld-aspect-pipe.name = Aspect Pipe -block.meld-aspect-pipe.description = Acts as a pipe.\n\nWhen transporting [#cb8650]Aether[], fills nearby buildings with highly volatile [#cbdbfc]Aspect[].\n\nWorks as an input/output terminal for a fluid network. +block.meld-intake-valve.name = Intake Valve +block.meld-intake-valve.description = Acts as a fluid junction. Can be toggled to control if fluids can pass through.\n\n[accent]Can compact/de-compact incoming sources of fluids into the channel network.[]\n\n[accent]Plated![] +block.meld-intake-valve.details = Yes, it works. + +block.meld-valve-controller.name = Valve Controller +block.meld-valve-controller.description = Acts as a fluid junction. Enables the targeted block when surrounded by blocks with fluids over its threshold.\n\nThreshold/State can be configured. +block.meld-valve-controller.details = Scidustry players, Ikaru is calling YOU. block.meld-channel-director.name = Channel Director -block.meld-channel-director.description = [red]Restricts[] the flow of fluids from its input to output by half.\n\nCan [red]detonate[] Channel Nodes full of [#cbdbfc]Aspect[].\n[accent]Transports at 50% pressure.[]\n\n[red]Will chain destruct![] +block.meld-channel-director.description = When used with other fluid blocks, [red]restricts[] the flow of fluids to one direction only. + +block.meld-pipebox.name = Pipebox +block.meld-pipebox.description = Routes fluids to the sides.\n\nCan be toggled to rotate the connections. block.meld-channel-director-pressurized.name = Pressurized Channel Director block.meld-channel-director-pressurized.description = Acts as a conduit. Transmits fluid from one side to the other. Stores a tiny amount of fluid.\n[accent]Transports at 200% pressure.[]\n\n[red]Will chain destruct![] @@ -195,6 +232,9 @@ block.meld-thermo-matting.details = ...appears to be little to no waste left beh block.meld-aether-accumulator.name = Aether Accumulator block.meld-aether-accumulator.description = Collects [#cb8650]Aether[] from suitable sources. +block.meld-fumehood.name = Fumehood +block.meld-fumehood.description = Placed over sources of aspects or gasses. + block.meld-crystal-cracker.name = Crystal Cracker block.meld-crystal-cracker.description = Breaks open Dissonitre crystals over [accent]aspect soil[] as a source of [#cb8650]Aether[]. @@ -209,10 +249,6 @@ block.meld-vitric-stimulator-ruined.name = Vitric Stimu1ator [lightgray](Ruined) block.meld-vitric-stimulator.description = Harvests [#8872da]Rift[] from suitable sources using Vitric Meshes to filter the air, producing a small amount of glass waste.\n\nRequires Power to run.\n\n[orange]Inefficient, deconstruction is advised[] block.meld-vitric-stimulator.details = If only those vents could be harvested from... -block.meld-vitric-stimulator.name = Vitric Stimu1ator -block.meld-vitric-stimulator.description = Harvests [#8872da]Rift[] from suitable sources using Vitric Meshes to filter the air, producing a substantial amount of glass waste.\n\nRequires Power to run. -block.meld-vitric-stimulator.details = If only those vents could be harvested from... - block.meld-flarestack-filter.name = Flarestack Filter block.meld-flarestack-filter.description = Harvests [#8872da]Rift[] from suitable sources by neutralizing the impurities from the air.\n\nRequires Resonarum and Riplom to run. block.meld-flarestack-filter.details = Neutralizes the Aether content of an impure [accent]rift vent[] by focusing it into Aspect and combusting it with Riplom, but requires a constant supply of lenses to function. @@ -233,6 +269,9 @@ block.meld-displacement-pump.description = Dumps Debris into fluids to retrive a block.meld-elemental-blaster.name = Elemental Blaster block.meld-elemental-blaster.description = Blasts deposits for items indefinitely. Requires [#cbdbfc]Aspect[] to run.\n\nCan be boosted with [#ea9ad6]Meld[] to double harvesting speed. +block.meld-pneumatic-pulsar.name = Pneumatic Pulsar +block.meld-pneumatic-pulsar.description = Blasts a single deposit for items indefinitely while maintained. Requires [#cb8650]Aether[] to run.\n\n[red]Explosions damage everything around them, high maintenance![] + block.meld-elemental-sampler.name = Elemental Sampler block.meld-elemental-sampler.description = Samples deposits for items indefinitely. Requires [#cbdbfc]Aspect[] and [#8872da]Rift[] to run.\n\nCan be boosted with [#b460e2]Warp[] to double harvesting speed.\n\n[accent]More efficient against soft tissue[] block.meld-elemental-sampler.details = It wants to return home. @@ -589,6 +628,10 @@ item.meld-clay-mallow.name = Clay-Mallow item.meld-clay-mallow.description = Clay from the Badlands. Easly moulded to form containers, but difficult to aquire by blasting soil. item.meld-clay-mallow.details = A delicate substance valued for its malleability and ability to keep its shape, along with its velvety texture. +item.meld-glass-mallow.name = Glass-Mallow +item.meld-glass-mallow.description = Refined clay from the Badlands, more glass than ceramic. +item.meld-glass-mallow.details = A glossy, crystalline substance. + item.meld-riplom.name = Riplom item.meld-riplom.description = Shale from the Storm Planes. A great flux for glasswork, though not much practical use found. Slightly volatile. item.meld-riplom.details = Looks almost fungal. Seems to absorb [#cbdbfc]Aspect[] from its suroundings. @@ -692,6 +735,18 @@ liquid.meld-aspect.name = [#cbdbfc]Aspect liquid.meld-aspect.description = Unstable alternative power source. Refinable. liquid.meld-aspect.details = Mixed primordial aspects. +liquid.meld-fumes.name = [#5b4739]Fumes +liquid.meld-fumes.description = Passively seeps into conductive materials. Used for a variety of metallurgic and restorative appliances. +liquid.meld-fumes.details = Smoggy primordial aspects. + +liquid.meld-pollutant-mixture.name = [#cb8650][#6b4e4e]Pollutant Mix[] +liquid.meld-pollutant-mixture.description = A mix of common aspects in the atmosphere of Ikaru. Emitted by [accent]aether vents[].\n\nCan be used in place of [#cb8650]Aether[] +liquid.meld-pollutant-mixture.details = A mixture of secondary aspects. + +liquid.meld-bound-aspect.name = [#a451c8]Bound Aspect[] +liquid.meld-bound-aspect.description = A highly energy dense, stable fuel.\n\nCan be used in place of [#cbdbfc]Aspect[] +liquid.meld-bound-aspect.details = Confusing mixture of primordial aspects + liquid.meld-nectar.name = [#b89f47]Nectar liquid.meld-nectar.description = Used as a potent coolant. Can be refined into [#89828c]Mercury[] over high heat with the right reagents. Encourages a slight mending effect on units. liquid.meld-nectar.details = Blood of the swamp. diff --git a/assets/bundles/bundle.shitpost b/assets/bundles/bundle.shitpost new file mode 100644 index 0000000..4806279 --- /dev/null +++ b/assets/bundles/bundle.shitpost @@ -0,0 +1,8 @@ +item.meld-glass-mallow.name = Pan-fried Plates + +item.meld-crucible-plating.name = Boiled Plates + +block.meld-sonar-spire.name = Slay the Sonar Spire + +block.meld-manual-valve.name = Gabe Nuel's Wife +block.meld-pressure-vent.name = Amogus Escape route \ No newline at end of file diff --git a/assets/maps/gameplay-testmap-2.msav b/assets/maps/gameplay-testmap-2.msav index 35af6f9..541753e 100644 Binary files a/assets/maps/gameplay-testmap-2.msav and b/assets/maps/gameplay-testmap-2.msav differ diff --git a/assets/maps/heavy-industry-test-1.msav b/assets/maps/heavy-industry-test-1.msav new file mode 100644 index 0000000..7ab6586 Binary files /dev/null and b/assets/maps/heavy-industry-test-1.msav differ diff --git a/assets/sprites/blocks/distrib/chute-bottom-0.png b/assets/sprites/blocks/distrib/chute-bottom-0.png new file mode 100644 index 0000000..741b480 Binary files /dev/null and b/assets/sprites/blocks/distrib/chute-bottom-0.png differ diff --git a/assets/sprites/blocks/distrib/chute-bottom-1.png b/assets/sprites/blocks/distrib/chute-bottom-1.png new file mode 100644 index 0000000..77d3b59 Binary files /dev/null and b/assets/sprites/blocks/distrib/chute-bottom-1.png differ diff --git a/assets/sprites/blocks/distrib/chute-bottom-2.png b/assets/sprites/blocks/distrib/chute-bottom-2.png new file mode 100644 index 0000000..379236f Binary files /dev/null and b/assets/sprites/blocks/distrib/chute-bottom-2.png differ diff --git a/assets/sprites/blocks/distrib/chute-bottom-3.png b/assets/sprites/blocks/distrib/chute-bottom-3.png new file mode 100644 index 0000000..0869160 Binary files /dev/null and b/assets/sprites/blocks/distrib/chute-bottom-3.png differ diff --git a/assets/sprites/blocks/distrib/chute-bottom-4.png b/assets/sprites/blocks/distrib/chute-bottom-4.png new file mode 100644 index 0000000..e5f1a5a Binary files /dev/null and b/assets/sprites/blocks/distrib/chute-bottom-4.png differ diff --git a/assets/sprites/chute-bridge-arrow.png b/assets/sprites/blocks/distrib/chute-bridge-arrow.png similarity index 100% rename from assets/sprites/chute-bridge-arrow.png rename to assets/sprites/blocks/distrib/chute-bridge-arrow.png diff --git a/assets/sprites/chute-bridge-bottom.png b/assets/sprites/blocks/distrib/chute-bridge-bottom.png similarity index 100% rename from assets/sprites/chute-bridge-bottom.png rename to assets/sprites/blocks/distrib/chute-bridge-bottom.png diff --git a/assets/sprites/chute-bridge-bridge.png b/assets/sprites/blocks/distrib/chute-bridge-bridge.png similarity index 100% rename from assets/sprites/chute-bridge-bridge.png rename to assets/sprites/blocks/distrib/chute-bridge-bridge.png diff --git a/assets/sprites/chute-bridge-dir.png b/assets/sprites/blocks/distrib/chute-bridge-dir.png similarity index 100% rename from assets/sprites/chute-bridge-dir.png rename to assets/sprites/blocks/distrib/chute-bridge-dir.png diff --git a/assets/sprites/chute-bridge.png b/assets/sprites/blocks/distrib/chute-bridge.png similarity index 100% rename from assets/sprites/chute-bridge.png rename to assets/sprites/blocks/distrib/chute-bridge.png diff --git a/assets/sprites/chute-bottom-4.png b/assets/sprites/blocks/distrib/chute-crossing-bottom.png similarity index 100% rename from assets/sprites/chute-bottom-4.png rename to assets/sprites/blocks/distrib/chute-crossing-bottom.png diff --git a/assets/sprites/chute-crossing.png b/assets/sprites/blocks/distrib/chute-crossing-top.png similarity index 100% rename from assets/sprites/chute-crossing.png rename to assets/sprites/blocks/distrib/chute-crossing-top.png diff --git a/assets/sprites/blocks/distrib/chute-crossing.png b/assets/sprites/blocks/distrib/chute-crossing.png new file mode 100644 index 0000000..4f7105e Binary files /dev/null and b/assets/sprites/blocks/distrib/chute-crossing.png differ diff --git a/assets/sprites/chute-overflow-top.png b/assets/sprites/blocks/distrib/chute-overflow-top.png similarity index 100% rename from assets/sprites/chute-overflow-top.png rename to assets/sprites/blocks/distrib/chute-overflow-top.png diff --git a/assets/sprites/chute-overflow.png b/assets/sprites/blocks/distrib/chute-overflow.png similarity index 100% rename from assets/sprites/chute-overflow.png rename to assets/sprites/blocks/distrib/chute-overflow.png diff --git a/assets/sprites/chute-router-top.png b/assets/sprites/blocks/distrib/chute-router-top.png similarity index 100% rename from assets/sprites/chute-router-top.png rename to assets/sprites/blocks/distrib/chute-router-top.png diff --git a/assets/sprites/chute-router.png b/assets/sprites/blocks/distrib/chute-router.png similarity index 100% rename from assets/sprites/chute-router.png rename to assets/sprites/blocks/distrib/chute-router.png diff --git a/assets/sprites/chute-top-0.png b/assets/sprites/blocks/distrib/chute-top-0.png similarity index 100% rename from assets/sprites/chute-top-0.png rename to assets/sprites/blocks/distrib/chute-top-0.png diff --git a/assets/sprites/chute-top-1.png b/assets/sprites/blocks/distrib/chute-top-1.png similarity index 100% rename from assets/sprites/chute-top-1.png rename to assets/sprites/blocks/distrib/chute-top-1.png diff --git a/assets/sprites/chute-top-2.png b/assets/sprites/blocks/distrib/chute-top-2.png similarity index 100% rename from assets/sprites/chute-top-2.png rename to assets/sprites/blocks/distrib/chute-top-2.png diff --git a/assets/sprites/chute-top-3.png b/assets/sprites/blocks/distrib/chute-top-3.png similarity index 100% rename from assets/sprites/chute-top-3.png rename to assets/sprites/blocks/distrib/chute-top-3.png diff --git a/assets/sprites/chute-top-4.png b/assets/sprites/blocks/distrib/chute-top-4.png similarity index 100% rename from assets/sprites/chute-top-4.png rename to assets/sprites/blocks/distrib/chute-top-4.png diff --git a/assets/sprites/chute-unloader-center.png b/assets/sprites/blocks/distrib/chute-unloader-center.png similarity index 100% rename from assets/sprites/chute-unloader-center.png rename to assets/sprites/blocks/distrib/chute-unloader-center.png diff --git a/assets/sprites/chute-unloader.png b/assets/sprites/blocks/distrib/chute-unloader.png similarity index 100% rename from assets/sprites/chute-unloader.png rename to assets/sprites/blocks/distrib/chute-unloader.png diff --git a/assets/sprites/unloading-hub-center.png b/assets/sprites/blocks/distrib/unloading-hub-center.png similarity index 100% rename from assets/sprites/unloading-hub-center.png rename to assets/sprites/blocks/distrib/unloading-hub-center.png diff --git a/assets/sprites/unloading-hub.png b/assets/sprites/blocks/distrib/unloading-hub.png similarity index 100% rename from assets/sprites/unloading-hub.png rename to assets/sprites/blocks/distrib/unloading-hub.png diff --git a/assets/sprites/blocks/environment/badlands/aspect-soil1.png b/assets/sprites/blocks/environment/badlands/aspect-soil1.png new file mode 100644 index 0000000..ade29f2 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/aspect-soil1.png differ diff --git a/assets/sprites/blocks/environment/badlands/aspect-soil2.png b/assets/sprites/blocks/environment/badlands/aspect-soil2.png new file mode 100644 index 0000000..981f518 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/aspect-soil2.png differ diff --git a/assets/sprites/blocks/environment/badlands/aspect-soil3.png b/assets/sprites/blocks/environment/badlands/aspect-soil3.png new file mode 100644 index 0000000..6d6c1dc Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/aspect-soil3.png differ diff --git a/assets/sprites/blocks/environment/badlands/cracked-sand-edge.png b/assets/sprites/blocks/environment/badlands/cracked-sand-edge.png new file mode 100644 index 0000000..60deeae Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/cracked-sand-edge.png differ diff --git a/assets/sprites/blocks/environment/badlands/cracked-sand1.png b/assets/sprites/blocks/environment/badlands/cracked-sand1.png new file mode 100644 index 0000000..e56e214 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/cracked-sand1.png differ diff --git a/assets/sprites/blocks/environment/badlands/cracked-sand2.png b/assets/sprites/blocks/environment/badlands/cracked-sand2.png new file mode 100644 index 0000000..3d3421a Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/cracked-sand2.png differ diff --git a/assets/sprites/blocks/environment/badlands/cracked-sand3.png b/assets/sprites/blocks/environment/badlands/cracked-sand3.png new file mode 100644 index 0000000..08acffa Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/cracked-sand3.png differ diff --git a/assets/sprites/blocks/environment/badlands/cracked-sand4.png b/assets/sprites/blocks/environment/badlands/cracked-sand4.png new file mode 100644 index 0000000..f7bde50 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/cracked-sand4.png differ diff --git a/assets/sprites/blocks/environment/badlands/crackstone-wall1.png b/assets/sprites/blocks/environment/badlands/crackstone-wall1.png new file mode 100644 index 0000000..dca88a7 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/crackstone-wall1.png differ diff --git a/assets/sprites/blocks/environment/badlands/crackstone-wall2.png b/assets/sprites/blocks/environment/badlands/crackstone-wall2.png new file mode 100644 index 0000000..e397b14 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/crackstone-wall2.png differ diff --git a/assets/sprites/blocks/environment/badlands/mallow-wall1.png b/assets/sprites/blocks/environment/badlands/mallow-wall1.png new file mode 100644 index 0000000..a606a30 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/mallow-wall1.png differ diff --git a/assets/sprites/blocks/environment/badlands/mallow-wall2.png b/assets/sprites/blocks/environment/badlands/mallow-wall2.png new file mode 100644 index 0000000..4b228b0 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/mallow-wall2.png differ diff --git a/assets/sprites/blocks/environment/badlands/red-sand-meld1.png b/assets/sprites/blocks/environment/badlands/red-sand-meld1.png new file mode 100644 index 0000000..4d32a61 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/red-sand-meld1.png differ diff --git a/assets/sprites/blocks/environment/badlands/red-sand-meld2.png b/assets/sprites/blocks/environment/badlands/red-sand-meld2.png new file mode 100644 index 0000000..8a0c175 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/red-sand-meld2.png differ diff --git a/assets/sprites/blocks/environment/badlands/red-sand-meld3.png b/assets/sprites/blocks/environment/badlands/red-sand-meld3.png new file mode 100644 index 0000000..f4bf276 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/red-sand-meld3.png differ diff --git a/assets/sprites/blocks/environment/badlands/red-sand-weave1.png b/assets/sprites/blocks/environment/badlands/red-sand-weave1.png new file mode 100644 index 0000000..3b666b0 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/red-sand-weave1.png differ diff --git a/assets/sprites/blocks/environment/badlands/red-sand-weave2.png b/assets/sprites/blocks/environment/badlands/red-sand-weave2.png new file mode 100644 index 0000000..8706a0f Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/red-sand-weave2.png differ diff --git a/assets/sprites/blocks/environment/badlands/red-sand-weave3.png b/assets/sprites/blocks/environment/badlands/red-sand-weave3.png new file mode 100644 index 0000000..5cf6278 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/red-sand-weave3.png differ diff --git a/assets/sprites/blocks/environment/badlands/red-sand1.png b/assets/sprites/blocks/environment/badlands/red-sand1.png new file mode 100644 index 0000000..b0b84c4 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/red-sand1.png differ diff --git a/assets/sprites/blocks/environment/badlands/red-sand2.png b/assets/sprites/blocks/environment/badlands/red-sand2.png new file mode 100644 index 0000000..a329ed8 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/red-sand2.png differ diff --git a/assets/sprites/blocks/environment/badlands/red-sand3.png b/assets/sprites/blocks/environment/badlands/red-sand3.png new file mode 100644 index 0000000..a06eb41 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/red-sand3.png differ diff --git a/assets/sprites/blocks/environment/badlands/silver-deposit-depleted2.png b/assets/sprites/blocks/environment/badlands/silver-deposit-depleted2.png new file mode 100644 index 0000000..f695e38 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/silver-deposit-depleted2.png differ diff --git a/assets/sprites/blocks/environment/badlands/silver-deposit-depleted3.png b/assets/sprites/blocks/environment/badlands/silver-deposit-depleted3.png new file mode 100644 index 0000000..ab7f9d7 Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/silver-deposit-depleted3.png differ diff --git a/assets/sprites/blocks/environment/badlands/vitric-weave1.png b/assets/sprites/blocks/environment/badlands/vitric-weave1.png new file mode 100644 index 0000000..d49cebc Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/vitric-weave1.png differ diff --git a/assets/sprites/blocks/environment/badlands/vitric-weave2.png b/assets/sprites/blocks/environment/badlands/vitric-weave2.png new file mode 100644 index 0000000..c9d212c Binary files /dev/null and b/assets/sprites/blocks/environment/badlands/vitric-weave2.png differ diff --git a/assets/sprites/blocks/environment/barrens/bedrock-edge.png b/assets/sprites/blocks/environment/barrens/bedrock-edge.png new file mode 100644 index 0000000..648aa78 Binary files /dev/null and b/assets/sprites/blocks/environment/barrens/bedrock-edge.png differ diff --git a/assets/sprites/blocks/environment/barrens/bedrock1.png b/assets/sprites/blocks/environment/barrens/bedrock1.png index dc5a571..576b931 100644 Binary files a/assets/sprites/blocks/environment/barrens/bedrock1.png and b/assets/sprites/blocks/environment/barrens/bedrock1.png differ diff --git a/assets/sprites/blocks/environment/barrens/bedrock2.png b/assets/sprites/blocks/environment/barrens/bedrock2.png index cac5552..d2a3cde 100644 Binary files a/assets/sprites/blocks/environment/barrens/bedrock2.png and b/assets/sprites/blocks/environment/barrens/bedrock2.png differ diff --git a/assets/sprites/blocks/environment/barrens/bedrock3.png b/assets/sprites/blocks/environment/barrens/bedrock3.png index 216f5d9..a660cdb 100644 Binary files a/assets/sprites/blocks/environment/barrens/bedrock3.png and b/assets/sprites/blocks/environment/barrens/bedrock3.png differ diff --git a/assets/sprites/blocks/environment/barrens/elnar-silt1.png b/assets/sprites/blocks/environment/barrens/elnar-silt1.png new file mode 100644 index 0000000..1b3025d Binary files /dev/null and b/assets/sprites/blocks/environment/barrens/elnar-silt1.png differ diff --git a/assets/sprites/blocks/environment/barrens/elnar-silt2.png b/assets/sprites/blocks/environment/barrens/elnar-silt2.png new file mode 100644 index 0000000..9c11030 Binary files /dev/null and b/assets/sprites/blocks/environment/barrens/elnar-silt2.png differ diff --git a/assets/sprites/blocks/environment/barrens/elnar-silt3.png b/assets/sprites/blocks/environment/barrens/elnar-silt3.png new file mode 100644 index 0000000..2d7e765 Binary files /dev/null and b/assets/sprites/blocks/environment/barrens/elnar-silt3.png differ diff --git a/assets/sprites/blocks/environment/barrens/elnar-silt4.png b/assets/sprites/blocks/environment/barrens/elnar-silt4.png new file mode 100644 index 0000000..6349d83 Binary files /dev/null and b/assets/sprites/blocks/environment/barrens/elnar-silt4.png differ diff --git a/assets/sprites/blocks/environment/barrens/embedded-elnar-overflowing1.png b/assets/sprites/blocks/environment/barrens/embedded-elnar-overflowing1.png new file mode 100644 index 0000000..fe5bc84 Binary files /dev/null and b/assets/sprites/blocks/environment/barrens/embedded-elnar-overflowing1.png differ diff --git a/assets/sprites/blocks/environment/barrens/embedded-elnar-overflowing2.png b/assets/sprites/blocks/environment/barrens/embedded-elnar-overflowing2.png new file mode 100644 index 0000000..07ee26c Binary files /dev/null and b/assets/sprites/blocks/environment/barrens/embedded-elnar-overflowing2.png differ diff --git a/assets/sprites/blocks/environment/barrens/embedded-elnar1.png b/assets/sprites/blocks/environment/barrens/embedded-elnar1.png new file mode 100644 index 0000000..f1d230d Binary files /dev/null and b/assets/sprites/blocks/environment/barrens/embedded-elnar1.png differ diff --git a/assets/sprites/blocks/environment/barrens/embedded-elnar2.png b/assets/sprites/blocks/environment/barrens/embedded-elnar2.png new file mode 100644 index 0000000..4bf05f7 Binary files /dev/null and b/assets/sprites/blocks/environment/barrens/embedded-elnar2.png differ diff --git a/assets/sprites/blocks/environment/barrens/tenbris-mix1.png b/assets/sprites/blocks/environment/barrens/tenbris-mix1.png new file mode 100644 index 0000000..25518da Binary files /dev/null and b/assets/sprites/blocks/environment/barrens/tenbris-mix1.png differ diff --git a/assets/sprites/blocks/environment/barrens/tenbris-mix2.png b/assets/sprites/blocks/environment/barrens/tenbris-mix2.png new file mode 100644 index 0000000..664a6f6 Binary files /dev/null and b/assets/sprites/blocks/environment/barrens/tenbris-mix2.png differ diff --git a/assets/sprites/blocks/environment/barrens/tenbris-ridges1.png b/assets/sprites/blocks/environment/barrens/tenbris-ridges1.png new file mode 100644 index 0000000..490c112 Binary files /dev/null and b/assets/sprites/blocks/environment/barrens/tenbris-ridges1.png differ diff --git a/assets/sprites/blocks/environment/barrens/tenbris-ridges2.png b/assets/sprites/blocks/environment/barrens/tenbris-ridges2.png new file mode 100644 index 0000000..b6e5deb Binary files /dev/null and b/assets/sprites/blocks/environment/barrens/tenbris-ridges2.png differ diff --git a/assets/sprites/blocks/fluid/channel-director.png b/assets/sprites/blocks/fluid/channel-director.png new file mode 100644 index 0000000..35b1b96 Binary files /dev/null and b/assets/sprites/blocks/fluid/channel-director.png differ diff --git a/assets/sprites/blocks/fluid/director/aspect-pipe-bottom-0.png b/assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-0.png similarity index 100% rename from assets/sprites/blocks/fluid/director/aspect-pipe-bottom-0.png rename to assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-0.png diff --git a/assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-1.png b/assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-1.png new file mode 100644 index 0000000..f876a72 Binary files /dev/null and b/assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-1.png differ diff --git a/assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-2.png b/assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-2.png new file mode 100644 index 0000000..1aea089 Binary files /dev/null and b/assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-2.png differ diff --git a/assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-3.png b/assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-3.png new file mode 100644 index 0000000..e506fa0 Binary files /dev/null and b/assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-3.png differ diff --git a/assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-4.png b/assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-4.png new file mode 100644 index 0000000..1465f60 Binary files /dev/null and b/assets/sprites/blocks/fluid/conduit/aspect-channel-bottom-4.png differ diff --git a/assets/sprites/blocks/fluid/conduit/aspect-channel-top-0.png b/assets/sprites/blocks/fluid/conduit/aspect-channel-top-0.png new file mode 100644 index 0000000..e7e4c94 Binary files /dev/null and b/assets/sprites/blocks/fluid/conduit/aspect-channel-top-0.png differ diff --git a/assets/sprites/blocks/fluid/conduit/aspect-channel-top-1.png b/assets/sprites/blocks/fluid/conduit/aspect-channel-top-1.png new file mode 100644 index 0000000..6e83bcc Binary files /dev/null and b/assets/sprites/blocks/fluid/conduit/aspect-channel-top-1.png differ diff --git a/assets/sprites/blocks/fluid/conduit/aspect-channel-top-2.png b/assets/sprites/blocks/fluid/conduit/aspect-channel-top-2.png new file mode 100644 index 0000000..3d64984 Binary files /dev/null and b/assets/sprites/blocks/fluid/conduit/aspect-channel-top-2.png differ diff --git a/assets/sprites/blocks/fluid/conduit/aspect-channel-top-3.png b/assets/sprites/blocks/fluid/conduit/aspect-channel-top-3.png new file mode 100644 index 0000000..c275ba7 Binary files /dev/null and b/assets/sprites/blocks/fluid/conduit/aspect-channel-top-3.png differ diff --git a/assets/sprites/blocks/fluid/conduit/aspect-channel-top-4.png b/assets/sprites/blocks/fluid/conduit/aspect-channel-top-4.png new file mode 100644 index 0000000..4046d12 Binary files /dev/null and b/assets/sprites/blocks/fluid/conduit/aspect-channel-top-4.png differ diff --git a/assets/sprites/blocks/fluid/director/aspect-pipe-bottom-1.png b/assets/sprites/blocks/fluid/director/aspect-pipe-bottom-1.png deleted file mode 100644 index ffa41c1..0000000 Binary files a/assets/sprites/blocks/fluid/director/aspect-pipe-bottom-1.png and /dev/null differ diff --git a/assets/sprites/blocks/fluid/director/aspect-pipe-bottom-2.png b/assets/sprites/blocks/fluid/director/aspect-pipe-bottom-2.png deleted file mode 100644 index 4bdb794..0000000 Binary files a/assets/sprites/blocks/fluid/director/aspect-pipe-bottom-2.png and /dev/null differ diff --git a/assets/sprites/blocks/fluid/director/aspect-pipe-bottom-3.png b/assets/sprites/blocks/fluid/director/aspect-pipe-bottom-3.png deleted file mode 100644 index bfd93ec..0000000 Binary files a/assets/sprites/blocks/fluid/director/aspect-pipe-bottom-3.png and /dev/null differ diff --git a/assets/sprites/blocks/fluid/director/aspect-pipe-bottom-4.png b/assets/sprites/blocks/fluid/director/aspect-pipe-bottom-4.png deleted file mode 100644 index 0517905..0000000 Binary files a/assets/sprites/blocks/fluid/director/aspect-pipe-bottom-4.png and /dev/null differ diff --git a/assets/sprites/blocks/fluid/director/aspect-pipe-preview.png b/assets/sprites/blocks/fluid/director/aspect-pipe-preview.png deleted file mode 100644 index de2c069..0000000 Binary files a/assets/sprites/blocks/fluid/director/aspect-pipe-preview.png and /dev/null differ diff --git a/assets/sprites/blocks/fluid/director/aspect-pipe-top-0.png b/assets/sprites/blocks/fluid/director/aspect-pipe-top-0.png deleted file mode 100644 index 5a79cbf..0000000 Binary files a/assets/sprites/blocks/fluid/director/aspect-pipe-top-0.png and /dev/null differ diff --git a/assets/sprites/blocks/fluid/director/aspect-pipe-top-1.png b/assets/sprites/blocks/fluid/director/aspect-pipe-top-1.png deleted file mode 100644 index fbcbc65..0000000 Binary files a/assets/sprites/blocks/fluid/director/aspect-pipe-top-1.png and /dev/null differ diff --git a/assets/sprites/blocks/fluid/director/aspect-pipe-top-2.png b/assets/sprites/blocks/fluid/director/aspect-pipe-top-2.png deleted file mode 100644 index 737f5e1..0000000 Binary files a/assets/sprites/blocks/fluid/director/aspect-pipe-top-2.png and /dev/null differ diff --git a/assets/sprites/blocks/fluid/director/aspect-pipe-top-3.png b/assets/sprites/blocks/fluid/director/aspect-pipe-top-3.png deleted file mode 100644 index ac03a5d..0000000 Binary files a/assets/sprites/blocks/fluid/director/aspect-pipe-top-3.png and /dev/null differ diff --git a/assets/sprites/blocks/fluid/director/aspect-pipe-top-4.png b/assets/sprites/blocks/fluid/director/aspect-pipe-top-4.png deleted file mode 100644 index e031d19..0000000 Binary files a/assets/sprites/blocks/fluid/director/aspect-pipe-top-4.png and /dev/null differ diff --git a/assets/sprites/blocks/fluid/manual-valve-on.png b/assets/sprites/blocks/fluid/manual-valve-on.png new file mode 100644 index 0000000..1b212ed Binary files /dev/null and b/assets/sprites/blocks/fluid/manual-valve-on.png differ diff --git a/assets/sprites/blocks/fluid/manual-valve.png b/assets/sprites/blocks/fluid/manual-valve.png new file mode 100644 index 0000000..e1e329f Binary files /dev/null and b/assets/sprites/blocks/fluid/manual-valve.png differ diff --git a/assets/sprites/blocks/fluid/pipebox-direction.png b/assets/sprites/blocks/fluid/pipebox-direction.png new file mode 100644 index 0000000..74c36fa Binary files /dev/null and b/assets/sprites/blocks/fluid/pipebox-direction.png differ diff --git a/assets/sprites/blocks/fluid/pipebox-marker-on.png b/assets/sprites/blocks/fluid/pipebox-marker-on.png new file mode 100644 index 0000000..c017dd7 Binary files /dev/null and b/assets/sprites/blocks/fluid/pipebox-marker-on.png differ diff --git a/assets/sprites/blocks/fluid/pipebox-marker.png b/assets/sprites/blocks/fluid/pipebox-marker.png new file mode 100644 index 0000000..0b62bfe Binary files /dev/null and b/assets/sprites/blocks/fluid/pipebox-marker.png differ diff --git a/assets/sprites/blocks/fluid/pipebox-on.png b/assets/sprites/blocks/fluid/pipebox-on.png new file mode 100644 index 0000000..4669183 Binary files /dev/null and b/assets/sprites/blocks/fluid/pipebox-on.png differ diff --git a/assets/sprites/blocks/fluid/pipebox.png b/assets/sprites/blocks/fluid/pipebox.png new file mode 100644 index 0000000..be38a29 Binary files /dev/null and b/assets/sprites/blocks/fluid/pipebox.png differ diff --git a/assets/sprites/blocks/fluid/pressure-vent-bottom.png b/assets/sprites/blocks/fluid/pressure-vent-bottom.png new file mode 100644 index 0000000..9694a01 Binary files /dev/null and b/assets/sprites/blocks/fluid/pressure-vent-bottom.png differ diff --git a/assets/sprites/blocks/fluid/pressure-vent.png b/assets/sprites/blocks/fluid/pressure-vent.png new file mode 100644 index 0000000..2d14bb9 Binary files /dev/null and b/assets/sprites/blocks/fluid/pressure-vent.png differ diff --git a/assets/sprites/blocks/fluid/valve-controller-bottom.png b/assets/sprites/blocks/fluid/valve-controller-bottom.png new file mode 100644 index 0000000..c16ba8a Binary files /dev/null and b/assets/sprites/blocks/fluid/valve-controller-bottom.png differ diff --git a/assets/sprites/blocks/fluid/valve-controller-sign-inverted.png b/assets/sprites/blocks/fluid/valve-controller-sign-inverted.png new file mode 100644 index 0000000..e3f23a4 Binary files /dev/null and b/assets/sprites/blocks/fluid/valve-controller-sign-inverted.png differ diff --git a/assets/sprites/blocks/fluid/valve-controller-sign.png b/assets/sprites/blocks/fluid/valve-controller-sign.png new file mode 100644 index 0000000..514ff15 Binary files /dev/null and b/assets/sprites/blocks/fluid/valve-controller-sign.png differ diff --git a/assets/sprites/blocks/fluid/valve-controller.png b/assets/sprites/blocks/fluid/valve-controller.png new file mode 100644 index 0000000..08a87d3 Binary files /dev/null and b/assets/sprites/blocks/fluid/valve-controller.png differ diff --git a/assets/sprites/blocks/fluid/valve/intake-valve-on.png b/assets/sprites/blocks/fluid/valve/intake-valve-on.png new file mode 100644 index 0000000..1c605fb Binary files /dev/null and b/assets/sprites/blocks/fluid/valve/intake-valve-on.png differ diff --git a/assets/sprites/blocks/fluid/valve/intake-valve.png b/assets/sprites/blocks/fluid/valve/intake-valve.png new file mode 100644 index 0000000..cbc00fc Binary files /dev/null and b/assets/sprites/blocks/fluid/valve/intake-valve.png differ diff --git a/assets/sprites/blocks/production/fumehood.png b/assets/sprites/blocks/production/fumehood.png new file mode 100644 index 0000000..1f2defb Binary files /dev/null and b/assets/sprites/blocks/production/fumehood.png differ diff --git a/assets/sprites/blocks/walls/shadesteel-shingles.png b/assets/sprites/blocks/walls/shadesteel-shingles.png new file mode 100644 index 0000000..c90d4e3 Binary files /dev/null and b/assets/sprites/blocks/walls/shadesteel-shingles.png differ diff --git a/assets/sprites/blocks/walls/silver-husk-bottom.png b/assets/sprites/blocks/walls/silver-husk-bottom.png new file mode 100644 index 0000000..5e8a635 Binary files /dev/null and b/assets/sprites/blocks/walls/silver-husk-bottom.png differ diff --git a/assets/sprites/blocks/walls/silver-husk-preview.png b/assets/sprites/blocks/walls/silver-husk-preview.png new file mode 100644 index 0000000..0f69e52 Binary files /dev/null and b/assets/sprites/blocks/walls/silver-husk-preview.png differ diff --git a/assets/sprites/blocks/walls/silver-husk.png b/assets/sprites/blocks/walls/silver-husk.png new file mode 100644 index 0000000..312ad1b Binary files /dev/null and b/assets/sprites/blocks/walls/silver-husk.png differ diff --git a/assets/sprites/chute-bottom-0.png b/assets/sprites/chute-bottom-0.png deleted file mode 100644 index 300d1e1..0000000 Binary files a/assets/sprites/chute-bottom-0.png and /dev/null differ diff --git a/assets/sprites/chute-bottom-1.png b/assets/sprites/chute-bottom-1.png deleted file mode 100644 index b95e3b7..0000000 Binary files a/assets/sprites/chute-bottom-1.png and /dev/null differ diff --git a/assets/sprites/chute-bottom-2.png b/assets/sprites/chute-bottom-2.png deleted file mode 100644 index ff6b62f..0000000 Binary files a/assets/sprites/chute-bottom-2.png and /dev/null differ diff --git a/assets/sprites/chute-bottom-3.png b/assets/sprites/chute-bottom-3.png deleted file mode 100644 index edcd084..0000000 Binary files a/assets/sprites/chute-bottom-3.png and /dev/null differ diff --git a/assets/sprites/items/clay-mallow.png b/assets/sprites/items/clay-mallow.png new file mode 100644 index 0000000..3401583 Binary files /dev/null and b/assets/sprites/items/clay-mallow.png differ diff --git a/assets/sprites/items/heavy ind/ferric-geode.png b/assets/sprites/items/heavy ind/ferric-geode.png new file mode 100644 index 0000000..8e6c394 Binary files /dev/null and b/assets/sprites/items/heavy ind/ferric-geode.png differ diff --git a/assets/sprites/items/heavy ind/motis.png b/assets/sprites/items/heavy ind/motis.png new file mode 100644 index 0000000..cb64233 Binary files /dev/null and b/assets/sprites/items/heavy ind/motis.png differ diff --git a/assets/sprites/items/stony-particulate.png b/assets/sprites/items/stony-particulate.png new file mode 100644 index 0000000..92713c0 Binary files /dev/null and b/assets/sprites/items/stony-particulate.png differ diff --git a/assets/sprites/liquids/bound-aspect.png b/assets/sprites/liquids/bound-aspect.png new file mode 100644 index 0000000..ecbb649 Binary files /dev/null and b/assets/sprites/liquids/bound-aspect.png differ diff --git a/assets/sprites/liquids/pollutant-mixture.png b/assets/sprites/liquids/pollutant-mixture.png new file mode 100644 index 0000000..2e94f21 Binary files /dev/null and b/assets/sprites/liquids/pollutant-mixture.png differ diff --git a/mod.hjson b/mod.hjson index 14e1686..f78e66c 100644 --- a/mod.hjson +++ b/mod.hjson @@ -14,7 +14,7 @@ main: "meld.Meld" description: "Meld Java.\n\n[[]accent]Only has custom game content! (play the info map to understand)[[]]\n\nIncompatable with hjson meld" #the mod version -version: gameplay test 1.01 +version: gameplay expirimental v1 #the minimum game build required to run this mod minGameVersion: 154 diff --git a/src/meld/Meld.java b/src/meld/Meld.java index 74faef5..112f64a 100644 --- a/src/meld/Meld.java +++ b/src/meld/Meld.java @@ -1,11 +1,13 @@ package meld; import arc.*; +import arc.graphics.Color; import arc.math.geom.Geometry; import arc.math.geom.Point2; import arc.struct.IntSeq; import arc.struct.Seq; import arc.util.Time; +import arc.util.Tmp; import meld.content.*; import meld.core.*; import mindustry.Vars; @@ -31,6 +33,28 @@ public Meld(){ public static String prefix(String in){ return name + "-" + in; } + private static final StringBuilder b = new StringBuilder(); + + public static String gradient(String in, Color... colors){ + if(colors.length == 1) return "[#" + colors[0].toString().substring(0, 6) + "]" + in + "[]"; + + b.setLength(0); + b.trimToSize(); + int length = in.length(); + int spaces = 0; + + for(int i = 0; i < length; i++){ + char ind = in.charAt(i); + if(Character.isWhitespace(ind)){ + spaces++; + b.append(' '); + continue; + } + b.append("[#").append(Tmp.c1.set(colors[0]).lerp(colors, (float) i / (length - spaces)).toString(), 0, 6).append("]").append(ind).append("[]"); + } + + return b.toString(); + } @Override public void init() { @@ -61,10 +85,17 @@ public void init() { @Override public void loadContent(){ MeldStatusEffects.load(); + MeldBullets.load(); MeldUnits.load(); MeldItems.load(); MeldLiquids.load(); MeldBlocks.load(); MeldEnvironment.load(); + + Vars.content.blocks().each(b -> { + if(b.minfo.mod != null && b.minfo.mod.name.equals("meld")){ + b.deconstructDropAllLiquid = true; + } + }); } } diff --git a/src/meld/content/MeldBlocks.java b/src/meld/content/MeldBlocks.java index b948d51..d31db7d 100644 --- a/src/meld/content/MeldBlocks.java +++ b/src/meld/content/MeldBlocks.java @@ -6,12 +6,19 @@ import meld.entities.bullet.OutflowBulletType; import meld.entities.bullet.TransitionBulletType; import meld.graphics.*; +import meld.world.blocks.consumers.ConsumeAspects; import meld.world.blocks.*; import meld.world.blocks.crafting.ModularCrafter; -import meld.world.blocks.crafting.modules.ConsumeGate; -import meld.world.blocks.crafting.modules.ConsumeLiquidModule; -import meld.world.blocks.crafting.modules.MultiplierModule; -import meld.world.blocks.crafting.modules.ProduceLiquidModule; +import meld.world.blocks.crafting.RecipeCrafter; +import meld.world.blocks.crafting.recipe.ItemRecipe; +import meld.world.blocks.crafting.recipe.SpoolRecipe; +import meld.world.blocks.crafting.modules.*; +import meld.world.blocks.crafting.modules.GateModule.ConsumeCondition; +import meld.world.blocks.crafting.modules.GateModule.OutputCondition; +import meld.world.blocks.crafting.recipe.TimedRecipe; +import meld.world.blocks.fluid.*; +import meld.world.blocks.items.PriorityInputSplitter; +import meld.world.blocks.production.SingleBeamDrill; import meld.world.meta.*; import mindustry.Vars; import mindustry.content.Fx; @@ -26,17 +33,21 @@ import mindustry.entities.pattern.ShootSpread; import mindustry.gen.Sounds; import mindustry.graphics.Layer; +import mindustry.graphics.Pal; import mindustry.type.*; import mindustry.world.Block; import mindustry.world.blocks.defense.ForceProjector; +import mindustry.world.blocks.defense.RegenProjector; import mindustry.world.blocks.defense.Wall; import mindustry.world.blocks.defense.turrets.ItemTurret; import mindustry.world.blocks.defense.turrets.LiquidTurret; import mindustry.world.blocks.distribution.*; +import mindustry.world.blocks.liquid.ArmoredConduit; import mindustry.world.blocks.liquid.Conduit; import mindustry.world.blocks.liquid.LiquidJunction; import mindustry.world.blocks.liquid.LiquidRouter; import mindustry.world.blocks.production.*; +import mindustry.world.blocks.storage.Unloader; import mindustry.world.blocks.units.UnitFactory; import mindustry.world.consumers.ConsumeLiquid; import mindustry.world.draw.*; @@ -47,16 +58,27 @@ public class MeldBlocks { //Strata blocks first - public static Block chute, chuteRouter, chuteBridge, chuteJunction, chuteOverflow; + public static Block chute, chuteRouter, chuteBridge, chuteJunction, chuteOverflow, unloadingHub; - public static Block sonarSpire, movementAnchor, nullifier; + public static Block sonarSpire, movementAnchor, nullifier, + //Bruisekit: Targets largest, highest hp blocks, functional blocks first, continuously heals - public static Block coreRaft, aetherAccumulator, elementalBlaster, earthboundInfuser, sharkFactory; + //Gauze chainheals smallest, lowest hp blocks, low target prio blocks first. - public static Block channelNode, channelFace, aspectOutlet, aspectPipe; + //Suture shoots healing needles in a cone at the closest damaged block. Impales enemies, causing them to take constant chip damage and be sedated. + bruisekit, gauze, suture; + + public static Block coreRaft, aetherAccumulator, elementalBlaster, pneumaticPulsear, + earthboundInfuser, fumehood, sharkFactory; + + public static ModularCrafter gasKiln, rotaryKiln, pneumaticExtruder; + + public static Block channelNode, channelFace, aspectOutlet, aspectChannel, channelDirector, channelVent, manualValve, intakeValve, valveController, pipebox; public static Block sunder, molotov, vivisection; + public static Block silverHusk, shadesteelShingles; + //Meld blocks public static Block pipeline, pipelineRouter, pipelineCrossing, pipelineBridge, meldCannon, meldMortar, @@ -75,13 +97,14 @@ public static Item item(String name){ public static void load(){ - channelFace = new LiquidJunction("channel-face"){{ + channelFace = new FlexibleSizeJunction("channel-face"){{ requirements(Category.liquid, with( MeldItems.debris, 2 )); health = 120; solid = false; placeableLiquid = true; + usePassedOffset = false; }}; channelNode = new LiquidRouter("channel-node"){{ @@ -90,50 +113,162 @@ public static void load(){ )); health = 120; - liquidCapacity = 100; + liquidCapacity = 200; solid = false; placeableLiquid = true; }}; - aspectOutlet = new GenericCrafter("aspect-outlet"){{ + aspectOutlet = new RecipeCrafter("aspect-outlet"){{ + outputDirections.putAll(MeldLiquids.aspect, new int[]{0}, MeldLiquids.boundAspect, new int[]{0}); + requirements(Category.liquid, with( MeldItems.debris, 7 )); health = 200; + solid = false; + hasLiquids = true; + placeableLiquid = true; - liquidOutputDirections = new int[]{0}; + //TODO: WE DON'T TALK ABOUT THAT WE DON'T TALK ABOUT THAT WE DON'T TALK ABOUT THAT WE DON'T TAAAAAAAAAAAA + //liquidOutputDirections = new int[]{0}; rotate = true; quickRotate = true; drawer = new DrawMulti( new DrawRegion("-bottom"), - new DrawLiquidTile(), + new DrawLiquidTile(){{ + drawLiquid = MeldLiquids.aspect; + }}, + new DrawLiquidTile(){{ + drawLiquid = MeldLiquids.boundAspect; + }}, new DrawRegion(), new DrawSideRegion() ); - consume(new ConsumeLiquid( - MeldLiquids.aether, outletRate/10f - )); + //consumeLiquid(MeldLiquids.aether, outletRate/10); + + liquidCapacity = 100; - outputLiquid = new LiquidStack(MeldLiquids.aspect, outletRate); + inputLiquidSlots = 1; + outputLiquidSlots = 1; + recipes.addAll( + new TimedRecipe(){{ + craftTime = 10; + float multi = MeldLiquids.aetherEfficiencies.get(MeldLiquids.aether, 1); + float density = MeldLiquids.aetherDensities.get(MeldLiquids.aether, 1); + inputLiquids = LiquidStack.with(MeldLiquids.aether, outletRate/density); + outputLiquids = LiquidStack.with(MeldLiquids.aspect, outletRate * multi * 10); + }}, + new TimedRecipe(){{ + craftTime = 10; + float multi = MeldLiquids.aetherEfficiencies.get(MeldLiquids.pollutantMixture, 1); + float density = MeldLiquids.aetherDensities.get(MeldLiquids.pollutantMixture, 1); + inputLiquids = LiquidStack.with(MeldLiquids.pollutantMixture, outletRate/density); + outputLiquids = LiquidStack.with(MeldLiquids.boundAspect, outletRate * multi * 10); + }} + ); }}; - aspectPipe = new AspectPipe("aspect-pipe"){{ + aspectChannel = new VisualAspectPipe("aspect-channel"){{ requirements(Category.liquid, with( - MeldItems.silver, 3 + MeldItems.annealedSilver, 5, MeldItems.glassMallows, 2 )); leaks = false; - health = 120; + health = 200; + armor = 2; + insulated = true; placeableLiquid = true; liquidCapacity = 80; size = 1; botColor = Color.white; + junctionReplacement = channelFace; + }}; + + channelDirector = new ChannelDirector("channel-director"){{ + requirements(Category.liquid, with( + MeldItems.debris, 5 + )); + + health = 200; + + placeableLiquid = true; + liquidPressure = 0.5f; + + liquidCapacity = 80; + size = 1; + }}; + + //TODO: Lock players out of using in badlands/storm plains route if waste becomes too big of an issue + channelVent = new ChannelVent("pressure-vent"){{ + requirements(Category.liquid, with( + MeldItems.debris, 8 + )); + health = 180; + armor = 1; + + minPressure = -0.25f; + ventRate = 0.5f; + + liquidCapacity = 100; + solid = false; + placeableLiquid = true; + }}; + + manualValve = new ChannelValve("manual-valve"){{ + requirements(Category.liquid, with( + MeldItems.debris, 8 + )); + + health = 120; + + solid = false; + placeableLiquid = true; + }}; + + intakeValve = new ChannelValve("intake-valve"){{ + requirements(Category.liquid, with( + MeldItems.debris, 80, + MeldItems.shadesteel, 48 + )); + size = 3; + + health = 800; + armor = 8; + + solid = false; + placeableLiquid = true; + }}; + + valveController = new ValveController("valve-controller"){{ + requirements(Category.liquid, with( + MeldItems.debris, 12, + MeldItems.aspectPipe, 6 + )); + size = 1; + + health = 120; + + solid = false; + placeableLiquid = true; + }}; + + pipebox = new Pipebox("pipebox") {{ + requirements(Category.liquid, with( + MeldItems.debris, 2, + MeldItems.aspectPipe, 4 + )); + size = 1; + + health = 120; + + solid = false; + placeableLiquid = true; }}; sunder = new ItemTurret("sunder"){{ @@ -291,146 +426,179 @@ public static void load(){ inaccuracy = 2; shootCone = 5; - ammoTypes.put( - MeldItems.silver, - new OutflowBulletType(){{ - //HHJKGHJGJK. - collidesTiles = false; - collides = false; - collidesAir = false; - scaleLife = true; - hitShake = 1.0F; - hitSound = Sounds.explosionArtillery; - hitEffect = Fx.flakExplosion; - shootEffect = Fx.shootBig; - shrinkX = 0.25f; - shrinkY = 0.8f; - shrinkInterp = Interp.slope; - trailEffect = Fx.artilleryTrail; - trailChance = 0.35f; - - speed = 7; - damage = 1; - lifetime = 46; - width = 18; - height = 24; - status = MeldStatusEffects.aspectBurn; - statusDuration = 300; + BulletType molBullet = new OutflowBulletType(){{ + //HHJKGHJGJK. + collidesTiles = false; + collides = false; + collidesAir = false; + scaleLife = true; + hitShake = 1.0F; + hitSound = Sounds.explosionArtillery; + hitEffect = Fx.flakExplosion; + shootEffect = Fx.shootBig; + shrinkX = 0.25f; + shrinkY = 0.8f; + shrinkInterp = Interp.slope; + trailEffect = Fx.artilleryTrail; + trailChance = 0.35f; + + speed = 7; + damage = 1; + lifetime = 46; + width = 18; + height = 24; + status = MeldStatusEffects.aspectBurn; + statusDuration = 300; + frontColor = Color.white; + backColor = Color.valueOf("cbdbfc"); + + splashDamage = 4; + splashDamageRadius = 8; + + collidesTiles = false; + makeFire = true; + hitShake = 2.5f; + + despawnHit = true; + fragOnAbsorb = false; + trailColor = Color.valueOf("cbdbfc"); + ammoMultiplier = 1; + fragBullets = 24; + fragVelocityMin = 0.8f; + fragVelocityMax = 1; + fragLifeMin = 0.6f; + + fragRandomSpread = 360; + + outflowBullet = new ExplosionBulletType(){{ + hitEffect = despawnEffect = Fx.none; + damage = splashDamage = 0; + fragBullets = 3; + fragRandomSpread = 15; + fragLifeMin = 0.5f; + killShooter = false; + + fragBullet = new BasicBulletType() {{ + lightRadius = 0; + speed = 8.5f; + drag = 0.03f; + damage = 2; + lifetime = 25; + pierce = true; + pierceCap = 4; + removeAfterPierce = true; + pierceArmor = true; + absorbable = false; + + + width = 7; + height = 16; + shrinkX = 1; + shrinkY = 1; frontColor = Color.white; backColor = Color.valueOf("cbdbfc"); - - splashDamage = 4; + splashDamage = 3; splashDamageRadius = 8; - - collidesTiles = false; makeFire = true; - hitShake = 2.5f; + collidesAir = false; + despawnHit = false; + hitEffect = despawnEffect = Fx.none; - despawnHit = true; - fragOnAbsorb = false; - trailColor = Color.valueOf("cbdbfc"); - ammoMultiplier = 1; - fragBullets = 24; - fragVelocityMin = 0.8f; - fragVelocityMax = 1; - fragLifeMin = 0.6f; - - fragRandomSpread = 360; - - outflowBullet = new ExplosionBulletType(){{ - hitEffect = despawnEffect = Fx.none; - damage = splashDamage = 0; - fragBullets = 3; - fragRandomSpread = 15; - fragLifeMin = 0.5f; - killShooter = false; - - fragBullet = new BasicBulletType() {{ - lightRadius = 0; - speed = 8.5f; - drag = 0.03f; - damage = 2; - lifetime = 25; - pierce = true; - pierceCap = 4; - removeAfterPierce = true; - pierceArmor = true; - absorbable = false; - - - width = 7; - height = 16; - shrinkX = 1; - shrinkY = 1; - frontColor = Color.white; - backColor = Color.valueOf("cbdbfc"); - splashDamage = 3; - splashDamageRadius = 8; - makeFire = true; - collidesAir = false; - despawnHit = false; - hitEffect = despawnEffect = Fx.none; - - knockback = 0.35f; - impact = true; - }}; - }}; + knockback = 0.35f; + impact = true; + }}; + }}; - fragBullet = new BasicBulletType(){{ - lightRadius = 0; - speed = 4.5f; - drag = 0.04f; - damage = 2; - lifetime = 20; - pierce = true; - pierceCap = 2; - pierceArmor = true; - absorbable = false; + fragBullet = new BasicBulletType(){{ + lightRadius = 0; + speed = 4.5f; + drag = 0.04f; + damage = 2; + lifetime = 20; + pierce = true; + pierceCap = 2; + pierceArmor = true; + absorbable = false; + + + width = 9; + height = 13; + shrinkX = 1; + shrinkY = 1; + status = StatusEffects.burning; + statusDuration = 120; + frontColor = Color.white; + backColor = Color.valueOf("cbdbfc"); + splashDamage = 5; + splashDamageRadius = 8; + makeFire = true; + collidesAir = false; + despawnHit = false; + hitEffect = despawnEffect = Fx.none; + + knockback = 0.35f; + impact = true; + + fragRandomSpread = 0; + fragBullets = 1; + fragBullet = new BasicBulletType(){{ + width = height = 2; + speed = 6; + lifetime = 8; + shrinkX = shrinkY = 1; + shrinkInterp = Interp.pow2In; - width = 9; - height = 13; - shrinkX = 1; - shrinkY = 1; - status = StatusEffects.burning; - statusDuration = 120; - frontColor = Color.white; - backColor = Color.valueOf("cbdbfc"); - splashDamage = 5; - splashDamageRadius = 8; - makeFire = true; - collidesAir = false; - despawnHit = false; - hitEffect = despawnEffect = Fx.none; + damage = 1; + pierce = true; + sticky = true; + stickyExtraLifetime = 60; + + frontColor = Color.white; + backColor = Color.valueOf("cbdbfc"); - knockback = 0.35f; - impact = true; + hitEffect = despawnEffect = Fx.none; + }}; + }}; + }}; + ammoTypes.putAll( + MeldItems.silver, + molBullet, + MeldItems.annealedSilver, + molBullet + ); - fragRandomSpread = 0; - fragBullets = 1; - fragBullet = new BasicBulletType(){{ - width = height = 2; - speed = 6; - lifetime = 8; + consume(new ConsumeAspects(outletRate, MeldLiquids.aspectEfficiencies, MeldLiquids.aspectDensities)); + }}; - shrinkX = shrinkY = 1; - shrinkInterp = Interp.pow2In; + shadesteelShingles = new Wall("shadesteel-shingles"){{ + requirements(Category.defense, with(MeldItems.shadesteel, 64)); + size = 2; + health = 2400; + }}; - damage = 1; - pierce = true; - sticky = true; - stickyExtraLifetime = 60; + silverHusk = new RegenProjector("silver-husk"){{ + requirements(Category.defense, with(MeldItems.debris, 15, MeldItems.annealedSilver, 8)); + health = 600; + armor = 3; + range = 1; + healPercent = 0.05f; + effectChance = 0.05f; + baseColor = MeldPal.aspect; - frontColor = Color.white; - backColor = Color.valueOf("cbdbfc"); + insulated = true; - hitEffect = despawnEffect = Fx.none; - }}; - }}; - }} + liquidCapacity = 20; + drawer = new DrawMulti( + new DrawRegion("-bottom"){{ + layer = Layer.block - 1; + }}, + new DrawLiquidTile(MeldLiquids.aspect), + new DrawLiquidTile(MeldLiquids.boundAspect), + new DrawDefault() ); - consume(new ConsumeLiquid(MeldLiquids.aspect, outletRate)); + consume(new ConsumeAspects(outletRate/2, MeldLiquids.aspectEfficiencies, MeldLiquids.aspectDensities)); }}; coreRaft = new CoreRaft("core-raft"){ @@ -468,6 +636,46 @@ public static void load(){ outputLiquid = new LiquidStack(MeldLiquids.aether, 1); }}; + fumehood = new ModularCrafter("fumehood"){{ + requirements(Category.production, with( + MeldItems.debris, 80, MeldItems.shadesteel, 40 + )); + size = 3; + health = 500; + armor = 2; + hasLiquids = true; + replaceBars = false; + + squareSprite = false; + + dumpedLiquids.addAll(MeldLiquids.pollutantMixture, MeldLiquids.fumes); + + //Should make all the modules trigger in order + hookAll(BlockEvent.Defaults.proximityUpdate, + new AttributeModule(){{ + attribute = MeldAttributes.aetherAttr; + baseEfficiency = 0; + minEfficiency = 1; + boostScale = 1f/9f; + + efficiencyPin = 0; + }}, + new AttributeModule(){{ + attribute = Attribute.steam; + baseEfficiency = 0; + minEfficiency = 1; + boostScale = 1f/9f; + + efficiencyPin = 1; + }} + ); + + modules.addAll( + new ProduceLiquidModule(new LiquidStack(MeldLiquids.pollutantMixture, 1), 0), + new ProduceLiquidModule(new LiquidStack(MeldLiquids.fumes, 1), 1) + ); + }}; + elementalBlaster = new BeamDrill("elemental-blaster"){{ requirements(Category.production, with( MeldItems.debris, 40 @@ -483,8 +691,8 @@ public static void load(){ optionalBoostIntensity = 2; - consume(new ConsumeLiquid( - MeldLiquids.aspect, outletRate + consume(new ConsumeAspects( + outletRate, MeldLiquids.aspectEfficiencies, MeldLiquids.aspectDensities )); consume(new ConsumeLiquid( @@ -495,6 +703,28 @@ public static void load(){ }}); }}; + pneumaticPulsear = new SingleBeamDrill("pneumatic-pulsar"){{ + requirements(Category.production, with(MeldItems.debris, 500, MeldItems.carbolith, 250, MeldItems.shadesteel, 350, MeldItems.aspectPipe, 300)); + health = 2400; + armor = 40; + + size = 5; + itemCapacity = 100; + baseProductivity = 50; + drillTime = 360; + range = 8; + + transformItems.putAll( + MeldItems.clayMallows, MeldItems.glassMallows, + MeldItems.tenbris, MeldItems.shadesteel + ); + + liquidCapacity = 50; + + + consume(new ConsumeAspects(outletRate/2, MeldLiquids.outletEfficiencies, MeldLiquids.outletDensities)); + }}; + earthboundInfuser = new ModularCrafter("earthbound-infuser"){{ requirements(Category.crafting, with( MeldItems.debris, 40, @@ -523,23 +753,17 @@ public static void load(){ }} ); - defaultData.put(1, 1); + ItemRecipe carbolith = new ItemRecipe(with(MeldItems.debris, 1), with(MeldItems.carbolith, 1)); modules.addAll( new ProduceLiquidModule(new LiquidStack(MeldLiquids.fumes, 2f), 0), + new GateModule(1, new GateModule.RecipeCondition(carbolith)), new ConsumeLiquidModule(LiquidStack.with(MeldLiquids.fumes, 1, MeldLiquids.aspect, outletRate * 2), 1, 2), - new ConsumeGate(with(MeldItems.debris, 1), 3), - new MultiplierModule(){{ - inputPins = new int[]{2,3}; - outputPin = 4; - }}, - new ItemCraftingModule(){{ - efficiencyPin = 4; + new RecipeCraftingModule(){{ + efficiencyPin = 2; progressPin = 5; craftTime = 12; - - inputItems = with(MeldItems.debris, 1); - outputItem = new ItemStack(MeldItems.carbolith, 1); + recipe = carbolith; }} ); @@ -551,6 +775,248 @@ public static void load(){ */ }}; + gasKiln = new ModularCrafter("gas-kiln"){{ + requirements(Category.crafting, with(MeldItems.debris, 80)); + size = 3; + + hasItems = true; + hasLiquids = true; + liquidCapacity = outletRate * 60 * 2; + + itemCapacity = 10; + + acceptedLiquids.addAll(MeldLiquids.aspect, MeldLiquids.boundAspect); + acceptedItems.addAll(MeldItems.tenbris, MeldItems.clayMallows, MeldItems.carbolith, MeldItems.debris, MeldItems.shadesteel, MeldItems.glassMallows, MeldItems.silver); + dumpedItems.addAll(MeldItems.cruciblePlating, MeldItems.shadesteel, MeldItems.glassMallows, MeldItems.annealedSilver); + dumpedLiquids.addAll(MeldLiquids.fumes); + + ItemRecipe + shadesteel = new ItemRecipe(with(MeldItems.tenbris, 2, MeldItems.carbolith, 2), with(MeldItems.shadesteel, 2)).output(LiquidStack.with(MeldLiquids.fumes, 60)), + glass = new ItemRecipe(with(MeldItems.clayMallows, 2), with(MeldItems.glassMallows, 2)), + silver = new ItemRecipe(with(MeldItems.silver, 1), with(MeldItems.annealedSilver, 2)), + platings1 = new ItemRecipe(with(MeldItems.shadesteel, 4, MeldItems.debris, 2), with(MeldItems.cruciblePlating, 4)), + platings2 = new ItemRecipe(with(MeldItems.glassMallows, 4, MeldItems.debris, 2), with(MeldItems.cruciblePlating, 4)); + + float produceTime = 60; + + modules.addAll( + new GateModule( + ModOUT.ZERO, new GateModule.RecipeCondition(shadesteel) + ), + new GateModule( + ModOUT.ONE, new GateModule.RecipeCondition(glass) + ), + new GateModule( + ModOUT.TWO, new GateModule.RecipeCondition(silver) + ), + new GateModule( + ModOUT.THREE, new GateModule.RecipeCondition(platings1) + ), + new GateModule( + ModOUT.FOUR, new GateModule.RecipeCondition(platings2) + ), + new LambdaModule(){{ + //Set every pin after the first one found as 1 to zero + updater = b -> { + int a = 0; + for(int i = 0; i < 5; i++){ + b.setPin(i, Math.max(b.getPin(i) - a, 0)); + a = (int)Math.max(a, b.getPin(i)); + } + b.setPin(ModOUT.FIVE, a); + }; + }}, + new ConsumeAspectModule(outletRate * 2, MeldLiquids.aspectEfficiencies, MeldLiquids.aspectDensities, ModIN.FIVE, ModOUT.SIX), + new RecipeCraftingModule(){{ + recipe = shadesteel; + efficiencyPins = new int[]{ModIN.SIX, ModIN.ZERO}; + progressPin = ModOUT.SEVEN; + craftTime = produceTime; + }}, + new RecipeCraftingModule(){{ + recipe = glass; + efficiencyPins = new int[]{ModIN.SIX, ModIN.ONE}; + progressPin = ModOUT.EIGHT; + craftTime = produceTime; + }}, + new RecipeCraftingModule(){{ + recipe = silver; + efficiencyPins = new int[]{ModIN.SIX, ModIN.TWO}; + progressPin = ModOUT.NINE; + craftTime = produceTime; + }}, + new RecipeCraftingModule(){{ + recipe = platings1; + efficiencyPins = new int[]{ModIN.SIX, ModIN.THREE}; + progressPin = ModOUT.TEN; + craftTime = produceTime; + }}, + new RecipeCraftingModule(){{ + recipe = platings2; + efficiencyPins = new int[]{ModIN.SIX, ModIN.FOUR}; + progressPin = ModOUT.ELEVEN; + craftTime = produceTime; + }} + ); + }}; + + rotaryKiln = new ModularCrafter("rotary-kiln"){{ + requirements(Category.crafting, with(MeldItems.debris, 250, MeldItems.cruciblePlating, 150)); + size = 5; + + hasItems = true; + hasLiquids = true; + liquidCapacity = outletRate * 60 * 2; + + itemCapacity = 48; + + acceptedLiquids.addAll(MeldLiquids.aspect, MeldLiquids.boundAspect); + acceptedItems.addAll(MeldItems.tenbris, MeldItems.clayMallows, MeldItems.carbolith, MeldItems.debris, MeldItems.shadesteel, MeldItems.glassMallows, MeldItems.silver); + dumpedItems.addAll(MeldItems.cruciblePlating, MeldItems.shadesteel, MeldItems.glassMallows, MeldItems.annealedSilver); + + defaultData.put(0, 1); + + ItemRecipe shadesteel = new ItemRecipe(with(MeldItems.tenbris, 12), with(MeldItems.shadesteel, 12)); + ItemRecipe glass = new ItemRecipe(with(MeldItems.clayMallows, 12), with(MeldItems.glassMallows, 12)); + ItemRecipe silver = new ItemRecipe(with(MeldItems.silver, 1), with(MeldItems.annealedSilver, 2)); + ItemRecipe platings1 = new ItemRecipe(with(MeldItems.shadesteel, 4, MeldItems.debris, 2), with(MeldItems.cruciblePlating, 4)); + ItemRecipe platings2 = new ItemRecipe(with(MeldItems.glassMallows, 4, MeldItems.debris, 2), with(MeldItems.cruciblePlating, 4)); + + //The max crafting speed when boosted + float craftingTime = 120; + + modules.addAll( + //Set the base rate based on aspect intake + new ConsumeAspectModule(outletRate * 8, MeldLiquids.aspectEfficiencies, MeldLiquids.aspectDensities, 0, 1), + //Setup the flags for possible recipies + new GateModule( + ModOUT.TWO, + new ConsumeCondition(shadesteel.inputItems), + new OutputCondition(shadesteel.outputItems) + ), + new GateModule( + ModOUT.THREE, + new ConsumeCondition(glass.inputItems), + new OutputCondition(glass.outputItems) + ), + new GateModule( + ModOUT.FOUR, + new ConsumeCondition(platings1.inputItems), + new OutputCondition(platings1.outputItems) + ), + new GateModule( + ModOUT.FIVE, + new ConsumeCondition(platings2.inputItems), + new OutputCondition(platings2.outputItems) + ), + new GateModule( + ModOUT.SIX, + new ConsumeCondition(silver.inputItems), + new OutputCondition(silver.outputItems) + ), + //Take the average efficiency + new LambdaModule(){{ + int[] gatePins = new int[]{2, 3, 4, 5, 6}; + float drums = 3; + int outPin = 7; + + updater = build -> { + float total = 0; + for(int i: gatePins){ + total += build.data.get(i); + } + float out = drums/Math.max(total, 1); + build.setPin(outPin, out); + }; + }}, + //Recipies + new RecipeCraftingModule(){{ + recipe = shadesteel; + efficiencyPins = new int[]{1, 2, 7}; + progressPin = 8; + craftTime = craftingTime; + }}, + new RecipeCraftingModule(){{ + recipe = glass; + efficiencyPins = new int[]{1, 3, 7}; + progressPin = 9; + craftTime = craftingTime; + }}, + new RecipeCraftingModule(){{ + recipe = platings1; + efficiencyPins = new int[]{1, 4, 7}; + progressPin = 10; + craftTime = craftingTime; + }}, + new RecipeCraftingModule(){{ + recipe = platings2; + efficiencyPins = new int[]{1, 5, 7}; + progressPin = 11; + craftTime = craftingTime; + }}, + new RecipeCraftingModule(){{ + recipe = silver; + efficiencyPins = new int[]{1, 6, 7}; + progressPin = 12; + craftTime = craftingTime/8f; + }} + ); + }}; + + pneumaticExtruder = new ModularCrafter("pneumatic-extruder"){{ + requirements(Category.crafting, with(MeldItems.debris, 60, MeldItems.cruciblePlating, 40)); + size = 3; + + hasItems = true; + hasLiquids = true; + liquidCapacity = outletRate * 60; + + itemCapacity = 10; + + acceptedLiquids.addAll(MeldLiquids.aspect, MeldLiquids.boundAspect); + acceptedItems.addAll(MeldItems.shadesteel, MeldItems.elnarDust, MeldItems.debris, MeldItems.annealedSilver); + dumpedItems.addAll(MeldItems.aspectPipe); + + ItemRecipe + aspectPipe1 = new ItemRecipe(with(MeldItems.shadesteel, 2, MeldItems.elnarDust, 2), with(MeldItems.aspectPipe, 4)), + aspectPipe2 = new ItemRecipe(with(MeldItems.debris, 1, MeldItems.annealedSilver, 2), with(MeldItems.aspectPipe, 4)); + + float produceTime = 30; + + modules.addAll( + new GateModule( + ModOUT.ZERO, new GateModule.RecipeCondition(aspectPipe1) + ), + new GateModule( + ModOUT.ONE, new GateModule.RecipeCondition(aspectPipe2) + ), + new LambdaModule(){{ + //Set every ping after the first one found as 1 to zero + updater = b -> { + int a = 0; + for(int i = 0; i < 2; i++){ + b.setPin(i, Math.max(b.getPin(i) - a, 0)); + a = (int)Math.max(a, b.getPin(i)); + } + b.setPin(ModOUT.TWO, a); + }; + }}, + new ConsumeLiquidModule(LiquidStack.with(MeldLiquids.aspect, outletRate * 2), ModIN.TWO, ModOUT.THREE), + new RecipeCraftingModule(){{ + recipe = aspectPipe1; + efficiencyPins = new int[]{ModIN.THREE, ModIN.ZERO}; + progressPin = ModOUT.FOUR; + craftTime = produceTime; + }}, + new RecipeCraftingModule(){{ + recipe = aspectPipe2; + efficiencyPins = new int[]{ModIN.THREE, ModIN.ONE}; + progressPin = ModOUT.FIVE; + craftTime = produceTime; + }} + ); + }}; + sharkFactory = new UnitFactory("shark-factory"){{ requirements(Category.units, with(MeldItems.debris, 500, MeldItems.carbolith, 350, MeldItems.silver, 450)); size = 5; @@ -576,13 +1042,10 @@ public static void load(){ range = 220; - liquidCapacity = 8 * outletRate * 60; + liquidCapacity = 1 * outletRate * 60; + hasLiquids = true; - consume( - new ConsumeLiquid( - MeldLiquids.aspect, 2 * outletRate - ) - ); + consume(new ConsumeAspects(outletRate * 2, MeldLiquids.aspectEfficiencies, MeldLiquids.aspectDensities)); }}; movementAnchor = new MovementAnchor("movement-anchor"){{ @@ -594,11 +1057,7 @@ public static void load(){ health = 1200; range = 22 * Vars.tilesize; - consume( - new ConsumeLiquid( - MeldLiquids.aspect, 3 * outletRate - ) - ); + consume(new ConsumeAspects(outletRate * 3, MeldLiquids.aspectEfficiencies, MeldLiquids.aspectDensities)); }}; nullifier = new Nullifier("nullifier"){{ @@ -612,6 +1071,38 @@ public static void load(){ health = 300; }}; + bruisekit = new Bruisekit("bruisekit"){{ + requirements(Category.effect, with( + MeldItems.debris, 60, + MeldItems.aspectPipe, 45, + MeldItems.resonarum, 80 + )); + size = 2; + + consume( + new ConsumeLiquid(MeldLiquids.fumes, 0.5f) + ); + }}; + + gauze = new Gauze("gauze"){{ + requirements(Category.effect, with( + MeldItems.debris, 60, + MeldItems.aspectPipe, 45, + MeldItems.resonarum, 80 + )); + size = 3; + + health = 640; + propagateMaxRange = 16; + + recipies.addAll( + new SpoolRecipe(new ItemStack(MeldItems.resonarum, 2), 200) + ); + + consumeLiquid(MeldLiquids.fumes, 1f); + consumeItem(MeldItems.resonarum, 2); + }}; + chute = new Duct("chute"){{ requirements(Category.distribution, with(MeldItems.debris, 1)); health = 90; @@ -624,7 +1115,6 @@ public static void load(){ speed = 4f; solid = false; }}; - chuteBridge = new DuctBridge("chute-bridge"){{ requirements(Category.distribution, with(MeldItems.debris, 8)); range = 5; @@ -634,13 +1124,22 @@ public static void load(){ ((Duct) chute).bridgeReplacement = this; }}; - chuteOverflow = new OverflowDuct("chute-overflow"){{ - requirements(Category.distribution, with(MeldItems.debris, 6)); + chuteOverflow = new PriorityInputSplitter("chute-overflow"){{ + requirements(Category.distribution, with(MeldItems.debris, 4)); health = 90; speed = 4f; solid = false; }}; + unloadingHub = new Unloader("unloading-hub"){{ + requirements(Category.distribution, with(MeldItems.debris, 450)); + size = 3; + health = 900; + speed = 1f; + + solid = false; + }}; + chuteJunction = new DuctJunction("chute-crossing"){{ requirements(Category.distribution, with(MeldItems.debris, 7)); health = 90; diff --git a/src/meld/content/MeldBullets.java b/src/meld/content/MeldBullets.java new file mode 100644 index 0000000..84acab3 --- /dev/null +++ b/src/meld/content/MeldBullets.java @@ -0,0 +1,65 @@ +package meld.content; + +import arc.math.Interp; +import meld.Meld; +import mindustry.content.Blocks; +import mindustry.content.Fx; +import mindustry.entities.bullet.BasicBulletType; +import mindustry.entities.bullet.BulletType; +import mindustry.entities.bullet.ExplosionBulletType; +import mindustry.entities.bullet.RailBulletType; + +public class MeldBullets { + + public static BulletType + + pulsarBlast, pulsarShrapnel; + + public static void load(){ + + pulsarShrapnel = new BasicBulletType(){{ + sprite = Meld.prefix("clump"); + shrinkX = 1; + shrinkY = 0.2f; + + width = 5; + height = 12; + shrinkInterp = Interp.pow2In; + speed = 12; + drag = 0.02f; + + lifetime = 30; + damage = 10; + pierce = true; + pierceBuilding = true; + pierceDamageFactor = 0.5f; + lightRadius = 0; + + lightningDamage = 5; + lightning = 1; + lightningLength = 12; + + setDefaults = false; + despawnEffect = hitEffect = Fx.none; + despawnHit = false; + + collideTerrain = true; + }}; + + pulsarBlast = new ExplosionBulletType(){{ + lightningDamage = 5; + lightning = 12; + lightningLength = 48; + + fragOffsetMin = fragOffsetMax = 0; + fragLifeMin = 0.5f; + + fragBullets = 120; + fragSpread = 3; + fragRandomSpread = 0; + fragBullet = pulsarShrapnel; + killShooter = false; + }}; + + } +} diff --git a/src/meld/content/MeldEnvironment.java b/src/meld/content/MeldEnvironment.java index 8483c48..2b878d1 100644 --- a/src/meld/content/MeldEnvironment.java +++ b/src/meld/content/MeldEnvironment.java @@ -14,13 +14,23 @@ public class MeldEnvironment { //Ore deposits - public static Block debrisDeposit, debrisDepositLarge, debrisNodule, carbolithDeposit, carbolithDepositDepleted, silverDeposit, resonarumDeposit, resonarumCrystal, resonarumOutcrop, + public static Block + + //Marsh pt1 + debrisDeposit, debrisDepositLarge, debrisNodule, + //Barrens + carbolithDeposit, carbolithDepositDepleted, tenbrisMix, tenbrisRidges, elnarSilt, embeddedElnar, embeddedElnarOverflowing, + //Badlands + silverDeposit, + //Storm Planes + resonarumDeposit, resonarumCrystal, resonarumOutcrop, //Marsh meldWall, meldCrystalWall, metalMeshWall, metalMeshWallMeld, metalAetherWall, //Badlands pillowWall, sandstoneWall, + mallowWall, crackstoneWall, //Barrens carbonicWall, earthenWall //Storm Planes @@ -31,6 +41,7 @@ public class MeldEnvironment { metalWeave, metalWeaveHole, metalWeaveGlow, //Badlands sandMeld, softSand, sandstone, + redsandMeld, redSand, aspectSoil, redSandWeave, crackstone, //Barrens bedrock, bedrockMeld, slate, slateMeld, @@ -70,6 +81,32 @@ public static void load(){ itemDrop = MeldItems.carbolith; }}; + tenbrisMix = new StaticWall("tenbris-mix"){{ + variants = 2; + itemDrop = MeldItems.tenbris; + }}; + + tenbrisRidges = new StaticWall("tenbris-ridges"){{ + variants = 2; + itemDrop = MeldItems.tenbris; + }}; + + embeddedElnar = new StaticWall("embedded-elnar"){{ + variants = 2; + itemDrop = MeldItems.elnarDust; + }}; + + elnarSilt = new OreBlock("elnar-silt"){{ + variants = 4; + itemDrop = MeldItems.elnarDust; + needsSurface = false; + }}; + + embeddedElnarOverflowing = new StaticWall("embedded-elnar-overflowing"){{ + variants = 2; + itemDrop = MeldItems.elnarDust; + }}; + carbolithDepositDepleted = new StaticWall("carbolith-deposit-depleted"){{ variants = 3; }}; @@ -127,10 +164,13 @@ public static void load(){ //Barrens bedrock = new Floor("bedrock", 3); slate = new Floor("slate", 0); - literallyCarbonStoneFromMindustryButSlightlyDifferent = new Floor("carbonic-stone", 4); + earthenStone = new Floor("earthen-stone", 4); carbonicPlates = new Floor("carbonic-plates", 3); - earthenStone = new Floor("mixture-stone", 3); + literallyCarbonStoneFromMindustryButSlightlyDifferent = new Floor("carbonic-stone", 4); + + slate.blendGroup = bedrock; + mixtureStone = new Floor("mixture-stone", 3); metalWeave = new Floor("metal-weave", 3); metalWeaveHole= new Floor("metal-weave-hole", 0); @@ -183,7 +223,10 @@ public static void load(){ isLiquid = true; cacheLayer = CacheLayer.water; }}; - + redsandMeld = new Floor("red-sand-meld", 3){{ + isLiquid = true; + cacheLayer = CacheLayer.water; + }}; slateMeld = new Floor("slate-meld", 3){{ isLiquid = true; cacheLayer = CacheLayer.water; @@ -236,6 +279,10 @@ public static void load(){ softSand = new Floor("soft-sand", 3); sandstone = new Floor("hard-sand", 3); + redSandWeave = new Floor("red-sand-weave", 3); + redSand = new Floor("red-sand", 3); + aspectSoil = new Floor("aspect-soil", 3); + crackstone = new Floor("cracked-sand", 4); meldWall = new StaticWall("meld-wall"){{ variants = 3; @@ -266,6 +313,15 @@ public static void load(){ variants = 2; }}; + mallowWall = new StaticWall("mallow-wall"){{ + variants = 2; + itemDrop = MeldItems.clayMallows; + }}; + + crackstoneWall = new StaticWall("crackstone-wall"){{ + variants = 2; + }}; + resonantStone = new Floor("resonant-stone", 3); aetherGrowth = new SteamVent("aether-growth"){{ diff --git a/src/meld/content/MeldFx.java b/src/meld/content/MeldFx.java index 58b23d3..9dcbef9 100644 --- a/src/meld/content/MeldFx.java +++ b/src/meld/content/MeldFx.java @@ -5,6 +5,7 @@ import arc.graphics.g2d.Draw; import arc.graphics.g2d.Fill; import arc.graphics.g2d.Lines; +import arc.math.Angles; import arc.math.Interp; import arc.math.Mathf; import arc.math.geom.Position; @@ -22,6 +23,15 @@ public class MeldFx { public static Effect + gasTransfer = new Effect(60, e -> { + Draw.z(Layer.blockUnder); + Draw.color(e.color); + Draw.alpha(e.finpowdown()); + Angles.randLenVectors(e.id, 2, e.fin() * Vars.tilesize * 1.5f, e.rotation,Vars.tilesize/4f, (x, y) -> { + Fill.circle(e.x + x, e.y + y, 2 * e.foutpowdown()); + }); + }), + chain = new Effect(240, e -> { Draw.color(Color.red); if(e.data instanceof Position pos) { diff --git a/src/meld/content/MeldItems.java b/src/meld/content/MeldItems.java index e047fd5..b0d36ba 100644 --- a/src/meld/content/MeldItems.java +++ b/src/meld/content/MeldItems.java @@ -4,7 +4,7 @@ public class MeldItems { public static Item - debris, carbolith, silver, resonarum, + debris, carbolith, silver, resonarum, clayMallows, meldShard; @@ -13,19 +13,23 @@ public class MeldItems { //Heavy industry content public static Item - tenbris, shadesteel, elnarDust, annealedSilver, cruciblePlating, aspectPipe; + tenbris, shadesteel, elnarDust, annealedSilver, glassMallows, cruciblePlating, aspectPipe; public static void load(){ debris = new Item("debris"){{ - cost = 0.1f; + cost = 0.5f; }}; carbolith = new Item("carbolith"){{ - cost = 0.5f; + cost = 0.8f; }}; silver = new Item("silver"){{ - cost = 0.4f; + cost = 0.3f; + }}; + clayMallows = new Item("clay-mallow"){{ + cost = 0.2f; }}; + resonarum = new Item("resonarum"); stonyParticulate = new Item("stony-particulate"){{ @@ -53,6 +57,8 @@ public static void load(){ }}; + glassMallows = new Item("glass-mallow"); + aspectPipe = new Item("aspect-pipe"){{ }}; diff --git a/src/meld/content/MeldLiquids.java b/src/meld/content/MeldLiquids.java index 8f41fb6..dc6e5d6 100644 --- a/src/meld/content/MeldLiquids.java +++ b/src/meld/content/MeldLiquids.java @@ -1,16 +1,33 @@ package meld.content; import arc.graphics.Color; +import arc.struct.ObjectFloatMap; +import arc.struct.ObjectMap; +import arc.struct.Seq; import mindustry.type.Liquid; public class MeldLiquids { - public static Liquid aether, aspect, meld, fumes; + public static Liquid aether, aspect, meld, fumes, + pollutantMixture, boundAspect; + + public static ObjectFloatMap aetherEfficiencies = new ObjectFloatMap<>(); + public static ObjectFloatMap aetherDensities = new ObjectFloatMap<>(); + + public static ObjectFloatMap aspectEfficiencies = new ObjectFloatMap<>(); + public static ObjectFloatMap aspectDensities = new ObjectFloatMap<>(); + + public static ObjectFloatMap outletEfficiencies = new ObjectFloatMap<>(); + public static ObjectFloatMap outletDensities = new ObjectFloatMap<>(); + + public static ObjectMap outletMapping = new ObjectMap<>(); + public float outletRatio = 10; public static void load(){ aether = new Liquid("aether"){{ gas = true; color = Color.valueOf("cb8650"); + temperature = 0.6f; }}; aspect = new Liquid("aspect"){{ @@ -18,6 +35,7 @@ public static void load(){ flammability = 1; explosiveness = 2; color = Color.valueOf("cbdbfc"); + temperature = 0.6f; }}; meld = new Liquid("meld"){{ @@ -31,5 +49,43 @@ public static void load(){ color = Color.valueOf("5b4739"); temperature = 0.6f; }}; + + pollutantMixture = new Liquid("pollutant-mixture"){{ + gas = true; + color = Color.valueOf("6a634d"); + temperature = 0.6f; + }}; + + boundAspect = new Liquid("bound-aspect"){{ + gas = true; + color = Color.valueOf("d7a9ef"); + temperature = 0.6f; + }}; + + aetherEfficiencies.put(aether, 1); + aetherEfficiencies.put(pollutantMixture, 1); + + aetherDensities.put(aether, 1); + aetherDensities.put(pollutantMixture, 1/5f); + + aspectEfficiencies.put(aspect, 1); + aspectEfficiencies.put(boundAspect, 1); + + aspectDensities.put(aspect, 1); + aspectDensities.put(boundAspect, 2.5f); + + outletMapping.putAll( + aether, aspect, + pollutantMixture, boundAspect + ); + + Seq outletLiquids = Seq.with(aether, pollutantMixture); + + outletLiquids.each(liquid -> { + Liquid aspecti = outletMapping.get(liquid); + outletEfficiencies.put(liquid, aetherEfficiencies.get(liquid, 1) * aspectEfficiencies.get(aspecti, 1)); + outletDensities.put(liquid, aetherDensities.get(liquid, 1) * aspectDensities.get(aspecti, 1)); + }); + } } diff --git a/src/meld/graphics/MeldPal.java b/src/meld/graphics/MeldPal.java index 5a49b6d..52d238a 100644 --- a/src/meld/graphics/MeldPal.java +++ b/src/meld/graphics/MeldPal.java @@ -5,6 +5,7 @@ public class MeldPal { public static Color + aspect = Color.valueOf("f0f5fe"), shark = Color.valueOf("a393feff"), darkShark = Color.valueOf("665c9f"), accentClear = Pal.accent.cpy().a(0), diff --git a/src/meld/world/WorldUtil.java b/src/meld/world/WorldUtil.java index 310f9fc..6eabd8d 100644 --- a/src/meld/world/WorldUtil.java +++ b/src/meld/world/WorldUtil.java @@ -1,7 +1,10 @@ package meld.world; +import arc.math.Mathf; +import arc.math.geom.Point2; import arc.struct.Seq; import arc.util.Nullable; +import arc.util.Tmp; import mindustry.world.Tile; import mindustry.world.meta.Attribute; @@ -19,4 +22,28 @@ public static float sumAttribute(@Nullable Attribute attr, int x, int y){ tile.getLinkedTiles(tempTiles); return tempTiles.sumf(other -> other.floor().attributes.get(attr)); } + + //Just to note + //Rotation 0/0: (1, 0) + //Rotation 90/1: (0, 1) + //Rotation 180/2: (-1, 0) + //Rotation 270/3: (0, -1) + + //Really hyper compact and im not sure this is the best way to do it but like + public static int relativeTo(int x1, int y1, int x2, int y2){ + int dx = x2 - x1, dy = y2 - y1; + int ax = Math.abs(dx), ay = Math.abs(dy); + + boolean up = ay > ax; + int rotation = 0; + if(up){ + rotation++; + if(Mathf.sign(dy) == -1) rotation += 2; + return rotation; + } + + //Flippies! + if(Mathf.sign(dx) == -1) rotation += 2; + return rotation; + } } diff --git a/src/meld/world/blocks/Bruisekit.java b/src/meld/world/blocks/Bruisekit.java new file mode 100644 index 0000000..a9164b0 --- /dev/null +++ b/src/meld/world/blocks/Bruisekit.java @@ -0,0 +1,62 @@ +package meld.world.blocks; + +import arc.graphics.g2d.Draw; +import arc.graphics.g2d.Lines; +import arc.math.Mathf; +import arc.struct.Seq; +import mindustry.entities.Units; +import mindustry.gen.Building; + +public class Bruisekit extends FieldPulsar{ + + Seq tmpDamaged = new Seq<>(); + + int targetTimer = timers++; + + public float healSpeed = 2; + public float retargetInterval = 5; + + public float recentDamageMultiplier = 0.1f; + + public Bruisekit(String name) { + super(name); + fogRadius = 0; + } + + public class BruisekitBuild extends PulsarBuild{ + public Building target; + + + @Override + public void updateTile() { + super.updateTile(); + if(timer.get(targetTimer, retargetInterval)) findTarget(); + if(target != null){ + if(target.isAdded() && target.damaged()) { + float healAmount = healSpeed; + if(target.wasRecentlyDamaged()) healAmount *= recentDamageMultiplier; + + target.heal(healAmount); + } + } + } + + public void findTarget(){ + tmpDamaged.clear(); + + Units.nearbyBuildings(x, y, smoothRadius, b -> { + if(b.team == team() && b.damaged() && b.block.size > 1) tmpDamaged.add(b); + }); + + tmpDamaged.sort(b -> b.block.size + (1 - b.healthf()) + Mathf.log(10, b.block.health)/10); + if(!tmpDamaged.isEmpty()) target = tmpDamaged.pop(); + } + + @Override + public void draw() { + super.draw(); + Draw.alpha(1); + if(target != null) Lines.line(x, y, target.x, target.y); + } + } +} diff --git a/src/meld/world/blocks/Gauze.java b/src/meld/world/blocks/Gauze.java new file mode 100644 index 0000000..aff2d37 --- /dev/null +++ b/src/meld/world/blocks/Gauze.java @@ -0,0 +1,196 @@ +package meld.world.blocks; + +import arc.graphics.Color; +import arc.graphics.g2d.Lines; +import arc.math.Mathf; +import arc.struct.Seq; +import arc.util.Time; +import arc.util.io.Reads; +import arc.util.io.Writes; +import meld.world.blocks.crafting.recipe.SpoolRecipe; +import mindustry.Vars; +import mindustry.content.Fx; +import mindustry.gen.Building; +import mindustry.graphics.Pal; +import mindustry.ui.Bar; +import mindustry.world.Block; + +public class Gauze extends Block { + + public float craftTime = 60; + public float spoolStorage = 800; + + public Seq recipies = new Seq<>(); + + public float reload = 120; + public float detectHeadstart = 0.75f; + + public float syncMargin = 20; + + public int propagateMaxRange = 10; + + public float pulseStrength = 200; + public float maxFract = 0.25f; + + Seq searching = new Seq<>(), qued = new Seq<>(), explored = new Seq<>(); + Seq connectedGauzes = new Seq<>(); + + public Gauze(String name) { + super(name); + update = true; + } + + @Override + public void setBars() { + super.setBars(); + addBar( + "spool", + entity -> new Bar("stats.spool", Pal.heal, () -> ((GauzeBuild)entity).spoolf()).blink(Color.red) + ); + } + + public class GauzeBuild extends Building { + + Gauze gauze; + + public float time; + public float craftTimer; + public float energy = 0; + + public float spoolf(){ + return energy/spoolStorage; + } + + @Override + public void updateTile() { + super.updateTile(); + if(energy >= pulseStrength){ + if(time >= reload) { + time %= reload; + propagate(); + } + time += Time.delta; + } + + craftTimer += efficiency; + if(craftTimer >= craftTime){ + craft(); + } + } + + @Override + public void created() { + super.created(); + gauze = (Gauze) block; + } + + public boolean shouldCraft(){ + return recipies.copy().find(r -> r.valid(gauze, this)) != null; + } + + @Override + public boolean shouldConsume() { + return super.shouldConsume() && shouldCraft(); + } + + public void craft(){ + SpoolRecipe recipe = recipies.find(r -> r.valid(gauze, this)); + if(recipe != null){ + //I've somehow had recipe be null so im not taking any chances here + recipe.apply(gauze, this); + craftTimer %= craftTime; + } + } + + //Only propagates through 1x1 blocks and their adjacent blocks + public void propagate(){ + explored.clear(); + searching.clear(); + qued.clear(); + + explored.add(this); + searching.addAll(this.proximity); + + boolean healed = false; + float charge = pulseStrength; + + for(int i = 0; i < propagateMaxRange; i++){ + for(Building build: searching){ + Fx.healBlock.at(build.x, build.y, 1); + if(build.damaged()){ + /** + * Max of a few numbers + * -Missing health + * -maxFract * Math.max(build.maxHealth pulseStrength) + * -Remaining charge + * -0 + */ + float healAmount = Mathf.maxZero(Math.min(Math.min(Math.min(build.maxHealth, pulseStrength) * maxFract, build.block.health - build.health), charge)); + if(healAmount > 0){ + Fx.healBlockFull.at(build.x, build.y, 0, Pal.heal, build.block); + build.heal(healAmount); + charge -= healAmount; + healed = true; + } + } + + if(build.block.size == 1) build.proximity.each( b -> !explored.contains(b), qued::addUnique); + if(build instanceof GauzeBuild gauze){ + connectedGauzes.add(gauze); + } + } + + explored.add(searching); + searching.set(qued); + qued.clear(); + + //No more healing to expand, goodbye world + if(charge == 0) break; + } + + if(healed) time = reload * detectHeadstart; + energy = energy - Mathf.clamp(pulseStrength - charge, 0, pulseStrength); + + float totalTime = 0; + connectedGauzes.addAll(this); + + //Remove gauzes close to firing, then sync + + connectedGauzes.removeAll(b -> reload - b.time < syncMargin); + for(GauzeBuild gauze: connectedGauzes){ + totalTime += gauze.time; + } + + float averageTime = totalTime / (connectedGauzes.size); + + for(GauzeBuild gauze: connectedGauzes){ + gauze.time = averageTime; + } + + connectedGauzes.clear(); + } + + @Override + public void write(Writes write) { + super.write(write); + write.f(time); + write.f(craftTimer); + write.f(energy); + } + + @Override + public void read(Reads read, byte revision) { + super.read(read, revision); + time = read.f(); + craftTimer = read.f(); + energy = read.f(); + } + + @Override + public void draw() { + super.draw(); + + Lines.arc(x, y, Vars.tilesize * 3, time/reload); + } + } +} diff --git a/src/meld/world/blocks/LiquidUtil.java b/src/meld/world/blocks/LiquidUtil.java new file mode 100644 index 0000000..2312a46 --- /dev/null +++ b/src/meld/world/blocks/LiquidUtil.java @@ -0,0 +1,42 @@ +package meld.world.blocks; + +import arc.util.Log; +import mindustry.gen.Building; +import mindustry.type.LiquidStack; +import mindustry.world.modules.LiquidModule; + +public class LiquidUtil { + + public static boolean hasAll(LiquidStack[] liquids, Building build){ + for(LiquidStack stack: liquids){ + if(!(build.liquids.get(stack.liquid) < stack.amount)) return false; + } + return true; + } + + public static boolean has(LiquidStack[] liquids, Building build){ + for(LiquidStack stack: liquids){ + if(build.liquids.get(stack.liquid) <= 0) { + return false; + } + } + return true; + } + + public static void add(LiquidStack[] liquids, LiquidModule module){ + for(var liquid: liquids){ + module.add(liquid.liquid, liquid.amount); + } + } + public static void remove(LiquidStack[] liquids, LiquidModule module){ + for(var liquid: liquids){ + module.remove(liquid.liquid, liquid.amount); + } + } + + public static void add(LiquidStack[] liquids, Building build, Building source){ + for(var liquid: liquids){ + build.handleLiquid(source, liquid.liquid, liquid.amount); + } + } +} diff --git a/src/meld/world/blocks/MovementAnchor.java b/src/meld/world/blocks/MovementAnchor.java index 3b0b7c6..f4daac4 100644 --- a/src/meld/world/blocks/MovementAnchor.java +++ b/src/meld/world/blocks/MovementAnchor.java @@ -4,6 +4,8 @@ import arc.graphics.g2d.Lines; import arc.struct.Seq; import arc.util.Time; +import arc.util.io.Reads; +import arc.util.io.Writes; import meld.content.MeldFx; import meld.content.MeldStatusEffects; import mindustry.entities.Units; @@ -99,5 +101,17 @@ public void draw() { Draw.z(Layer.effect); Lines.arc(x, y, range, reloadTime/reload); } + + @Override + public void write(Writes write) { + super.write(write); + write.f(reloadTime); + } + + @Override + public void read(Reads read, byte revision) { + super.read(read, revision); + reloadTime = read.f(); + } } } diff --git a/src/meld/world/blocks/consumers/ConsumeAspects.java b/src/meld/world/blocks/consumers/ConsumeAspects.java new file mode 100644 index 0000000..3dc0d47 --- /dev/null +++ b/src/meld/world/blocks/consumers/ConsumeAspects.java @@ -0,0 +1,101 @@ +package meld.world.blocks.consumers; + +import arc.Core; +import arc.graphics.Color; +import arc.math.Mathf; +import arc.struct.ObjectFloatMap; +import arc.util.Log; +import meld.world.blocks.crafting.MeldGenericCrafter; +import mindustry.Vars; +import mindustry.gen.Building; +import mindustry.type.Liquid; +import mindustry.ui.Bar; +import mindustry.world.Block; +import mindustry.world.consumers.*; + +public class ConsumeAspects extends ConsumeLiquidFilter implements MeldGenericCrafter.BarConsumer { + + public ObjectFloatMap efficiencyMap, densityMap; + + + public ConsumeAspects(float amount, ObjectFloatMap efficiencyMap, ObjectFloatMap densityMap){ + super(); + this.efficiencyMap = efficiencyMap; + this.densityMap = densityMap; + this.amount = amount; + filter = efficiencyMap::containsKey; + } + + private static Liquid currentBest; + + @Override + public void apply(Block block) { + block.hasLiquids = true; + Vars.content.liquids().each(l -> efficiencyMap.containsKey(l), (item) -> { + block.liquidFilter[item.id] = true; + }); + } + + @Override + public boolean consumes(Liquid liquid) { + return efficiencyMap.containsKey(liquid); + } + + @Override + public void update(Building build) { + Liquid consumed = getConsumed(build); + build.liquids.remove(consumed, this.amount * build.edelta()/densityMap.get(consumed, 1)); + } + + @Override + public Liquid getConsumed(Building build){ + float highest = 0; + currentBest = null; + for(Liquid liquid: efficiencyMap.keys()){ + if(!Mathf.zero(build.liquids.get(liquid))) { + float value = efficiencyMap.get(liquid, 0); + + if(value > highest){ + highest = value; + currentBest = liquid; + } + } + } + return currentBest; + } + + @Override + public float efficiency(Building build) { + Liquid liq = this.getConsumed(build); + float ed = build.edelta(); + if(Mathf.zero(ed)) return 0; + else { + + float multi = efficiencyMap.get(liq, 0); + + return liq != null ? Math.min(build.liquids.get(liq) / (this.amount * ed * multi), multi) : 0; + } + } + + @Override + public float efficiencyMultiplier(Building build) { + Liquid liq = this.getConsumed(build); + return liq == null ? 0.0F : efficiencyMap.get(liq, 0); + } + + @Override + public void setBars(MeldGenericCrafter crafter) { + + crafter.addBar("liquid", entity -> { + Liquid current = getConsumed(entity); + + return new Bar( + () -> current == null || entity.liquids.get(current) <= 0.001f ? Core.bundle.get("bar.liquid") : current.localizedName, + () -> current == null ? Color.clear : current.barColor(), + () -> current == null ? 0f : entity.liquids.get(current) / crafter.liquidCapacity + ); + } + ); + + } +} diff --git a/src/meld/world/blocks/crafting/MeldGenericCrafter.java b/src/meld/world/blocks/crafting/MeldGenericCrafter.java new file mode 100644 index 0000000..54d1e29 --- /dev/null +++ b/src/meld/world/blocks/crafting/MeldGenericCrafter.java @@ -0,0 +1,28 @@ +package meld.world.blocks.crafting; + +import mindustry.world.blocks.production.GenericCrafter; +import mindustry.world.consumers.ConsumeLiquid; +import mindustry.world.consumers.ConsumeLiquids; + +public class MeldGenericCrafter extends GenericCrafter { + public MeldGenericCrafter(String name) { + super(name); + } + + public interface BarConsumer{ + void setBars(MeldGenericCrafter crafter); + } + + @Override + public void setBars() { + super.setBars(); + + for(var consl : consumers){ + if(consl instanceof BarConsumer barCons) barCons.setBars(this); + } + } + + public class MeldGenericCrafterBuild extends GenericCrafterBuild{ + + } +} diff --git a/src/meld/world/blocks/crafting/ModularCrafter.java b/src/meld/world/blocks/crafting/ModularCrafter.java index 9c91a89..a56528b 100644 --- a/src/meld/world/blocks/crafting/ModularCrafter.java +++ b/src/meld/world/blocks/crafting/ModularCrafter.java @@ -1,16 +1,17 @@ package meld.world.blocks.crafting; -import arc.struct.IntFloatMap; -import arc.struct.ObjectMap; -import arc.struct.Seq; +import arc.struct.*; import arc.util.Log; import arc.util.Time; +import arc.util.io.Reads; +import arc.util.io.Writes; import mindustry.game.Team; import mindustry.gen.Building; import mindustry.type.Item; import mindustry.type.ItemStack; import mindustry.type.Liquid; import mindustry.world.Block; +import mindustry.world.blocks.production.GenericCrafter; import mindustry.world.meta.Attribute; import java.util.HashMap; @@ -21,19 +22,32 @@ public class ModularCrafter extends Block { public Seq modules = new Seq(); public ObjectMap> listeners = new ObjectMap>(); + //list of items/liquids which this block accepts public Seq acceptedLiquids = new Seq<>(); public Seq acceptedItems = new Seq<>(); + //List of items/liquids which get dumped public Seq dumpedLiquids = new Seq<>(); public Seq dumpedItems = new Seq<>(); + public boolean replaceBars = true; + + //Default float data array + public IntFloatMap defaultData = new IntFloatMap(); + + public ModularCrafter(String name) { + super(name); + update = true; + solid = true; + } @Override public void setBars() { super.setBars(); - if(acceptedLiquids.size + dumpedLiquids.size > 0){ + if(replaceBars && acceptedLiquids.size + dumpedLiquids.size > 0){ removeBar("liquid"); + for(Liquid liquid: acceptedLiquids){ addLiquidBar(liquid); } @@ -43,14 +57,6 @@ public void setBars() { } } - public ModularCrafter(String name) { - super(name); - update = true; - } - - //Default float data array - public IntFloatMap defaultData = new IntFloatMap(); - public static void trigger(ModularCrafter block, ModularCrafterBuild build, Object event){ Seq events = block.listeners.get(event); if(events != null) events.each(c -> c.update(build)); @@ -88,12 +94,26 @@ public void update(ModularCrafterBuild build){ } public static abstract class CraftingModule extends CrafterModule{ - public int efficiencyPin; + public int efficiencyPin = -1; + public int[] efficiencyPins; public int progressPin; - public float craftTime; + public float craftTime = 60; + + public boolean canCraft(ModularCrafterBuild build){ + return true; + }; public void update(ModularCrafterBuild build){ - float efficiency = build.getPin(efficiencyPin); + if(!canCraft(build)) return; + + float efficiency = 1; + if(efficiencyPin != -1) efficiency = build.getPin(efficiencyPin); + if(efficiencyPins != null){ + for(int i: efficiencyPins){ + efficiency *= build.getPin(i); + } + } + float progress = build.getPin(progressPin); progress += efficiency * Time.delta; @@ -107,55 +127,44 @@ public void update(ModularCrafterBuild build){ public abstract void craft(ModularCrafterBuild build); } - public static class AttributeModule extends CrafterModule{ - public int efficiencyPin; - - public Attribute attribute; - public float baseEfficiency = 1; - public float boostScale = 1; - public float maxBoost = 1; - public float minEfficiency = -1; - @Override - public void update(ModularCrafterBuild build) { - float efficiency = baseEfficiency + Math.min(maxBoost, boostScale * build.block.sumAttribute(attribute, build.tileX(), build.tileY()) + attribute.env()); - - Log.info(efficiency); - - if(minEfficiency != -1 && efficiency < minEfficiency) { - build.setPin(efficiencyPin, 0); - return; - } - - build.data.put(efficiencyPin, efficiency); - } - } - - public static class ItemCraftingModule extends CraftingModule{ - public ItemStack outputItem; - public ItemStack[] outputItems; - - public ItemStack[] inputItems; - - @Override - public void update(ModularCrafterBuild build) { - super.update(build); - - } - - @Override - public void craft(ModularCrafterBuild build) { - if(outputItem != null) build.items.add(outputItem.item, outputItem.amount); - - if(inputItems != null) build.items.remove(inputItems); - - if(outputItems != null) { - for (ItemStack item : outputItems) { - build.items.add(item.item, item.amount); - } - } - } - } + //Just some static finals to help readability + public static class ModOUT{ + public static final float ON = 1, OFF = 0; + public static final int + ZERO = 0, + ONE = 1, + TWO = 2, + THREE = 3, + FOUR = 4, + FIVE = 5, + SIX = 6, + SEVEN = 7, + EIGHT = 8, + NINE = 9, + TEN = 10, + ELEVEN = 11, + TWELVE = 12; + }; + public static class ModIN{ + public static final float ON = 1, OFF = 0; + public static final int + ZERO = 0, + ONE = 1, + TWO = 2, + THREE = 3, + FOUR = 4, + FIVE = 5, + SIX = 6, + SEVEN = 7, + EIGHT = 8, + NINE = 9, + TEN = 10, + ELEVEN = 11, + TWELVE = 12; + }; + + public static final float ON = 1, OFF = 0; public class ModularCrafterBuild extends Building { @@ -214,5 +223,27 @@ public void update() { super.update(); modules.each(c -> c.update(this)); } + + @Override + public void write(Writes write) { + super.write(write); + write.i(data.size); + int[] keys = data.keys().toArray().toArray(); + + for(int i: keys){ + write.i(i); + write.f(data.get(i)); + } + } + + @Override + public void read(Reads read, byte revision) { + super.read(read, revision); + data = new IntFloatMap(); + int len = read.i(); + for (int i = 0; i < len; i++){ + data.put(read.i(), read.f()); + } + } } } diff --git a/src/meld/world/blocks/crafting/RecipeCrafter.java b/src/meld/world/blocks/crafting/RecipeCrafter.java new file mode 100644 index 0000000..80527b5 --- /dev/null +++ b/src/meld/world/blocks/crafting/RecipeCrafter.java @@ -0,0 +1,285 @@ +package meld.world.blocks.crafting; + +import arc.Core; +import arc.func.Func; +import arc.graphics.Color; +import arc.graphics.g2d.TextureRegion; +import arc.math.Mathf; +import arc.struct.ObjectMap; +import arc.struct.Seq; +import arc.util.Eachable; +import arc.util.io.Reads; +import arc.util.io.Writes; +import meld.world.blocks.crafting.recipe.ItemRecipe; +import meld.world.blocks.crafting.recipe.Recipe; +import meld.world.blocks.crafting.recipe.TimedRecipe; +import mindustry.Vars; +import mindustry.entities.units.BuildPlan; +import mindustry.gen.Building; +import mindustry.type.Item; +import mindustry.type.ItemStack; +import mindustry.type.Liquid; +import mindustry.type.LiquidStack; +import mindustry.ui.Bar; +import mindustry.world.Block; +import mindustry.world.blocks.production.GenericCrafter; +import mindustry.world.draw.DrawBlock; +import mindustry.world.draw.DrawDefault; + +//HAAHHHAHAHAHHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +//So on top of basic crafter functions we have... uh... yeah....... +public class RecipeCrafter extends Block { + + public ObjectMap outputDirections = new ObjectMap<>(); + + private static final Seq tmpSlots = new Seq<>(); + + public RecipeCrafter(String name) { + super(name); + update = true; + solid = true; + } + + public void setRecipes(TimedRecipe... recipies){ + this.recipes.set(recipies); + } + + public int inputLiquidSlots, outputLiquidSlots; + + //list of items/liquids which this block accepts + public Seq inputLiquids = new Seq<>(); + public Seq inputItems = new Seq<>(); + + //List of items/liquids which get dumped + public Seq outputLiquids = new Seq<>(); + public Seq outputItems = new Seq<>(); + + public Seq recipes = new Seq<>(); + + public DrawBlock drawer = new DrawDefault(); + + @Override + public void drawPlanRegion(BuildPlan plan, Eachable list){ + drawer.drawPlan(this, plan, list); + } + + @Override + public TextureRegion[] icons(){ + return drawer.finalIcons(this); + } + + @Override + public boolean outputsItems(){ + return outputItems != null; + } + + @Override + public void getRegionsToOutline(Seq out){ + drawer.getRegionsToOutline(this, out); + } + + @Override + public void init() { + super.init(); + + //MeldBlocks.aspectOutlet.inputLiquids.add(MeldLiquids.aether);MeldBlocks.aspectOutlet.outputLiquids.add(MeldLiquids.aspect) + recipes.each(recipe -> { + if(recipe.inputItems != null) for(ItemStack item: recipe.inputItems){ + inputItems.add(item.item); + itemFilter[item.item.id] = true; + } + if(recipe.outputItems != null) for(ItemStack item: recipe.outputItems){ + outputItems.add(item.item); + } + if(recipe.inputLiquids != null) for(LiquidStack item: recipe.inputLiquids){ + inputLiquids.add(item.liquid); + liquidFilter[item.liquid.id] = true; + } + if(recipe.outputLiquids != null) for(LiquidStack item: recipe.outputLiquids){ + outputLiquids.add(item.liquid); + } + }); + } + + //Just addLiquidBar but with a name + public void addLiquidBar(String name, Func current){ + addBar(name, entity -> new Bar( + () -> current.get((T)entity) == null || entity.liquids.get(current.get((T)entity)) <= 0.001f ? Core.bundle.get("bar.liquid") : current.get((T)entity).localizedName, + () -> current.get((T)entity) == null ? Color.clear : current.get((T)entity).barColor(), + () -> current.get((T)entity) == null ? 0f : entity.liquids.get(current.get((T)entity)) / liquidCapacity) + ); + } + + + @Override + public void setBars() { + super.setBars(); + + if(inputLiquidSlots + outputLiquidSlots > 0){ + removeBar("liquid"); + for(int i = 0; i < inputLiquidSlots; i++){ + final int j = i; + addLiquidBar("liquid-in" + i, build -> { + RecipeCrafterBuild crafter = ((RecipeCrafterBuild) build); + return crafter.inputSlots.size <= j ? null : crafter.inputSlots.get(j); + }); + } + + for(int i = 0; i < outputLiquidSlots; i++){ + final int j = i; + addLiquidBar("liquid-out" + i, build -> { + RecipeCrafterBuild crafter = ((RecipeCrafterBuild) build); + return crafter.outputSlots.size <= j ? null : crafter.outputSlots.get(j); + }); + } + } + } + + @Override + public void load(){ + super.load(); + + drawer.load(this); + } + + public class RecipeCrafterBuild extends Building{ + + RecipeCrafter crafter; + public TimedRecipe recipe = null; + + public int last = -1; + public float[] times; + + public Seq inputSlots = new Seq<>(), outputSlots = new Seq<>(); + + @Override + public void created() { + super.created(); + crafter = (RecipeCrafter) block; + times = new float[recipes.size]; + } + + @Override + public void draw(){ + drawer.draw(this); + } + + @Override + public void drawLight(){ + super.drawLight(); + drawer.drawLight(this); + } + + @Override + public void transferLiquid(Building next, float amount, Liquid liquid) { + super.transferLiquid(next, amount, liquid); + } + + @Override + public boolean acceptLiquid(Building source, Liquid liquid) { + //If the respective slot is full, don't accept any more liquids + if(source == this ? + !outputSlots.contains(liquid) && outputSlots.size >= outputLiquidSlots + : + !inputSlots.contains(liquid) && inputSlots.size >= inputLiquidSlots + ) return false; + + return super.acceptLiquid(source, liquid); + } + + + @Override + public void handleLiquid(Building source, Liquid liquid, float amount) { + //TODO: Handle multislot + if(inputLiquids.contains(liquid) && outputLiquids.contains(liquid)){ + + } + + Seq slots = source == this ? outputSlots : inputSlots; + if(!slots.contains(liquid)){ + slots.add(liquid); + } + + this.liquids.add(liquid, amount); + } + + @Override + public void updateTile() { + super.updateTile(); + + tmpSlots.set(inputSlots); + tmpSlots.each(l -> { + if(Mathf.zero(liquids.get(l))) inputSlots.remove(l); + }); + tmpSlots.set(outputSlots); + tmpSlots.each(l -> { + if(Mathf.zero(liquids.get(l))) outputSlots.remove(l); + }); + + if(recipe != null && recipe.valid(block, this)){ + recipe.update(block, this); + float time = times[last]; + time += efficiency; + if(time >= recipe.craftTime){ + recipe.apply(crafter, this); + time %= recipe.craftTime; + } + times[last] = time; + } + else { + recipe = recipes.find(r -> r.valid(crafter, this)); + if(recipe != null) last = recipes.indexOf(recipe); + } + + dumpOutputs(); + } + + + public void dumpOutputs(){ + if(outputSlots.size > 0){ + + for(Liquid output: outputSlots){ + if(!outputDirections.containsKey(output)) { + dumpLiquid(output); + continue; + } + + int[] dirs = outputDirections.get(output); + for(int dir: dirs){ + dumpLiquid(output, 2f, dir); + } + } + } + } + + @Override + public void write(Writes write) { + super.write(write); + write.i(last); + write.i(times.length); + for(float f: times){ + write.f(f); + } + } + + @Override + public void read(Reads read, byte revision) { + super.read(read, revision); + last = read.i(); + int length = read.i(); + + times = new float[recipes.size]; + for(int i = 0; i < length; i++){ + times[i] = read.i(); + } + rehashSlots(); + } + + public void rehashSlots(){ + Vars.content.liquids().each(l -> { + if(outputLiquids.contains(l)) outputSlots.add(l); + if(inputLiquids.contains(l)) inputSlots.add(l); + }); + } + } +} diff --git a/src/meld/world/blocks/crafting/modules/AdditionModule.java b/src/meld/world/blocks/crafting/modules/AdditionModule.java new file mode 100644 index 0000000..9e4a2f7 --- /dev/null +++ b/src/meld/world/blocks/crafting/modules/AdditionModule.java @@ -0,0 +1,13 @@ +package meld.world.blocks.crafting.modules; + +import meld.world.blocks.crafting.ModularCrafter; + +public class AdditionModule extends ModularCrafter.CrafterModule { + int[] inputPins; + int outputPin; + + public AdditionModule(int outputPin, int... inputPins){ + this.outputPin = outputPin; + this.inputPins = inputPins; + } +} diff --git a/src/meld/world/blocks/crafting/modules/AttributeModule.java b/src/meld/world/blocks/crafting/modules/AttributeModule.java new file mode 100644 index 0000000..600085e --- /dev/null +++ b/src/meld/world/blocks/crafting/modules/AttributeModule.java @@ -0,0 +1,27 @@ +package meld.world.blocks.crafting.modules; + +import arc.util.Log; +import meld.world.blocks.crafting.ModularCrafter; +import mindustry.world.meta.Attribute; + +public class AttributeModule extends ModularCrafter.CrafterModule { + public int efficiencyPin; + + public Attribute attribute; + public float baseEfficiency = 1; + public float boostScale = 1; + public float maxBoost = 1; + public float minEfficiency = -1; + + @Override + public void update(ModularCrafter.ModularCrafterBuild build) { + float efficiency = baseEfficiency + Math.min(maxBoost, boostScale * build.block.sumAttribute(attribute, build.tileX(), build.tileY()) + attribute.env()); + + if(minEfficiency != -1 && efficiency < minEfficiency) { + build.setPin(efficiencyPin, 0); + return; + } + + build.data.put(efficiencyPin, efficiency); + } +} \ No newline at end of file diff --git a/src/meld/world/blocks/crafting/modules/ConsumeAspectModule.java b/src/meld/world/blocks/crafting/modules/ConsumeAspectModule.java new file mode 100644 index 0000000..3f32c21 --- /dev/null +++ b/src/meld/world/blocks/crafting/modules/ConsumeAspectModule.java @@ -0,0 +1,58 @@ +package meld.world.blocks.crafting.modules; + +import arc.math.Mathf; +import arc.struct.ObjectFloatMap; +import arc.struct.ObjectMap; +import meld.world.blocks.crafting.ModularCrafter; +import mindustry.type.Liquid; +import mindustry.type.LiquidStack; + +public class ConsumeAspectModule extends ModularCrafter.CrafterModule{ + public ObjectFloatMap efficiencyMap; + public ObjectFloatMap densityMap; + + float consumeRate; + public int efficiencyPin; + public int outputEfficiencyPin; + + public ConsumeAspectModule(float consumeRate, ObjectFloatMap efficiencyMap, ObjectFloatMap densityMap, int efficiencyPin, int outputEfficiencyPin) { + this.consumeRate = consumeRate; + this.efficiencyMap = efficiencyMap; + this.densityMap = densityMap; + this.efficiencyPin = efficiencyPin; + this.outputEfficiencyPin = outputEfficiencyPin; + } + + @Override + public void update(ModularCrafter.ModularCrafterBuild build) { + float efficiency = build.getPin(efficiencyPin); + if(efficiency == 0) return; + + float highest = 0; + Liquid liquid = null; + for(Liquid aspect: efficiencyMap.keys()){ + if(!Mathf.zero(build.liquids.get(aspect))){ + float current = efficiencyMap.get(aspect, 1); + if(current > highest){ + liquid = aspect; + highest = current; + } + } + } + + if(liquid == null){ + build.setPin(outputEfficiencyPin, 0); + return; + } + + float amount = build.liquids.get(liquid); + float consumeAmount = consumeRate * efficiency/densityMap.get(liquid, 1); + float maxEfficiency = Math.min(amount/consumeAmount, 1); + + consumeAmount *= maxEfficiency; + + build.liquids.remove(liquid, consumeAmount); + + build.setPin(outputEfficiencyPin, efficiency * maxEfficiency * efficiencyMap.get(liquid, 1)); + } +} diff --git a/src/meld/world/blocks/crafting/modules/ConsumeGate.java b/src/meld/world/blocks/crafting/modules/ConsumeGate.java index e323ce3..bb79adf 100644 --- a/src/meld/world/blocks/crafting/modules/ConsumeGate.java +++ b/src/meld/world/blocks/crafting/modules/ConsumeGate.java @@ -1,7 +1,10 @@ package meld.world.blocks.crafting.modules; +import meld.world.blocks.LiquidUtil; import meld.world.blocks.crafting.ModularCrafter; import mindustry.type.ItemStack; +import mindustry.type.Liquid; +import mindustry.type.LiquidStack; //If item requirement is not met, set the output to 0. Otherwise, set the output to one. public class ConsumeGate extends ModularCrafter.CrafterModule { @@ -10,13 +13,28 @@ public ConsumeGate(ItemStack[] items, int outputPin){ this.items = items; this.outputPin = outputPin; } + public ConsumeGate(LiquidStack[] liquids, int outputPin){ + this.liquids = liquids; + this.outputPin = outputPin; + } + public ConsumeGate(ItemStack[] items, LiquidStack[] liquids, int outputPin){ + this.items = items; + this.liquids = liquids; + this.outputPin = outputPin; + } public ItemStack[] items; + public LiquidStack[] liquids; public int outputPin; @Override public void update(ModularCrafter.ModularCrafterBuild build) { - build.setPin(outputPin,build.items.has(items) ? 1 : 0); + float out = 1; + + if(liquids != null && !LiquidUtil.has(liquids, build)) out = 0; + + //Set the output to zero if the build doesn't have the items, otherwise set it to whatever the out is + build.setPin(outputPin,build.items.has(items) ? out : 0); } } diff --git a/src/meld/world/blocks/crafting/modules/GateModule.java b/src/meld/world/blocks/crafting/modules/GateModule.java new file mode 100644 index 0000000..f740b85 --- /dev/null +++ b/src/meld/world/blocks/crafting/modules/GateModule.java @@ -0,0 +1,115 @@ +package meld.world.blocks.crafting.modules; + +import arc.struct.Seq; +import meld.world.blocks.LiquidUtil; +import meld.world.blocks.crafting.ModularCrafter; +import meld.world.blocks.crafting.recipe.ItemRecipe; +import mindustry.type.ItemStack; +import mindustry.type.LiquidStack; + +public class GateModule extends ModularCrafter.CrafterModule { + + + int outputPin; + + public Seq conditions = new Seq<>(); + + public GateModule(){ + + } + + public GateModule(int outputPin, CrafterCondition... conditions){ + this.outputPin = outputPin; + this.conditions.set(conditions); + } + + @Override + public void update(ModularCrafter.ModularCrafterBuild build) { + build.setPin(outputPin, validate(build) ? 1 : 0); + } + + public boolean validate(ModularCrafter.ModularCrafterBuild build){ + for (var condition: conditions){ + if(!condition.valid(build)) return false; + } + return true; + } + + public abstract static class CrafterCondition{ + public abstract boolean valid(ModularCrafter.ModularCrafterBuild build); + } + + public static class ConsumeCondition extends CrafterCondition{ + public ConsumeCondition(ItemStack[] items){ + this.items = items; + } + + public ConsumeCondition(LiquidStack[] liquids){ + this.liquids = liquids; + } + + public ConsumeCondition(ItemStack[] items, LiquidStack[] liquids){ + this.items = items; + this.liquids = liquids; + } + + public ItemStack[] items; + public LiquidStack[] liquids; + + public boolean valid(ModularCrafter.ModularCrafterBuild build){ + if(liquids != null && !LiquidUtil.has(liquids, build)) return false; + + //Set the output to zero if the build doesn't have the items, otherwise set it to whatever the out is + return build.items.has(items); + } + } + public static class OutputCondition extends CrafterCondition{ + public OutputCondition(ItemStack[] items){ + this.items = items; + } + + public OutputCondition(LiquidStack[] liquids){ + this.liquids = liquids; + } + + public OutputCondition(ItemStack[] items, LiquidStack[] liquids){ + this.items = items; + this.liquids = liquids; + } + + public ItemStack[] items; + public LiquidStack[] liquids; + + public boolean valid(ModularCrafter.ModularCrafterBuild build){ + if(items != null){ + for(var output : items){ + if(build.items.get(output.item) + output.amount > build.block.itemCapacity){ + return false; + } + } + } + if(liquids != null){ + for(var output: liquids){ + if(build.liquids.get(output.liquid) + output.amount >= build.block.liquidCapacity){ + return false; + } + } + } + return true; + } + } + + public static class RecipeCondition extends CrafterCondition{ + public ItemRecipe recipe; + + public RecipeCondition(ItemRecipe recipe){ + this.recipe = recipe; + } + + @Override + public boolean valid(ModularCrafter.ModularCrafterBuild build) { + return recipe.valid(build.block, build); + } + } + +} diff --git a/src/meld/world/blocks/crafting/modules/LambdaModule.java b/src/meld/world/blocks/crafting/modules/LambdaModule.java new file mode 100644 index 0000000..661f70e --- /dev/null +++ b/src/meld/world/blocks/crafting/modules/LambdaModule.java @@ -0,0 +1,14 @@ +package meld.world.blocks.crafting.modules; + +import arc.func.Cons; +import meld.world.blocks.crafting.ModularCrafter; + +public class LambdaModule extends ModularCrafter.CrafterModule { + public Cons updater; + + @Override + public void update(ModularCrafter.ModularCrafterBuild build) { + updater.get(build); + } + +} diff --git a/src/meld/world/blocks/crafting/modules/ProduceLiquidModule.java b/src/meld/world/blocks/crafting/modules/ProduceLiquidModule.java index 560af62..590998e 100644 --- a/src/meld/world/blocks/crafting/modules/ProduceLiquidModule.java +++ b/src/meld/world/blocks/crafting/modules/ProduceLiquidModule.java @@ -1,5 +1,6 @@ package meld.world.blocks.crafting.modules; +import arc.math.Mathf; import meld.world.blocks.crafting.ModularCrafter; import mindustry.type.LiquidStack; @@ -15,6 +16,7 @@ public ProduceLiquidModule(LiquidStack liquid, int efficiencyPin){ @Override public void update(ModularCrafter.ModularCrafterBuild build) { float efficiency = build.getPin(efficiencyPin); - build.liquids.add(liquid.liquid, liquid.amount * efficiency); + float addedAmount = Math.min(liquid.amount * efficiency, Mathf.maxZero(build.block.liquidCapacity - build.liquids.get(liquid.liquid))); + build.liquids.add(liquid.liquid, addedAmount); } } diff --git a/src/meld/world/blocks/crafting/modules/RecipeCraftingModule.java b/src/meld/world/blocks/crafting/modules/RecipeCraftingModule.java new file mode 100644 index 0000000..2320925 --- /dev/null +++ b/src/meld/world/blocks/crafting/modules/RecipeCraftingModule.java @@ -0,0 +1,19 @@ +package meld.world.blocks.crafting.modules; + +import meld.world.blocks.crafting.ModularCrafter; +import meld.world.blocks.crafting.recipe.Recipe; + +public class RecipeCraftingModule extends ModularCrafter.CraftingModule { + public Recipe recipe; + + + @Override + public boolean canCraft(ModularCrafter.ModularCrafterBuild build) { + return recipe.valid(build.block, build); + } + + @Override + public void craft(ModularCrafter.ModularCrafterBuild build) { + recipe.apply(build.block, build); + } +} diff --git a/src/meld/world/blocks/crafting/recipe/ItemRecipe.java b/src/meld/world/blocks/crafting/recipe/ItemRecipe.java new file mode 100644 index 0000000..97e5644 --- /dev/null +++ b/src/meld/world/blocks/crafting/recipe/ItemRecipe.java @@ -0,0 +1,87 @@ +package meld.world.blocks.crafting.recipe; + +import arc.util.Log; +import arc.util.Nullable; +import meld.world.blocks.LiquidUtil; +import mindustry.gen.Building; +import mindustry.type.ItemStack; +import mindustry.type.LiquidStack; +import mindustry.world.Block; + +public class ItemRecipe extends Recipe{ + + @Nullable + public ItemStack[] inputItems; + @Nullable + public ItemStack[] outputItems; + + @Nullable + public LiquidStack[] inputLiquids; + @Nullable + public LiquidStack[] outputLiquids; + + public ItemRecipe(){ + + } + + public ItemRecipe(ItemStack[] inputItems, ItemStack[] outputItems){ + this.inputItems = inputItems; + this.outputItems = outputItems; + }; + + @Override + public boolean valid(Block block, Building build){ + if(outputItems != null){ + for(var output : outputItems){ + if(build.items.get(output.item) + output.amount > build.block.itemCapacity){ + return false; + } + } + } + if(outputLiquids != null){ + for(var output: outputLiquids){ + if(build.liquids.get(output.liquid) + output.amount >= build.block.liquidCapacity){ + return false; + } + } + } + if(inputLiquids != null && !LiquidUtil.has(inputLiquids, build)) { + return false; + } + + //Set the output to zero if the build doesn't have the items, otherwise set it to whatever the out is + return build.items == null || build.items.has(inputItems); + } + + @Override + public void apply(Block block, Building building) { + if(inputItems != null) building.items.remove(inputItems); + + if(outputItems != null) { + for (ItemStack item : outputItems) { + building.items.add(item.item, item.amount); + } + } + + if(inputLiquids != null) LiquidUtil.remove(inputLiquids, building.liquids); + if(outputLiquids != null) LiquidUtil.add(outputLiquids, building, building); + } + + //Builder methods + public ItemRecipe input(ItemStack[] items){ + inputItems = items; + return this; + } + public ItemRecipe output(ItemStack[] items){ + outputItems = items; + return this; + } + public ItemRecipe input(LiquidStack[] liquids){ + inputLiquids = liquids; + return this; + } + public ItemRecipe output(LiquidStack[] liquids){ + outputLiquids = liquids; + return this; + } +} diff --git a/src/meld/world/blocks/crafting/recipe/Recipe.java b/src/meld/world/blocks/crafting/recipe/Recipe.java new file mode 100644 index 0000000..846f8d1 --- /dev/null +++ b/src/meld/world/blocks/crafting/recipe/Recipe.java @@ -0,0 +1,14 @@ +package meld.world.blocks.crafting.recipe; + +import mindustry.gen.Building; +import mindustry.world.Block; + +public abstract class Recipe { + + public abstract boolean valid(T block, A building); + public abstract void apply(T block, A building); + public void update(T block, A building) {} + //accepted liquids ey? + public void init(T block) {} + +} diff --git a/src/meld/world/blocks/crafting/recipe/SpoolRecipe.java b/src/meld/world/blocks/crafting/recipe/SpoolRecipe.java new file mode 100644 index 0000000..99c8fc0 --- /dev/null +++ b/src/meld/world/blocks/crafting/recipe/SpoolRecipe.java @@ -0,0 +1,26 @@ +package meld.world.blocks.crafting.recipe; + +import meld.world.blocks.Gauze; +import mindustry.type.ItemStack; + +public class SpoolRecipe extends Recipe { + + public SpoolRecipe(ItemStack ammo, float energy){ + this.ammo = ammo; + this.energy = energy; + } + + public ItemStack ammo; + public float energy; + + @Override + public boolean valid(Gauze block, Gauze.GauzeBuild build) { + return build.items.has(ammo.item, ammo.amount) && build.energy + energy <= block.spoolStorage; + } + + @Override + public void apply(Gauze block, Gauze.GauzeBuild build) { + build.removeStack(ammo.item, ammo.amount); + build.energy += energy; + } +} diff --git a/src/meld/world/blocks/crafting/recipe/TimedRecipe.java b/src/meld/world/blocks/crafting/recipe/TimedRecipe.java new file mode 100644 index 0000000..f935a84 --- /dev/null +++ b/src/meld/world/blocks/crafting/recipe/TimedRecipe.java @@ -0,0 +1,10 @@ +package meld.world.blocks.crafting.recipe; + +import meld.world.blocks.crafting.RecipeCrafter; + +public class TimedRecipe extends ItemRecipe { + + + public float craftTime = 60; + +} diff --git a/src/meld/world/blocks/AspectPipe.java b/src/meld/world/blocks/fluid/AspectPipe.java similarity index 69% rename from src/meld/world/blocks/AspectPipe.java rename to src/meld/world/blocks/fluid/AspectPipe.java index eee07ac..5ca01aa 100644 --- a/src/meld/world/blocks/AspectPipe.java +++ b/src/meld/world/blocks/fluid/AspectPipe.java @@ -1,8 +1,9 @@ -package meld.world.blocks; +package meld.world.blocks.fluid; import arc.math.Mathf; import arc.math.geom.Geometry; -import meld.content.MeldLiquids; +import arc.util.Log; +import meld.world.blocks.crafting.RecipeCrafter; import mindustry.Vars; import mindustry.gen.Building; import mindustry.type.Liquid; @@ -11,7 +12,12 @@ import mindustry.world.blocks.liquid.Conduit; import mindustry.world.blocks.liquid.LiquidRouter; +import static meld.content.MeldLiquids.*; + public class AspectPipe extends Conduit { + static final float rotatePad = 6, hpad = rotatePad / 2f / 4f; + static final float[][] rotateOffsets = {{hpad, hpad}, {-hpad, hpad}, {-hpad, -hpad}, {hpad, -hpad}}; + public AspectPipe(String name) { super(name); } @@ -23,10 +29,13 @@ public boolean blends(Tile tile, int rotation, int otherx, int othery, int other public class AspectPipeBuild extends ConduitBuild{ + public float lastMoved = 0; + public void updateTile() { + lastMoved = 0; this.smoothLiquid = Mathf.lerpDelta(this.smoothLiquid, this.liquids.currentAmount() / liquidCapacity, 0.05F); if (this.liquids.currentAmount() > 1.0E-4F && this.timer(timerFlow, 1.0F)) { - this.moveLiquidForward(leaks, this.liquids.current()); + lastMoved = moveLiquidForward(leaks, this.liquids.current()); this.noSleep(); //Attempt to push liquids to the sides @@ -34,7 +43,7 @@ public void updateTile() { //get the tile above and below the current pipe, accounting for rotation Tile t = Vars.world.tile(tile.x + Geometry.d4(1 + i * 2 + rotation).x, tile.y + Geometry.d4(1 + i * 2 + rotation).y); - if(t == null || t.build == null || !t.build.block.hasLiquids || t.build.liquids == null || t.build.block.consumers.length == 0) continue; + if(t == null || t.build == null || !t.build.block.hasLiquids || t.build.liquids == null || (!(t.build.block instanceof RecipeCrafter) && t.build.block.consumers.length == 0)) continue; moveLiquid(t.build, liquids.current()); } @@ -50,20 +59,19 @@ public float moveLiquid(Building other, Liquid liquid) { float total = 0; if(!Mathf.zero(liquids.get(liquid))){ - this.incrementDump(this.proximity.size); + incrementDump(this.proximity.size); other = other.getLiquidDestination(this, liquid); - if (other == null || !other.block.hasLiquids || other.liquids == null) return 0; //Transfer regular liquid - if(this.canDumpLiquid(other, liquid)) { + if(canDumpLiquid(other, liquid)) { float ofract = other.liquids.get(liquid) / other.block.liquidCapacity; float fract = this.liquids.get(liquid) / this.block.liquidCapacity; if (ofract < fract) { float amount = (fract - ofract) * this.block.liquidCapacity; - float flow = Math.min(other.block.liquidCapacity - other.liquids.get(liquid), amount); + if (other.acceptLiquid(this, liquid)) { other.handleLiquid(this, liquid, flow); this.liquids.remove(liquid, flow); @@ -72,10 +80,11 @@ public float moveLiquid(Building other, Liquid liquid) { } } + Liquid outletProduct = outletMapping.get(liquid); //At the same time try dumping aspect - if(!(other instanceof ConduitBuild || other instanceof LiquidRouter.LiquidRouterBuild) && liquid == MeldLiquids.aether && this.canDumpLiquid(other, MeldLiquids.aspect)) { + if(outletProduct != null && !(other instanceof ConduitBuild || other instanceof LiquidRouter.LiquidRouterBuild) && this.canDumpLiquid(other, outletProduct)) { Liquid original = liquid; - liquid = MeldLiquids.aspect; + liquid = outletProduct; float ofract = other.liquids.get(liquid) / other.block.liquidCapacity; float fract = this.liquids.get(original) / this.block.liquidCapacity; @@ -86,7 +95,7 @@ public float moveLiquid(Building other, Liquid liquid) { float flow = Math.min(other.block.liquidCapacity - other.liquids.get(liquid), amount) * 10; if (other.acceptLiquid(this, liquid)) { other.handleLiquid(this, liquid, flow); - this.liquids.remove(original, flow/10); + this.liquids.remove(original, flow/aetherDensities.get(liquid, 1)/10); total += amount; } @@ -96,32 +105,13 @@ public float moveLiquid(Building other, Liquid liquid) { return total; } - @Override - public void transferLiquid(Building next, float amount, Liquid liquid) { - transferLiquid(next, amount, liquid, false); - } - - //Translating original liquid to the pipe's target liquid; - public void transferLiquid(Building next, float amount, Liquid liquid, boolean translating){ - - if(translating){ - Liquid original = liquid; - liquid = MeldLiquids.aspect; - - float flow = Math.min(next.block.liquidCapacity - next.liquids.get(liquid), amount); - if (next.acceptLiquid(this, liquid)) { - next.handleLiquid(this, liquid, flow); - this.liquids.remove(original, flow/10); - } - - return; - } - float flow = Math.min(next.block.liquidCapacity - next.liquids.get(liquid), amount); - if (next.acceptLiquid(this, liquid)) { - next.handleLiquid(this, liquid, flow); - this.liquids.remove(liquid, flow); - } + //TODO: Figure out why this even has to be changed to get aspect pipes routing backwards when vanilla conduits don't + @Override + public boolean acceptLiquid(Building source, Liquid liquid){ + noSleep(); + return (liquids.current() == liquid || liquids.currentAmount() < 0.2f) + && (tile == null || source == this || (source.relativeTo(tile.x, tile.y) + 2) % 4 != rotation || source instanceof AspectPipeBuild); } } } diff --git a/src/meld/world/blocks/fluid/ChannelDirector.java b/src/meld/world/blocks/fluid/ChannelDirector.java new file mode 100644 index 0000000..1cdceb4 --- /dev/null +++ b/src/meld/world/blocks/fluid/ChannelDirector.java @@ -0,0 +1,33 @@ +package meld.world.blocks.fluid; + +import arc.Core; +import arc.graphics.g2d.Draw; +import arc.util.Log; +import meld.world.WorldUtil; +import mindustry.gen.Building; + +public class ChannelDirector extends FlexibleSizeJunction{ + + @Override + public void load() { + super.load(); + } + public ChannelDirector(String name) { + super(name); + rotate = true; + quickRotate = true; + } + + public class DirectorBuild extends FlexibleBuild{ + + @Override + public boolean acceptDirection(Building source, Building junction, int dir) { + return dir == rotation; + } + + @Override + public void draw(){ + Draw.rect(region, x, y, rotation * 90); + } + } +} diff --git a/src/meld/world/blocks/fluid/ChannelValve.java b/src/meld/world/blocks/fluid/ChannelValve.java new file mode 100644 index 0000000..19dc991 --- /dev/null +++ b/src/meld/world/blocks/fluid/ChannelValve.java @@ -0,0 +1,68 @@ +package meld.world.blocks.fluid; + +import arc.Core; +import arc.audio.Sound; +import arc.graphics.g2d.Draw; +import arc.graphics.g2d.TextureRegion; +import arc.util.Eachable; +import mindustry.entities.units.BuildPlan; +import mindustry.gen.Sounds; + +//A switch + liquid junction +public class ChannelValve extends FlexibleSizeJunction { + public Sound clickSound = Sounds.click; + + public TextureRegion onRegion; + + @Override + public void load() { + super.load(); + onRegion = Core.atlas.find(name + "-on", "clear"); + } + + public ChannelValve(String name) { + super(name); + configurable = true; + update = true; + drawDisabled = false; + autoResetEnabled = false; + configureSound = Sounds.none; + + config(Boolean.class, (ValveBuild entity, Boolean b) -> entity.enabled = b); + } + + @Override + public TextureRegion[] icons() { + return new TextureRegion[]{onRegion}; + } + + public TextureRegion getPlanRegion(BuildPlan plan, Eachable list){ + if(plan.config instanceof Boolean b && b) return onRegion; + return fullIcon; + } + + + public class ValveBuild extends FlexibleBuild{ + + @Override + public boolean configTapped(){ + configure(!enabled); + clickSound.at(this); + return false; + } + + @Override + public Boolean config(){ + return enabled; + } + + @Override + public void draw(){ + super.draw(); + + if(enabled){ + Draw.rect(onRegion, x, y); + } + } + } +} diff --git a/src/meld/world/blocks/fluid/ChannelVent.java b/src/meld/world/blocks/fluid/ChannelVent.java new file mode 100644 index 0000000..1499aca --- /dev/null +++ b/src/meld/world/blocks/fluid/ChannelVent.java @@ -0,0 +1,44 @@ +package meld.world.blocks.fluid; + +import arc.graphics.g2d.Draw; +import arc.math.Mathf; +import mindustry.entities.Puddles; +import mindustry.type.Liquid; +import mindustry.world.blocks.liquid.LiquidRouter; +import mindustry.world.meta.Attribute; + +public class ChannelVent extends LiquidRouter { + + public float minPressure = 0; + public float ventRate = 1; + public float ventDelay = 10; + + int ventTimer = timers++; + + public ChannelVent(String name) { + super(name); + } + + public class ChannelVentBuild extends LiquidRouterBuild{ + @Override + public void updateTile() { + super.updateTile(); + + Liquid liquid = liquids.current(); + + if(timer.get(ventTimer, ventDelay) && liquid.gas || liquid.boilPoint <= Attribute.heat.env()){ + float ventEfficiency = (liquids.get(liquid)/liquidCapacity - minPressure)/(1 - minPressure); + + if(ventEfficiency > 0){ + + float leakAmount = Math.min(ventEfficiency * ventRate * ventDelay, liquids.get(liquid)); + + if(leakAmount > 1E-4){ + Puddles.deposit(tile, tile, liquid, leakAmount, true, true); + liquids.remove(liquid, leakAmount); + } + } + } + } + } +} diff --git a/src/meld/world/blocks/fluid/FlexibleSizeJunction.java b/src/meld/world/blocks/fluid/FlexibleSizeJunction.java new file mode 100644 index 0000000..d66b1f0 --- /dev/null +++ b/src/meld/world/blocks/fluid/FlexibleSizeJunction.java @@ -0,0 +1,122 @@ +package meld.world.blocks.fluid; + +import arc.graphics.g2d.Draw; +import arc.math.geom.Geometry; +import arc.math.geom.Point2; +import arc.math.geom.Position; +import arc.util.Log; +import arc.util.Tmp; +import meld.world.WorldUtil; +import mindustry.Vars; +import mindustry.content.Fx; +import mindustry.gen.Building; +import mindustry.type.Liquid; +import mindustry.world.blocks.liquid.LiquidJunction; + +public class FlexibleSizeJunction extends LiquidJunction { + public boolean enabledToggles = true; + + public FlexibleSizeJunction(String name) { + super(name); + } + + public boolean usePassedOffset = true; + + public class FlexibleBuild extends LiquidJunctionBuild{ + + @Override + public Building getLiquidDestination(Building source, Liquid liquid){ + return getLiquidDestination(source, liquid, null); + } + + //Subclasses can change this + public float addedRotation(Building source, int dir){ + return 0; + } + + //With this too + public int transportRotation(Building source, int dir){ + return dir; + } + + public boolean acceptDirection(Building source, Building junction, int dir){ + return true; + } + + public Building getLiquidDestination(Building source, Liquid liquid, Position otherOffset){ + if(!enabled && enabledToggles) return this; + + //Find which direction the offset should go + int dir = WorldUtil.relativeTo(source.tile.x, source.tile.y, tile.x, tile.y); + Point2 direction = Geometry.d4(dir); + + //Direction offset vector + Tmp.v1.set(direction.x, direction.y).scl(size); + + //Tile offset vector, can grab from previous junction if it's already been calculated + int tolerance = size/2; + if(otherOffset != null){ + Tmp.v2.set(otherOffset).scl(size); + } + else { + //Store the unclamped offset for later + Tmp.v2.set(source.tile.x, source.tile.y).sub(tile.x, tile.y); + } + + //Start with the direction offset vector + Tmp.v3.set(Tmp.v1); + + //Rotate the offsets where aplicable + float rotationOffset = addedRotation(source, dir); + if(rotationOffset != 0){ + Tmp.v3.rotate(addedRotation(source, dir)); + Tmp.v2.rotate(addedRotation(source, dir)); + } + + //If usePassedOffset is true, grab the offset from the previous junction where possible, and clamp it + if(usePassedOffset) Tmp.v3.add(Tmp.v4.set(Tmp.v2).clamp(-tolerance, -tolerance, tolerance, tolerance)); + + + //Rotate dir too + int rotatedDir = transportRotation(source, dir); + + //Scale the offsets, add them to the tile's world coords + Tmp.v3.scl(Vars.tilesize); + Tmp.v3.add(tile.worldx(), tile.worldy()); + + Building next = Vars.world.buildWorld(Tmp.v3.x, Tmp.v3.y); + + boolean canSend = true; + //Prioritise sending down the corosponding output where possible + if(next instanceof FlexibleBuild b){ + canSend = b.acceptDirection(source, this, rotatedDir); + if(canSend) return b.getLiquidDestination(this, liquid, Tmp.v2.scl(1f/size)); + } + + //If next is null then attempt to pas fluid onto other next valid junction + if(next == null || (!next.acceptLiquid(this, liquid) && !(next.block instanceof LiquidJunction)) && next != this){ + //Try to find a flexible size junction in the direction we're routing to + + //Find the direction counter clockwise of the direction we're routing to + Point2 sidewaysDir = Geometry.d4(rotatedDir + 1); + Point2 rotatedDirection = Geometry.d4(rotatedDir); + + int tolerancePlus = tolerance + 1; + for(int i = 0; i < size; i++){ + int j = i - tolerance; + //We want a tile outside of the block in the direction we're routing to, then all the tiles along that face + Building junction = Vars.world.build(tile.x + rotatedDirection.x * tolerancePlus + sidewaysDir.x * j, tile.y + rotatedDirection.y * tolerancePlus + sidewaysDir.y * j); + + //If we find a junction, pass along the offset + if(junction instanceof FlexibleBuild b && b.acceptDirection(source, this, rotatedDir)){ + return b.getLiquidDestination(this, liquid, Tmp.v2.scl(1f/size)); + } + } + + return this; + } + //If all else fails, just do the default behaviour + return canSend ? next.getLiquidDestination(this, liquid) : null; + } + } +} diff --git a/src/meld/world/blocks/fluid/Pipebox.java b/src/meld/world/blocks/fluid/Pipebox.java new file mode 100644 index 0000000..d92e12e --- /dev/null +++ b/src/meld/world/blocks/fluid/Pipebox.java @@ -0,0 +1,133 @@ +package meld.world.blocks.fluid; + +import arc.Core; +import arc.audio.Sound; +import arc.graphics.g2d.Draw; +import arc.graphics.g2d.TextureRegion; +import arc.math.geom.Point2; +import arc.math.geom.Position; +import arc.util.Eachable; +import arc.util.Log; +import arc.util.Tmp; +import arc.util.io.Reads; +import arc.util.io.Writes; +import mindustry.Vars; +import mindustry.content.Fx; +import mindustry.entities.units.BuildPlan; +import mindustry.game.Team; +import mindustry.gen.Building; +import mindustry.gen.Sounds; +import mindustry.type.Liquid; +import mindustry.world.Tile; +import mindustry.world.blocks.production.BeamDrill; + +public class Pipebox extends FlexibleSizeJunction{ + public Sound clickSound = Sounds.click; + + public TextureRegion onRegion, directionRegion; + + public TextureRegion[] markerRegions = new TextureRegion[2]; + + @Override + public void load() { + super.load(); + onRegion = Core.atlas.find(name + "-on", "clear"); + markerRegions[0] = Core.atlas.find(name + "-marker"); + markerRegions[1] = Core.atlas.find(name + "-marker-on"); + directionRegion = Core.atlas.find(name + "-direction", "clear"); + } + + public Pipebox(String name) { + super(name); + configurable = true; + update = true; + drawDisabled = false; + autoResetEnabled = false; + configureSound = Sounds.none; + + enabledToggles = false; + saveConfig = true; + rotate = true; + + config(Boolean.class, (PipeboxBuild entity, Boolean b) -> { + entity.invert = b; + }); + } + + @Override + public TextureRegion[] icons() { + return new TextureRegion[]{region, markerRegions[0], directionRegion}; + } + + @Override + public void drawPlanRegion(BuildPlan plan, Eachable list){ + if(plan.config instanceof Boolean b && b) { + Draw.rect(onRegion, plan.drawx(), plan.drawy()); + Draw.rect(markerRegions[1], plan.drawx(), plan.drawy(), plan.rotation * 90); + } + else { + Draw.rect(region, plan.drawx(), plan.drawy()); + Draw.rect(markerRegions[0], plan.drawx(), plan.drawy(), plan.rotation * 90); + } + Draw.rect(directionRegion, plan.drawx(), plan.drawy(), plan.rotation * 90); + } + + //The rotation offsets themselves + public int[] rotMappings = new int[]{ + 90, -90, 90, -90 + }; + + //actually offsets to dir because lazy + public int[] dirMappings = new int[]{ + 1, -1, 1, -1 + }; + + public class PipeboxBuild extends FlexibleBuild{ + + public boolean invert = false; + + @Override + public boolean configTapped(){ + configure(!invert); + clickSound.at(this); + return false; + } + + @Override + public Boolean config(){ + return invert; + } + + @Override + public void draw(){ + super.draw(); + + if(invert){ + Draw.rect(onRegion, x, y); + } + Draw.rect(markerRegions[invert ? 1 : 0], x, y, rotation * 90); + Draw.rect(directionRegion, x, y, rotation * 90); + } + + @Override + public float addedRotation(Building source, int dir) { + return rotMappings[dir] * (invert ^ rotation % 2 == 0 ? -1 : 1); + } + @Override + public int transportRotation(Building source, int dir) { + return (dir + dirMappings[dir] * (invert ^ rotation % 2 == 0 ? -1 : 1)) % 4; + } + + @Override + public void write(Writes write) { + super.write(write); + write.bool(invert); + } + + @Override + public void read(Reads read, byte revision) { + super.read(read, revision); + invert = read.bool(); + } + } +} diff --git a/src/meld/world/blocks/fluid/ValveController.java b/src/meld/world/blocks/fluid/ValveController.java new file mode 100644 index 0000000..9009c2a --- /dev/null +++ b/src/meld/world/blocks/fluid/ValveController.java @@ -0,0 +1,216 @@ +package meld.world.blocks.fluid; + +import arc.Core; +import arc.audio.Sound; +import arc.graphics.Color; +import arc.graphics.g2d.Draw; +import arc.graphics.g2d.Fill; +import arc.graphics.g2d.TextureRegion; +import arc.math.Mathf; +import arc.scene.ui.layout.Table; +import arc.struct.Seq; +import arc.util.Eachable; +import arc.util.Log; +import arc.util.Tmp; +import arc.util.io.Reads; +import arc.util.io.Writes; +import mindustry.Vars; +import mindustry.entities.units.BuildPlan; +import mindustry.gen.Building; +import mindustry.gen.Icon; +import mindustry.gen.Sounds; +import mindustry.graphics.Layer; +import mindustry.graphics.Pal; +import mindustry.ui.Styles; +import mindustry.world.blocks.power.BeamNode; + +import static mindustry.Vars.ui; + +//When detecting nearby fluids, turn nearby valves off. Can be inverted. +public class ValveController extends FlexibleSizeJunction{ + + public int updateTimer = timers++; + public float minPressure = 0.1f; + + public float padding = 5/4f; + + public Sound clickSound = Sounds.click; + + public TextureRegion[] signRegions = new TextureRegion[2]; + public TextureRegion bottomRegion = new TextureRegion(); + + public Color indicatorColor = Pal.health, overflowColor = Pal.surge, fillColor = Pal.heal; + + @Override + public void load() { + super.load(); + bottomRegion = Core.atlas.find(name + "-bottom"); + signRegions[0] = Core.atlas.find(name + "-sign", "clear"); + signRegions[1] = Core.atlas.find(name + "-sign-inverted", "clear"); + } + + @Override + public TextureRegion[] icons() { + return new TextureRegion[]{bottomRegion, signRegions[0], region}; + } + + public ValveController(String name) { + super(name); + configurable = true; + saveConfig = true; + update = true; + drawDisabled = false; + autoResetEnabled = false; + configureSound = Sounds.none; + + rotate = true; + quickRotate = true; + + config(Boolean.class, (ValveControllerBuild entity, Boolean b) -> entity.invert = b); + config(Float.class, (ValveControllerBuild entity, Float f) -> entity.threshold = f); + config(Float[].class, (ValveControllerBuild entity, Float[] floats) -> { + entity.threshold = floats[0]; + entity.invert = floats[1] == -1f; + }); + } + + public void drawThreshold(float x, float y, float threshold){ + Fill.rect(x, y - (1 - threshold)/2f * (Vars.tilesize) - threshold * padding + padding, Vars.tilesize, (Vars.tilesize - padding * 2) * threshold); + } + + @Override + public void drawPlanRegion(BuildPlan plan, Eachable list){ + float threshold = minPressure; + boolean invert = false; + + if(plan.config instanceof Float[] floats){ + threshold = floats[0]; + invert = floats[1] == -1f; + } + + Draw.z(Layer.blockUnder); + Draw.rect(bottomRegion, plan.drawx(), plan.drawy()); + + Draw.z(Layer.block); + + Draw.color(indicatorColor); + drawThreshold(plan.drawx(), plan.drawy(), threshold); + Draw.color(); + Draw.rect(signRegions[invert ? 1 : 0], plan.drawx(), plan.drawy(), plan.rotation * 90); + Draw.rect(region, plan.drawx(), plan.drawy()); + } + + + public class ValveControllerBuild extends FlexibleBuild{ + + public boolean invert = false; + public float threshold = minPressure; + public float lastTotal = 0; + + @Override + public void updateTile() { + super.updateTile(); + enablingLogic(); + } + + public void enablingLogic(){ + + lastTotal = 0; + proximity.each(b -> { + if(b.liquids != null) lastTotal += b.liquids.currentAmount()/b.block.liquidCapacity; + }); + + boolean enable = lastTotal >= threshold; + + if(invert) enable = !enable; + + Building b = tile.nearbyBuild(rotation); + if(b == null) return; + + if(b.block.configurable) b.configure(enable); + else b.enabled = enable; + } + + @Override + public boolean configTapped(){ + /* + configure(!invert); + + */ + clickSound.at(this); + return true; + } + + @Override + public void buildConfiguration(Table table){ + table.slider(0, 1, 0.1f, threshold, Vars.net.active(), this::configure).size(240, 40f); + table.row(); + table.button(Icon.pencil, Styles.cleari, () -> { + configure(!invert); + }).size(40f); + } + + @Override + public boolean onConfigureBuildTapped(Building other){ + if(this == other){ + deselect(); + return false; + } + + return true; + } + + @Override + public Float[] config(){ + return new Float[]{ + threshold, invert ? -1f : 1f + }; + } + + @Override + public void draw(){ + Draw.z(Layer.blockUnder); + + Draw.rect(bottomRegion, x, y); + + Draw.z(Layer.block); + + + //Im sure theres a simpler formula but like... come on + + // + float fin2 = Mathf.clamp(lastTotal); + Draw.color(fillColor); + drawThreshold(x, y, fin2); + + float fin = threshold; + Draw.color(indicatorColor); + drawThreshold(x, y, fin); + + float finFree = Math.min(fin, fin2); + Draw.color(overflowColor); + drawThreshold(x, y, finFree); + + Draw.color(); + + //Draw.rect(region, x, y); + Draw.rect(signRegions[invert ? 1 : 0], x, y, rotation * 90); + + Draw.rect(region, x, y); + } + + @Override + public void write(Writes write) { + super.write(write); + write.bool(invert); + write.f(threshold); + } + + @Override + public void read(Reads read, byte revision) { + super.read(read, revision); + invert = read.bool(); + threshold = read.f(); + } + } +} diff --git a/src/meld/world/blocks/fluid/VisualAspectPipe.java b/src/meld/world/blocks/fluid/VisualAspectPipe.java new file mode 100644 index 0000000..03096d9 --- /dev/null +++ b/src/meld/world/blocks/fluid/VisualAspectPipe.java @@ -0,0 +1,258 @@ +package meld.world.blocks.fluid; + +import arc.graphics.Blending; +import arc.graphics.g2d.Draw; +import arc.graphics.g2d.Fill; +import arc.graphics.g2d.TextureRegion; +import arc.math.Angles; +import arc.math.Interp; +import arc.math.Mathf; +import arc.math.Rand; +import arc.math.geom.Geometry; +import arc.math.geom.Point2; +import arc.util.Log; +import arc.util.Time; +import arc.util.Tmp; +import meld.content.MeldFx; +import mindustry.Vars; +import mindustry.gen.Building; +import mindustry.graphics.Drawf; +import mindustry.graphics.Layer; +import mindustry.type.Liquid; +import mindustry.world.draw.DrawLiquidTile; + +import static mindustry.Vars.renderer; +import static mindustry.Vars.tilesize; + +//PLEASEWORKPLEAEWORKAPSLEAOSKOPK +public class VisualAspectPipe extends AspectPipe { + protected static final Rand rand = new Rand(); + + public int sides = 12; + public float px = 0, py = 0; + public float alpha = 0.1f; + public int particles = 12; + public float particleRotation = 0, particleLife = 70f, particleRad = 4.2f, particleSize = 3f, fadeMargin = 0.4f, rotateScl = 3f; + + //Life that additional particles get drawn at + public float flowingLife = 15; + + //Alpha which flowing particles get + public float flowAlpha = 0.1f; + + //Distance which additional particles travel + public float particleTravel = 16; + public float cone = 45; + + //How long a pipe can go without transporting fluid while still maintaining the flow visual + public float flowGrace = 5; + + public boolean reverse = false, poly = false; + public Interp particleInterp = new Interp.PowIn(1.5f); + public Interp particleSizeInterp = Interp.slope; + public Blending blendMode = Blending.additive; + + public float effectChance = 0.1f; + public float visualFlowSpeed = 10; + + public boolean debugDraw = false; + + public VisualAspectPipe(String name) { + super(name); + } + + public class VisualPipeBuild extends AspectPipeBuild{ + + public float warmup = 0; + public float flowWarmup = 0; + public float noflowTime; + public Building front; + public float effectTimer = Mathf.random(); + + @Override + public void updateTile() { + super.updateTile(); + + warmup = Mathf.lerpDelta(warmup, liquids.currentAmount()/liquidCapacity, 0.05f); + + //Keep the flow visual high as possible for as long as flowGrace in points of no flow + noflowTime += Time.delta; + if(lastMoved > 0) noflowTime = 0; + + float flowWarmupTarget = Mathf.clamp(lastMoved/liquidCapacity * visualFlowSpeed); + + if(flowWarmupTarget > flowWarmup || noflowTime > flowGrace) flowWarmup = Mathf.lerpDelta(flowWarmup, flowWarmupTarget, 0.05f); + else flowWarmup = Mathf.lerpDelta(flowWarmup, flowWarmupTarget, 0.01f); + + effectTimer += effectChance * lastMoved/liquidCapacity; + + if(Mathf.chance(effectTimer)){ + effectTimer = 0 ; + + //Stupid + //Rotation 0 faces right so randomise particle spawn top and bottom + Tmp.v1.set(-0.5f, Mathf.random(-0.5f, 0.5f)).rotate(rotation * 90).scl(tilesize/4f); + + MeldFx.gasTransfer.at(x + Tmp.v1.x, y + Tmp.v1.y, rotation * 90, liquids.current().color); + } + } + + @Override + public float warmup() { + return Math.max(Interp.pow5Out.apply(warmup), flowWarmup); + } + + @Override + public void draw(){ + if(debugDraw){ + + Draw.z(Layer.blockUnder); + + drawInbetween(); + Draw.reset(); + return; + } + + int r = this.rotation; + + //draw extra conduits facing this one for tiling purposes + //WHY WHY WHY WHY WHYYYYYYYYYYYYYYYYYYYYYYYYYYYY + Draw.z(Layer.blockUnder); + for(int i = 0; i < 4; i++){ + if((blending & (1 << i)) != 0){ + int dir = r - i; + drawAt(x + Geometry.d4x(dir) * tilesize*0.75f, y + Geometry.d4y(dir) * tilesize*0.75f, 0, i == 0 ? r : dir, i != 0 ? SliceMode.bottom : SliceMode.top); + } + } + + Draw.z(Layer.blockUnder); + + drawInbetween(); + Draw.z(Layer.block); + + Draw.scl(xscl, yscl); + drawAt(x, y, blendbits, r, SliceMode.none); + Draw.reset(); + + if(capped && capRegion.found()) Draw.rect(capRegion, x, y, rotdeg()); + if(backCapped && capRegion.found()) Draw.rect(capRegion, x, y, rotdeg() + 180); + } + + @Override + protected void drawAt(float x, float y, int bits, int rotation, SliceMode slice){ + float angle = rotation * 90f; + Draw.color(botColor); + + Draw.z(Layer.blockUnder - 0.1f); + Draw.rect(sliced(botRegions[bits], slice), x, y, angle); + + int offset = yscl == -1 ? 3 : 0; + + int frame = liquids.current().getAnimationFrame(); + int gas = liquids.current().gas ? 1 : 0; + float ox = 0f, oy = 0f; + int wrapRot = (rotation + offset) % 4; + TextureRegion liquidr = bits == 1 && padCorners ? rotateRegions[wrapRot][gas][frame] : renderer.fluidFrames[gas][frame]; + + if(bits == 1 && padCorners){ + ox = rotateOffsets[wrapRot][0]; + oy = rotateOffsets[wrapRot][1]; + } + + Draw.z(Layer.blockUnder); + + //the drawing state machine sure was a great design choice with no downsides or hidden behavior!!! + float xscl = Draw.xscl, yscl = Draw.yscl; + Draw.scl(1f, 1f); + Drawf.liquid(sliced(liquidr, slice), x + ox, y + oy, smoothLiquid, liquids.current().color.write(Tmp.c1).a(1f)); + Draw.scl(xscl, yscl); + + Draw.z(Layer.block - 0.01f); + Draw.rect(sliced(topRegions[bits], slice), x, y, angle); + } + + public void drawInbetween(){ + Draw.z(Layer.blockUnder + 0.01f); + + Liquid current = liquids.current(); + + if(warmup() > 0f && current != null){ + float a = alpha * warmup(); + float a2 = flowAlpha * Interp.pow5Out.apply(flowWarmup); + + Draw.blend(blendMode); + Draw.color(current.color); + + float base = Time.time / particleLife; + float flowBase = Time.time/flowingLife; + + rand.setSeed(id); + + for(int i = 0; i < particles; i++){ + float finFlow = (rand.random(2f) + flowBase) % 1f; + + float fin = (rand.random(2f) + base) % 1f; + if(reverse) fin = 1f - fin; + float fout = 1f - fin; + + float straightness = fin * flowWarmup; + + float particleAngle = rand.random(360f) + (Time.time / rotateScl) % 360f; + float len = particleRad * particleInterp.apply(fout); + //1. Calculate offsets for regular draw particles + + Tmp.v1.set(len, 0).rotate(Mathf.clamp(particleAngle % 360, cone, 360-cone)); + + //2. calculate the stream offsets for steam particles + Tmp.v2.set(Tmp.v1); + Tmp.v2.y = -particleTravel + particleTravel * 2 * fin; + + //Lerp between the two, then rotatie properly + Tmp.v3.set(Tmp.v1).lerp(Tmp.v2, straightness); + Tmp.v3.rotate((rotation - 1) * 90); + + + //3. Rotate them for block + + + Draw.alpha(a * (1f - Mathf.curve(fin, 1f - fadeMargin))); + if(poly){ + Fill.poly( + x + Tmp.v3.x, + y + Tmp.v3.y, + sides, + particleSize * particleSizeInterp.apply(fin) * warmup(), + particleRotation + ); + }else{ + Fill.circle( + x + Tmp.v3.x, + y + Tmp.v3.y, + particleSize * particleSizeInterp.apply(fin) * warmup() + ); + } + //Here we go on this trip again + Draw.alpha(a2 * (1 - Mathf.curve(finFlow, 1 - fadeMargin))); + if(poly){ + Fill.poly( + x + Tmp.v3.x, + y + Tmp.v3.y, + sides, + particleSize * particleSizeInterp.apply(fin) * warmup(), + particleRotation + ); + }else{ + Fill.circle( + x + Tmp.v3.x, + y + Tmp.v3.y, + particleSize * particleSizeInterp.apply(fin) * warmup() + ); + } + } + + Draw.blend(); + Draw.reset(); + } + } + } +} diff --git a/src/meld/world/blocks/items/PriorityInputSplitter.java b/src/meld/world/blocks/items/PriorityInputSplitter.java new file mode 100644 index 0000000..579ddc6 --- /dev/null +++ b/src/meld/world/blocks/items/PriorityInputSplitter.java @@ -0,0 +1,28 @@ +package meld.world.blocks.items; + +import mindustry.gen.Building; +import mindustry.type.Item; +import mindustry.world.Block; +import mindustry.world.Edges; +import mindustry.world.blocks.distribution.DuctRouter; +import mindustry.world.blocks.distribution.OverflowDuct; + +//hdasdjcdf ok fine it's TIME +public class PriorityInputSplitter extends OverflowDuct { + public PriorityInputSplitter(String name) { + super(name); + itemCapacity = 4; + } + + public float threshold; + + public class PriorityInputBuild extends OverflowDuctBuild{ + @Override + public boolean acceptItem(Building source, Item item){ + return current == null && + items.total() < itemCapacity/2 ? + true : + items.total() < itemCapacity && (Edges.getFacingEdge(source.tile, tile).relativeTo(tile) == rotation); + } + } +} diff --git a/src/meld/world/blocks/production/SingleBeamDrill.java b/src/meld/world/blocks/production/SingleBeamDrill.java new file mode 100644 index 0000000..eea2d9f --- /dev/null +++ b/src/meld/world/blocks/production/SingleBeamDrill.java @@ -0,0 +1,155 @@ +package meld.world.blocks.production; + +import arc.graphics.Color; +import arc.math.Mathf; +import arc.math.geom.Geometry; +import arc.math.geom.Point2; +import arc.struct.EnumSet; +import arc.struct.IntMap; +import arc.struct.ObjectFloatMap; +import arc.struct.ObjectMap; +import arc.util.Log; +import arc.util.Time; +import arc.util.io.Reads; +import arc.util.io.Writes; +import meld.content.MeldBullets; +import mindustry.Vars; +import mindustry.content.Fx; +import mindustry.entities.Damage; +import mindustry.entities.Effect; +import mindustry.entities.bullet.BulletType; +import mindustry.game.Team; +import mindustry.gen.Building; +import mindustry.gen.Sounds; +import mindustry.type.Item; +import mindustry.world.Block; +import mindustry.world.Tile; +import mindustry.world.blocks.production.BeamDrill; +import mindustry.world.meta.BlockFlag; + +//HAS TO be an odd number in size. +public class SingleBeamDrill extends Block { + + public int range = 10, tier = 4; + + public float minHealthf = 0.75f; + //I know that sounds like a lot of items at once but well... yeah it's a lot of items at once + public int baseProductivity = 50; + + //Additional items mined for each tile unused in the range + public int distanceProductivity = 5; + public float selfDamage = 400; + public float targetDamage = 2400; + public ObjectFloatMap itemMultipliers = new ObjectFloatMap<>(); + public ObjectMap transformItems = new ObjectMap<>(); + public float drillTime = 300; + + public BulletType bigExplosion; + + public Effect shootEffect = Fx.shootQuellPulse, trailEffect = Fx.explosion, hitEffect = Fx.massiveExplosion; + + public SingleBeamDrill(String name) { + super(name); + hasItems = true; + rotate = true; + update = true; + solid = true; + drawArrow = false; + regionRotated1 = 1; + ignoreLineRotation = true; + ambientSoundVolume = 0.05F; + ambientSound = Sounds.loopMineBeam; + envEnabled |= 2; + flags = EnumSet.of(new BlockFlag[]{BlockFlag.drill}); + bigExplosion = MeldBullets.pulsarBlast; + } + + public class SingleBeamBuild extends Building{ + public float time; + + @Override + public boolean shouldConsume() { + return super.shouldConsume() && healthf() >= minHealthf; + } + + @Override + public void updateTile() { + super.updateTile(); + if(healthf() >= minHealthf) time += efficiency; + if(time >= drillTime){ + drill(); + time %= drillTime; + } + + dump(); + } + + public void drill(){ + damage(selfDamage); + + Item found = null; + int unusedTiles = range + 1; + + int offset = (size + 1)/2; + Point2 dir = Geometry.d4(rotation); + + int tx = tileX(), ty = tileY(); + Tile other = Vars.world.tile(tx + dir.x, ty + dir.y); + Damage.dynamicExplosion(other.worldx(), other.worldy(), 5, 3, 90000, Vars.tilesize * 3, true, shootEffect); + Damage.dynamicExplosion(other.worldx(), other.worldy(), 5, 5, 300, Vars.tilesize * 2, true, shootEffect); + + for(int i = 0; i < range; i++){ + unusedTiles--; + int j = i + offset; + other = Vars.world.tile(tx + dir.x * j, ty + dir.y * j); + + if(other.solid()){ + if(bigExplosion == null){ + Damage.dynamicExplosion(other.worldx(), other.worldy(), 5, 5, 30000, Vars.tilesize * 3, true, hitEffect); + Damage.dynamicExplosion(other.worldx(), other.worldy(), 5, 15, 0, Vars.tilesize * 2, true, hitEffect); + } + else bigExplosion.create(this, Team.derelict, other.worldx() - dir.x * Vars.tilesize, other.worldy() - dir.y * Vars.tilesize, 0); + if(other.build != null) other.build.damage(targetDamage); + + Item drop = other.wallDrop(); + + if(drop == null) break; + + if(drop.hardness <= tier) found = drop; + + break; + } + else { + Damage.dynamicExplosion(other.worldx(), other.worldy(), 5, 2, 0, Vars.tilesize * 3, true, trailEffect); + } + + } + + if(found == null) return; + + found = transformItems.get(found, found); + + int mined = (int)((baseProductivity + distanceProductivity * unusedTiles) * itemMultipliers.get(found, 1)); + + mined = Mathf.ceilPositive(Math.min(itemCapacity - items.get(found), mined)); + items.add(found, mined); + } + + @Override + public float progress() { + return time/drillTime; + } + + @Override + public void write(Writes write) { + super.write(write); + write.f(time); + } + + @Override + public void read(Reads read, byte revision) { + super.read(read, revision); + time = read.f(); + } + } +} diff --git a/src/meld/world/meta/ContentTags.java b/src/meld/world/meta/ContentTags.java new file mode 100644 index 0000000..2353291 --- /dev/null +++ b/src/meld/world/meta/ContentTags.java @@ -0,0 +1,9 @@ +package meld.world.meta; + +import arc.struct.ObjectMap; +import arc.struct.Seq; +import mindustry.ctype.UnlockableContent; + +public class ContentTags { + public ObjectMap>[] tagMap; +}