diff --git a/README.md b/README.md index 3e0318f..25208d5 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,5 @@ dumbass who was in school now isn't, look at how time's passed This is the java repo for Meld (I might make the original repo for Meld the java edition) Still in alpha and in active development, each gameplay test will likely not be backwards compatable for a long while -for feedback, check the hjson repo's README for the link to the discord server +for feedback, come to the discord server +https://discord.gg/eNynvuJXud diff --git a/assets/bundles/bundle.properties b/assets/bundles/bundle.properties index c720038..3adb752 100644 --- a/assets/bundles/bundle.properties +++ b/assets/bundles/bundle.properties @@ -2,7 +2,7 @@ block.meld-sunder.name = Sunder block.meld-sunder.description = Fires clumps of Debris flak at enemy targets.\n[accent]Sticks shrapnel in targets![] block.meld-shredstorm.name = Shredstorm -block.meld-shredstorm.description = Sprays debris shrapnel or silver buckshot at enemy targets..\n[accent]Spread is focused towards the aim direction. +block.meld-shredstorm.description = Sprays debris shrapnel or silver buckshot at enemy targets.\n[accent]Spread is focused towards the aim direction. block.meld-flurry.name = Flurry block.meld-flurry.description = Charges and flings canisters of sticky Carbolith dust which spark on a delay.\n[accent]High damage vs force projectors[]\n\n[red]Warning: Putting hard matterials with sludge in will clog the machinery![]\n\n[accent]Armored![] @@ -30,13 +30,15 @@ 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, 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-gas-kiln.description = Heats materials using [#cbdbfc]Aspect[], often used for [red]primitive[] refinement processes like smelting or ceramic blasting.\n\n[accent]Carbolith + Tenbris -> Shadesteel + [#5b4739]Fumes[]\nSilver -> Annealed Silver\n\nClay-Mallows + Quartz Strata + Likestone Sediments -> Glassy-Mallows\n\nClay-Mallows + Likestone Sediments + Likestone Sediments + Debris -> Crucible-Plating\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-rotary-kiln.description = Burns mass amounts of [#cbdbfc]Aspect[] as fuel, heats materials to process them in bulk.\n\n[accent]Carbolith + Tenbris -> Shadesteel + [#5b4739]Fumes[]\nSilver -> Annealed Silver\n\nClay-Mallows + Quartz Strata + Likestone Sediments -> Glassy-Mallows\n\nClay-Mallows + Likestone Sediments + Likestone Sediments + Debris -> Crucible-Plating\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-pneumatic-extruder.description = Extrudes material into pipes, uses [#cbdbfc]Aspect[] to run. [accent]\n\nDebris + Elnar -> Aspect Pipe\n\nSilver/Annealed Silver + Debris -> Aspect Pipe block.meld-heating-basin.name = Heating Basin @@ -101,7 +103,7 @@ 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 works at half speed on 1x1s. +block.meld-bruisekit.description = Regenerates target block's health.\n\nPrioritises large, functional blocks and works at half speed on 1x1s.\n\nHeals up to 4x more health based on how low target health% is, down to 50%. 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. diff --git a/assets/sprites/blocks/production/earthbound-infuser-bottom.png b/assets/sprites/blocks/crafting/earthbound-infuser-bottom.png similarity index 100% rename from assets/sprites/blocks/production/earthbound-infuser-bottom.png rename to assets/sprites/blocks/crafting/earthbound-infuser-bottom.png diff --git a/assets/sprites/blocks/production/earthbound-infuser-full.png b/assets/sprites/blocks/crafting/earthbound-infuser-full.png similarity index 100% rename from assets/sprites/blocks/production/earthbound-infuser-full.png rename to assets/sprites/blocks/crafting/earthbound-infuser-full.png diff --git a/assets/sprites/blocks/production/earthbound-infuser-mixer.png b/assets/sprites/blocks/crafting/earthbound-infuser-mixer.png similarity index 100% rename from assets/sprites/blocks/production/earthbound-infuser-mixer.png rename to assets/sprites/blocks/crafting/earthbound-infuser-mixer.png diff --git a/assets/sprites/blocks/production/earthbound-infuser.png b/assets/sprites/blocks/crafting/earthbound-infuser.png similarity index 100% rename from assets/sprites/blocks/production/earthbound-infuser.png rename to assets/sprites/blocks/crafting/earthbound-infuser.png diff --git a/assets/sprites/blocks/crafting/gas-kiln.png b/assets/sprites/blocks/crafting/gas-kiln.png new file mode 100644 index 0000000..938942a Binary files /dev/null and b/assets/sprites/blocks/crafting/gas-kiln.png differ diff --git a/assets/sprites/blocks/crafting/pneumatic-extruder.png b/assets/sprites/blocks/crafting/pneumatic-extruder.png new file mode 100644 index 0000000..b8ad1ff Binary files /dev/null and b/assets/sprites/blocks/crafting/pneumatic-extruder.png differ diff --git a/assets/sprites/blocks/effect/bruisekit-base.png b/assets/sprites/blocks/effect/bruisekit-base.png new file mode 100644 index 0000000..776aa86 Binary files /dev/null and b/assets/sprites/blocks/effect/bruisekit-base.png differ diff --git a/assets/sprites/blocks/effect/bruisekit-turret.png b/assets/sprites/blocks/effect/bruisekit-turret.png new file mode 100644 index 0000000..c48828a Binary files /dev/null and b/assets/sprites/blocks/effect/bruisekit-turret.png differ diff --git a/assets/sprites/blocks/effect/gauze.png b/assets/sprites/blocks/effect/gauze.png new file mode 100644 index 0000000..8fafab2 Binary files /dev/null and b/assets/sprites/blocks/effect/gauze.png differ diff --git a/assets/sprites/items/heavy ind/likestone-sediments.png b/assets/sprites/items/heavy ind/likestone-sediments.png new file mode 100644 index 0000000..28bb2d7 Binary files /dev/null and b/assets/sprites/items/heavy ind/likestone-sediments.png differ diff --git a/assets/sprites/units/bulbhead-cell.png b/assets/sprites/units/bulbhead-cell.png index 2cdfd3a..89e2f8d 100644 Binary files a/assets/sprites/units/bulbhead-cell.png and b/assets/sprites/units/bulbhead-cell.png differ diff --git a/assets/sprites/units/bulbhead.png b/assets/sprites/units/bulbhead.png index 08b4975..68b39ec 100644 Binary files a/assets/sprites/units/bulbhead.png and b/assets/sprites/units/bulbhead.png differ diff --git a/mod.hjson b/mod.hjson index 51ec40f..3e069cd 100644 --- a/mod.hjson +++ b/mod.hjson @@ -17,7 +17,7 @@ description: "Meld Java.\n\n[[]accent]Only has custom game content! (play the in version: gameplay test v3 #the minimum game build required to run this mod -minGameVersion: 154 +minGameVersion: 157 #this is a java mod java: true diff --git a/src/meld/Meld.java b/src/meld/Meld.java index 3b39f84..7affe5f 100644 --- a/src/meld/Meld.java +++ b/src/meld/Meld.java @@ -7,6 +7,7 @@ import arc.math.geom.Point2; import arc.struct.IntSeq; import arc.struct.Seq; +import arc.util.Log; import arc.util.Time; import arc.util.Tmp; import meld.content.*; diff --git a/src/meld/content/MeldBlocks.java b/src/meld/content/MeldBlocks.java index cb4f1b0..5921046 100644 --- a/src/meld/content/MeldBlocks.java +++ b/src/meld/content/MeldBlocks.java @@ -6,14 +6,12 @@ import arc.math.Interp; import arc.math.Mathf; import arc.math.geom.Vec2; -import arc.util.Log; import arc.util.Tmp; import meld.*; import meld.entities.bullet.OutflowBulletType; import meld.entities.bullet.TransitionBulletType; import meld.fluid.AspectGroup; import meld.graphics.*; -import meld.world.blocks.consumers.ConsumeAspects; import meld.world.blocks.*; import meld.world.blocks.consumers.StupidConsumeAspects; import meld.world.blocks.crafting.ModularCrafter; @@ -22,19 +20,17 @@ 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.producer.ProduceItem; +import meld.world.blocks.producer.ProduceLiquid; import meld.world.blocks.production.SingleBeamDrill; import meld.world.meta.*; import mindustry.Vars; -import mindustry.content.Blocks; import mindustry.content.Fx; import mindustry.content.StatusEffects; import mindustry.entities.bullet.*; -import mindustry.entities.effect.MultiEffect; import mindustry.entities.effect.ParticleEffect; import mindustry.entities.part.DrawPart; import mindustry.entities.part.HaloPart; @@ -56,13 +52,13 @@ 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.ConsumeItems; import mindustry.world.consumers.ConsumeLiquid; import mindustry.world.draw.*; import mindustry.world.meta.Attribute; @@ -92,7 +88,7 @@ public class MeldBlocks { public static Block aetherAccumulator, elementalBlaster, pneumaticPulsear, earthboundInfuser, fumehood, sharkFactory; - public static ModularCrafter gasKiln, rotaryKiln, pneumaticExtruder; + public static Block gasKiln, metalworks, rotaryKiln, pneumaticExtruder; public static Block channelNode, channelHub, channelFace, aspectOutlet, aspectChannel, channelDirector, channelVent, manualValve, intakeValve, valveController, pipebox; @@ -121,7 +117,6 @@ public static Item item(String name){ } public static void load(){ - int channelHealth = 100; channelFace = new FlexibleSizeJunction("channel-face"){{ @@ -179,42 +174,44 @@ public static void load(){ new DrawSideRegion() ); - //consumeLiquid(MeldLiquids.aether, outletRate/10); - - - liquidCapacity = 100; + //Bit sloppy but it'll work + Vars.content.liquids().each(l -> { + if(AspectGroup.aether.stats.containsKey(l)) inputLiquids.add(l); + }); + Vars.content.liquids().each(l -> { + if(AspectGroup.aspect.stats.containsKey(l)) outputLiquids.add(l); + }); + inputLiquidSlots = 1; outputLiquidSlots = 1; + recipes.addAll( new TimedRecipe(){{ - craftTime = 10; float multi = AspectGroup.aether.getEfficiency(MeldLiquids.aether); float density = AspectGroup.aether.getDensity(MeldLiquids.aether); - inputLiquids = LiquidStack.with(MeldLiquids.aether, outletRate/density); - outputLiquids = LiquidStack.with(MeldLiquids.aspect, outletRate * multi * 10 * density); + consumers.add(new ConsumeLiquid(MeldLiquids.aether, outletRate/density/10)); + producers.add(new ProduceLiquid(MeldLiquids.aspect, outletRate * multi * density)); }}, new TimedRecipe(){{ - craftTime = 10; float multi = AspectGroup.aether.getEfficiency(MeldLiquids.pollutantMixture); float density = AspectGroup.aether.getDensity(MeldLiquids.pollutantMixture); - inputLiquids = LiquidStack.with(MeldLiquids.pollutantMixture, outletRate); - outputLiquids = LiquidStack.with(MeldLiquids.boundAspect, outletRate * multi * 10 * density); + consumers.add(new ConsumeLiquid(MeldLiquids.pollutantMixture, outletRate/density/10)); + producers.add(new ProduceLiquid(MeldLiquids.boundAspect, outletRate * multi * density)); }}, new TimedRecipe(){{ - craftTime = 10; float multi = AspectGroup.aether.getEfficiency(MeldLiquids.thunderingAether); float density = AspectGroup.aether.getDensity(MeldLiquids.thunderingAether); - inputLiquids = LiquidStack.with(MeldLiquids.thunderingAether, outletRate/density); - outputLiquids = LiquidStack.with(MeldLiquids.stormingAspect, outletRate * multi * 10 * density); + consumers.add(new ConsumeLiquid(MeldLiquids.thunderingAether, outletRate/density/10)); + producers.add(new ProduceLiquid(MeldLiquids.stormingAspect, outletRate * multi * density)); }} ); }}; aspectChannel = new VisualAspectPipe("aspect-channel"){{ requirements(Category.liquid, with( - MeldItems.annealedSilver, 5, MeldItems.aspectPipe, 2 + MeldItems.aspectPipe, 4 )); underBullets = false; leaks = false; @@ -330,6 +327,8 @@ public static void load(){ range = 200; fogRadiusMultiplier = 0.25f; + buildTime = 45; + reload = 30; shootEffect = Fx.shootBig; shootWarmupSpeed = 0.09f; @@ -391,6 +390,8 @@ public static void load(){ health = 450; range = 200; + buildTime = 30; + fogRadiusMultiplier = 0.25f; reload = 120; shootEffect = Fx.shootBig; @@ -1124,6 +1125,9 @@ public void update(Bullet b){ drillMultipliers.put( MeldItems.electrumSheets, 2 ); + drillMultipliers.put( + MeldItems.likestoneSediments, 0.5f + ); consume(new StupidConsumeAspects( outletRate, AspectGroup.aspect @@ -1150,6 +1154,7 @@ public void update(Bullet b){ baseProductivity = 50; drillTime = 360; range = 8; + selfDamage = 250; transformItems.putAll( MeldItems.clayMallows, MeldItems.glassMallows, @@ -1159,7 +1164,7 @@ public void update(Bullet b){ liquidCapacity = 50; - consume(new ConsumeAspects(outletRate/2, MeldLiquids.outletEfficiencies, MeldLiquids.outletDensities)); + consume(new StupidConsumeAspects(outletRate/2, AspectGroup.outlet)); }}; earthboundInfuser = new ModularCrafter("earthbound-infuser"){{ @@ -1212,7 +1217,7 @@ public void update(Bullet b){ */ }}; - gasKiln = new ModularCrafter("gas-kiln"){{ + gasKiln = new RecipeCrafter("gas-kiln"){{ requirements(Category.crafting, with(MeldItems.debris, 80)); size = 3; @@ -1222,82 +1227,22 @@ public void update(Bullet b){ 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)); + inputLiquids.addAll(MeldLiquids.aspect, MeldLiquids.boundAspect, MeldLiquids.stormingAspect); + inputItems.addAll(MeldItems.tenbris, MeldItems.clayMallows, MeldItems.carbolith, MeldItems.debris, MeldItems.shadesteel, MeldItems.glassMallows, MeldItems.silver, MeldItems.likestoneSediments, MeldItems.quartzStrata); + outputItems.addAll(MeldItems.cruciblePlating, MeldItems.shadesteel, MeldItems.glassMallows, MeldItems.annealedSilver); + outputLiquids.addAll(MeldLiquids.fumes); - 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, AspectGroup.aspect, 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; - }} - ); + inputLiquidSlots = 1; + outputLiquidSlots = 1; + recipes = MeldRecipes.kilnRecipies(2, 1); + }}; + /* + metalworks = new RecipeCrafter("metalworks"){{ + requirements(Category.crafting, with(MeldItems.debris, 350, MeldItems.cruciblePlating, 150)); }}; - rotaryKiln = new ModularCrafter("rotary-kiln"){{ + */ + rotaryKiln = new RecipeCrafter("rotary-kiln"){{ requirements(Category.crafting, with(MeldItems.debris, 350, MeldItems.cruciblePlating, 150)); size = 5; @@ -1306,101 +1251,18 @@ public void update(Bullet b){ liquidCapacity = outletRate * 60 * 2; itemCapacity = 48; + inputLiquidSlots = 1; + outputLiquidSlots = 1; - 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; + inputLiquids.addAll(MeldLiquids.aspect, MeldLiquids.boundAspect, MeldLiquids.stormingAspect); + inputItems.addAll(MeldItems.tenbris, MeldItems.clayMallows, MeldItems.carbolith, MeldItems.debris, MeldItems.shadesteel, MeldItems.glassMallows, MeldItems.silver, MeldItems.likestoneSediments, MeldItems.quartzStrata); + outputItems.addAll(MeldItems.cruciblePlating, MeldItems.shadesteel, MeldItems.glassMallows, MeldItems.annealedSilver); + outputLiquids.addAll(MeldLiquids.fumes); - modules.addAll( - //Set the base rate based on aspect intake - new ConsumeAspectModule(outletRate * 8, AspectGroup.aspect, 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; - }} - ); + recipes = MeldRecipes.kilnRecipies(12, 8); }}; - pneumaticExtruder = new ModularCrafter("pneumatic-extruder"){{ + pneumaticExtruder = new RecipeCrafter("pneumatic-extruder"){{ requirements(Category.crafting, with(MeldItems.debris, 120)); size = 3; @@ -1410,56 +1272,39 @@ public void update(Bullet b){ itemCapacity = 10; - acceptedLiquids.addAll(MeldLiquids.aspect, MeldLiquids.boundAspect); - acceptedItems.addAll(MeldItems.shadesteel, MeldItems.elnarDust, MeldItems.debris, MeldItems.silver, MeldItems.annealedSilver); - dumpedItems.addAll(MeldItems.aspectPipe); - - ItemRecipe - aspectPipe1 = new ItemRecipe(with(MeldItems.shadesteel, 2, MeldItems.elnarDust, 4), with(MeldItems.aspectPipe, 2)), - aspectPipe2 = new ItemRecipe(with(MeldItems.debris, 1, MeldItems.annealedSilver, 2), with(MeldItems.aspectPipe, 2)), - aspectPipe3 = new ItemRecipe(with(MeldItems.debris, 1, MeldItems.silver, 2), with(MeldItems.aspectPipe, 2));; + inputLiquids.addAll(MeldLiquids.aspect, MeldLiquids.boundAspect, MeldLiquids.stormingAspect); + inputItems.addAll(MeldItems.shadesteel, MeldItems.elnarDust, MeldItems.debris, MeldItems.silver, MeldItems.annealedSilver); + outputItems.addAll(MeldItems.aspectPipe); - float produceTime = 30; + inputLiquidSlots = 1; - modules.addAll( - new GateModule( - ModOUT.ZERO, new GateModule.RecipeCondition(aspectPipe1) - ), - new GateModule( - ModOUT.ONE, new GateModule.RecipeCondition(aspectPipe2) - ), - new GateModule( - ModOUT.TWO, new GateModule.RecipeCondition(aspectPipe3) - ), - new LambdaModule(){{ - //Set every ping after the first one found as 1 to zero - updater = b -> { - int a = 0; - for(int i = 0; i < 3; i++){ - b.setPin(i, Math.max(b.getPin(i) - a, 0)); - a = (int)Math.max(a, b.getPin(i)); - } - b.setPin(ModOUT.THREE, a); - }; - }}, - new ConsumeLiquidModule(LiquidStack.with(MeldLiquids.aspect, outletRate * 2), ModIN.THREE, ModOUT.FOUR), - new RecipeCraftingModule(){{ - recipe = aspectPipe1; - efficiencyPins = new int[]{ModIN.FOUR, ModIN.ZERO}; - progressPin = ModOUT.FOUR; - craftTime = produceTime; + recipes.addAll( + new TimedRecipe(){{ + consumers.addAll( + new ConsumeItems(with(MeldItems.annealedSilver, 2, MeldItems.debris, 2)), + new StupidConsumeAspects(outletRate * 2, AspectGroup.aspect) + ); + producers.addAll( + new ProduceItem(new ItemStack(MeldItems.aspectPipe, 2)) + ); }}, - new RecipeCraftingModule(){{ - recipe = aspectPipe2; - efficiencyPins = new int[]{ModIN.FOUR, ModIN.ONE}; - progressPin = ModOUT.FIVE; - craftTime = produceTime; + new TimedRecipe(){{ + consumers.addAll( + new ConsumeItems(with(MeldItems.silver, 2, MeldItems.debris, 2)), + new StupidConsumeAspects(outletRate * 2, AspectGroup.aspect) + ); + producers.addAll( + new ProduceItem(new ItemStack(MeldItems.aspectPipe, 2)) + ); }}, - new RecipeCraftingModule(){{ - recipe = aspectPipe3; - efficiencyPins = new int[]{ModIN.FOUR, ModIN.TWO}; - progressPin = ModOUT.SIX; - craftTime = produceTime; + new TimedRecipe(){{ + consumers.addAll( + new ConsumeItems(with(MeldItems.elnarDust, 2, MeldItems.debris, 2)), + new StupidConsumeAspects(outletRate * 2, AspectGroup.aspect) + ); + producers.addAll( + new ProduceItem(new ItemStack(MeldItems.aspectPipe, 2)) + ); }} ); }}; diff --git a/src/meld/content/MeldBullets.java b/src/meld/content/MeldBullets.java index 72a5aa0..09f2887 100644 --- a/src/meld/content/MeldBullets.java +++ b/src/meld/content/MeldBullets.java @@ -143,6 +143,8 @@ public static void load(){ collidesGround = true; scaleLife = true; + ammoMultiplier = 1; + reloadMultiplier = 2; rangeChange = -80; @@ -270,11 +272,11 @@ public static void load(){ shredSilver = new TransitionBulletType(){{ fragLifeMin = 0.8f; - ammoMultiplier = 2; reloadMultiplier = 2f; fragRandomSpread = 5; fragBullets = 1; + ammoMultiplier = 1; fragBullet = new RicochetBulletType(8, 10, "shell"){{ frontColor = Color.white; diff --git a/src/meld/content/MeldEnvironment.java b/src/meld/content/MeldEnvironment.java index 7bdfd66..57612d4 100644 --- a/src/meld/content/MeldEnvironment.java +++ b/src/meld/content/MeldEnvironment.java @@ -283,7 +283,7 @@ public static void load(){ meldCrystalFloor = new Floor("meld-crystal-floor", 3){{ }}; - meldCrystalFloor = new Floor("meld-hard-crystal-floor", 3){{ + meldCrystalHardFloor = new Floor("meld-hard-crystal-floor", 3){{ }}; carbonicVent = new SteamVent("carbonic-vent"){{ @@ -321,6 +321,10 @@ public static void load(){ likesand = new Floor("likesand", 3); likestone = new Floor("likestone", 3); likesalt = new Floor("likesalt", 3); + + likesand.itemDrop = likestone.itemDrop = MeldItems.likestoneSediments; + likesand.playerUnmineable = likestone.playerUnmineable = true; + redSilt = new Floor("red-silt", 3); aspectSoil = new Floor("aspect-soil", 3); softSand = new Floor("soft-sand", 3); @@ -402,10 +406,12 @@ public static void load(){ likesandWall = new StaticTree("likesand-wall"){{ variants = 2; + itemDrop = MeldItems.likestoneSediments; }}; likestoneWall = new StaticTree("likestone-wall"){{ variants = 2; + itemDrop = MeldItems.likestoneSediments; }}; likesaltWall= new StaticTree("likesalt-wall"){{ @@ -472,6 +478,7 @@ public static void load(){ buildVisibility = BuildVisibility.sandboxOnly; + buildTime = 120; }}; meldCrystal = new WobbleProp("meld-crystal"){{ diff --git a/src/meld/content/MeldFx.java b/src/meld/content/MeldFx.java index 9dcbef9..6218160 100644 --- a/src/meld/content/MeldFx.java +++ b/src/meld/content/MeldFx.java @@ -1,6 +1,8 @@ package meld.content; import arc.Core; +import arc.func.Floatp; +import arc.graphics.Blending; import arc.graphics.Color; import arc.graphics.g2d.Draw; import arc.graphics.g2d.Fill; @@ -9,16 +11,127 @@ import arc.math.Interp; import arc.math.Mathf; import arc.math.geom.Position; +import arc.math.geom.Vec2; import arc.util.Tmp; import meld.graphics.Draww; import meld.Meld; import mindustry.Vars; import mindustry.entities.Effect; import mindustry.gen.Healthc; +import mindustry.graphics.Drawf; import mindustry.graphics.Layer; +import static mindustry.content.Fx.rand; + public class MeldFx { + private static float percent = 0; + + public static Effect + + chainLightning = new Effect(15, 500 * 500/2 * Vars.tilesize, e -> { + if(!(e.data instanceof VisualLightningHolder)) return; + VisualLightningHolder p = (VisualLightningHolder) e.data; + + Draw.blend(Blending.additive); + + int seed = e.id; + //get the start and ends of the lightning, then the distance between them + float tx = Tmp.v1.set(p.start()).x, ty = Tmp.v1.y, dst = Tmp.v1.dst(Tmp.v2.set(p.end())); + + //Get the direction towards the endpoint from the start + Tmp.v3.set(p.end()).sub(p.start()).nor(); + float normx = Tmp.v3.x, normy = Tmp.v3.y; + + rand.setSeed(seed); + + //Set arc width before rand gets based on time + float arcWidth = rand.range(dst * p.arc()); + + seed = e.id - (int) (e.time * 2); + + float angle = Tmp.v1.angleTo(Tmp.v2); + + //How offset each point is from the line based on an arc + Floatp arcX = () -> Mathf.sinDeg(percent * 180) * arcWidth; + + //range of lightning strike's vary depending on turret + float range = p.segLength(); + int links = Mathf.ceil(dst / p.segLength()); + float spacing = dst / links; + + Lines.stroke(p.width() * e.fout()); + Draw.color(Color.white, e.color, e.finpow()); + Fill.circle(Tmp.v2.x, Tmp.v2.y, p.width() * e.fout()/2); + + //begin the line + //Lines.beginLine(); + + //Lines.linePoint(Tmp.v1.x, Tmp.v1.y); + + //Join the links together + + int coils = p.coils(); + for(int u = 0; u < coils; u++){ + int coil = u + 1; + float coilSpacing = spacing/coil; + + //Make the lower numbered, less eratic coils travel quicker + float travelPercent = Mathf.clamp(e.finpow() * (coils - coil + 1)); + + + int coilLinks = links * coil; + + float lastx = Tmp.v1.x, lasty = Tmp.v1.y; + for(int i = 0; i < Mathf.ceil(coilLinks * travelPercent); i++){ + float nx, ny; + //Only put an endpoint at the very end of the lightning, ending early shoudn't end it at the end point + if(i == links * coil - 1){ + //line at end + nx = Tmp.v2.x; + ny = Tmp.v2.y; + }else{ + float len = (i) * coilSpacing + rand.range(coilSpacing/2) + coilSpacing; + rand.setSeed(seed + i); + + //Gets more random with each coil + Tmp.v3.trns(rand.random(360), range/2/(coils - coil + 1)); + percent = ((float) (i + 1))/coilLinks; + + nx = tx + normx * len + Tmp.v3.x + Tmp.v4.set(0, arcX.get()).rotate(angle).x; + ny = ty + normy * len + Tmp.v3.y + Tmp.v4.y; + } + + Drawf.light(lastx, lasty, nx, ny, Lines.getStroke(), Draw.getColor(), Draw.getColor().a); + + //Using a quad instead of just a line so that the edges can join together + Lines.line(lastx, lasty, nx, ny); + + lastx = nx; + lasty = ny; + //Lines.linePoint(nx, ny); + } + } + + + //ines.endLine(); + Draw.blend(); + }); + + public interface VisualLightningHolder{ + Vec2 start(); + + Vec2 end(); + + float width(); + + float segLength(); + + float arc(); + + int coils(); + } + public static float root2 = Mathf.sqrt(2); public static Effect diff --git a/src/meld/content/MeldItems.java b/src/meld/content/MeldItems.java index 0f295de..52bf984 100644 --- a/src/meld/content/MeldItems.java +++ b/src/meld/content/MeldItems.java @@ -28,10 +28,10 @@ public class MeldItems { public static void load(){ debris = new Item("debris"){{ - cost = 0.5f; + cost = 1; }}; carbolith = new Item("carbolith"){{ - cost = 0.8f; + cost = 1.2f; }}; silver = new Item("silver"){{ cost = 0.3f; diff --git a/src/meld/content/MeldLiquids.java b/src/meld/content/MeldLiquids.java index 03a3667..a0d0e04 100644 --- a/src/meld/content/MeldLiquids.java +++ b/src/meld/content/MeldLiquids.java @@ -105,6 +105,12 @@ public static void load(){ } public static void mapOutlet(Liquid input, Liquid output){ + + put(input, AspectGroup.outlet, new AspectStats( + AspectGroup.aether.getEfficiency(input) * AspectGroup.aspect.getEfficiency(output), + AspectGroup.aether.getDensity(input) * AspectGroup.aspect.getDensity(output) + )); + outletMapping.putAll(input, output); outletEfficiencies.put(input, AspectGroup.aether.getEfficiency(input) * AspectGroup.aspect.getEfficiency(output)); diff --git a/src/meld/content/MeldRecipes.java b/src/meld/content/MeldRecipes.java new file mode 100644 index 0000000..d48017c --- /dev/null +++ b/src/meld/content/MeldRecipes.java @@ -0,0 +1,58 @@ +package meld.content; + +import arc.struct.Seq; +import meld.fluid.AspectGroup; +import meld.world.blocks.consumers.StupidConsumeAspects; +import meld.world.blocks.crafting.recipe.TimedRecipe; +import meld.world.blocks.producer.ProduceItem; +import meld.world.blocks.producer.ProduceLiquid; +import mindustry.type.ItemStack; +import mindustry.type.LiquidStack; +import mindustry.world.consumers.ConsumeItems; + +import static meld.content.MeldBlocks.outletRate; +import static mindustry.type.ItemStack.with; + +public class MeldRecipes { + public static Seq kilnRecipies(float outlets, float speedMultiplier){ + return Seq.with( + new TimedRecipe(120/speedMultiplier){{ + consumers.addAll( + new ConsumeItems(with(MeldItems.tenbris, 2, MeldItems.carbolith, 2)), + new StupidConsumeAspects(outletRate * outlets, AspectGroup.aspect) + ); + producers.addAll( + new ProduceItem(new ItemStack(MeldItems.shadesteel, 2)), + new ProduceLiquid(new LiquidStack(MeldLiquids.fumes, 1 * speedMultiplier)) + ); + }}, + new TimedRecipe(30/speedMultiplier){{ + consumers.addAll( + new ConsumeItems(with(MeldItems.silver, 2)), + new StupidConsumeAspects(outletRate * outlets, AspectGroup.aspect) + ); + producers.addAll( + new ProduceItem(new ItemStack(MeldItems.annealedSilver, 3)) + ); + }}, + new TimedRecipe(240/speedMultiplier){{ + consumers.addAll( + new ConsumeItems(with(MeldItems.clayMallows, 2, MeldItems.likestoneSediments, 2, MeldItems.quartzStrata, 4)), + new StupidConsumeAspects(outletRate * outlets, AspectGroup.aspect) + ); + producers.addAll( + new ProduceItem(new ItemStack(MeldItems.glassMallows, 4)) + ); + }}, + new TimedRecipe(240/speedMultiplier){{ + consumers.addAll( + new ConsumeItems(with(MeldItems.clayMallows, 4, MeldItems.likestoneSediments, 2, MeldItems.debris, 2)), + new StupidConsumeAspects(outletRate * outlets, AspectGroup.aspect) + ); + producers.addAll( + new ProduceItem(new ItemStack(MeldItems.cruciblePlating, 4)) + ); + }} + ); + } +} diff --git a/src/meld/content/MeldUnits.java b/src/meld/content/MeldUnits.java index 5f915e5..6b3bf94 100644 --- a/src/meld/content/MeldUnits.java +++ b/src/meld/content/MeldUnits.java @@ -262,15 +262,16 @@ public static void load(){ bulbhead = new UnitType("bulbhead"){{ float IR = 120; + outlineColor = Color.clear; health = 290; - speed = 2.55f; - drag = 0.15f; - accel = 0.8f; + speed = 4.55f; + drag = 0.1f; + accel = 0.09f; - rotateSpeed = 9; - trailLength = 18; + rotateSpeed = 7; + trailLength = 80; trailScl = 1.2f; hitSize = 10; @@ -291,8 +292,7 @@ public static void load(){ mineRange = IR; fogRadius = IR/ Vars.tilesize; - canBoost = true; - boostMultiplier = 0.1f; + canBoost = false; shadowElevation = 0; shadowElevationScl = 0f; @@ -445,7 +445,8 @@ public static void load(){ new StatusFieldAbility(MeldStatusEffects.rally, 120, 5, IR){{ activeEffect = Fx.none; }}, - new SlipstreamHullAbility() + new SlipstreamHullAbility(), + new BeachedAbility() ); //can't rally yourself goober >w< immunities.addAll( diff --git a/src/meld/core/Melting.java b/src/meld/core/Melting.java index 625d9ab..7093239 100644 --- a/src/meld/core/Melting.java +++ b/src/meld/core/Melting.java @@ -28,6 +28,7 @@ public Melting(){ } public void start(Tile start){ + Log.info("Starting!"); start.getLinkedTiles(toSpread::add); if(!running){ @@ -38,6 +39,7 @@ public void start(Tile start){ @Override public void run(){ + Log.info("ticking"); toMelt // TODO: this check might not be necessary .select(it -> it.floor() != melted) diff --git a/src/meld/entities/unit/BulbheadEntity.java b/src/meld/entities/unit/BulbheadEntity.java index fb29658..b10313b 100644 --- a/src/meld/entities/unit/BulbheadEntity.java +++ b/src/meld/entities/unit/BulbheadEntity.java @@ -12,6 +12,7 @@ import arc.math.geom.Geometry; import arc.math.geom.Point2; import arc.math.geom.Position; +import arc.math.geom.Vec2; import arc.util.*; import meld.content.MeldUnits; import meld.graphics.Draww; @@ -44,12 +45,68 @@ public class BulbheadEntity extends UnitWaterMove { //Actually counts upwards... kinda counter intuitively named public float corelinkGrace = 0; - + //Goes up to 1 and once it's at one, well... stuck... + public float beached = 0; + + public float standstillDrag = 1; + public boolean controllerMoved = false; + + public Vec2 lastSafe = new Vec2(); + + //It's a d8 but I shoved several hamburgors in it + public final static Point2[] d8Expanded = { + new Point2(1, 0), + new Point2(1, 1), + new Point2(0, 1), + new Point2(-1, 1), + new Point2(-1, 0), + new Point2(-1, -1), + new Point2(0, -1), + new Point2(1, -1), + + new Point2(2, 0), + new Point2(2, 1), + new Point2(2, -1), + new Point2(2, 2), + new Point2(2, -2), + + new Point2(-2, 0), + new Point2(-2, 1), + new Point2(-2, -1), + new Point2(-2, 2), + new Point2(-2, -2), + + new Point2(0, 2), + new Point2(1, 2), + new Point2(-1, 2), + + new Point2(0, -2), + new Point2(1, -2), + new Point2(-1, -2), + }; @Override public EntityCollisions.SolidPred solidity() { return (x, y) -> { Tile tile = Vars.world.tile(x, y); - return tile == null || tile.solid(); + + //If the tile is out of bounds or solid, then yeah it's solid + if(tile == null || tile.solid()) return true; + return false; + + /* + //If the current floor is a liquid then we're good + if(tile.floor().isLiquid) return false; + + for(int i = 0; i < 24; i++){ + Point2 offset = d8Expanded[i]; + Tile other = tile.nearby(offset); + if(other != null && !other.solid() && other.floor().isLiquid) return false; + } + + //If we can't find a nearby liquid tile, return true + return true; + + */ }; } @@ -70,6 +127,23 @@ public void update() { Tile tile = this.tileOn(); + + if(tile != null && !tile.floor().isLiquid){ + if(Mathf.chance(vel.len()/speed())) Fx.unitLandSmall.at(x, y, type.hitSize/Vars.tilesize, tile.floor().mapColor); + + beached = Mathf.approachDelta(beached, 1, 1/60f); + + if(beached == 1){ + float exitAngle = angleTo(lastSafe); + set(lastSafe); + rotation(exitAngle); + } + } + else { + beached = 0; + lastSafe.set(this); + } + if (tile != null && !this.canPassOn()) { for(int i = 0; i < 4; i++){ Tile other = tile.nearby(i); @@ -81,8 +155,26 @@ public void update() { } } } + super.update(); + speedMultiplier *= Mathf.lerp(1, 0f, beached * beached); + if(beached > 0){ + drag *= Mathf.clamp(Mathf.lerp(1, 10, beached * 5), 1, 10); + drag *= Mathf.lerp(1, 5, beached * beached); + } + + if(!controllerMoved) standstillDrag = Mathf.approachDelta(standstillDrag, 10, 1); + else standstillDrag = 1; + + drag *= standstillDrag; + controllerMoved = false; + } + + @Override + public void rotateMove(Vec2 vec) { + super.rotateMove(vec); + controllerMoved = true; } public void getNearbyLink(){ @@ -254,8 +346,6 @@ public void updateBuildLogic() { public void draw(){ super.draw(); - float actualElevation = elevation; - elevation /= 2; //Draww.drawChain(chain, x, y, Core.input.mouseWorldX(), Core.input.mouseWorldY(), 0); @@ -279,7 +369,28 @@ public void draw(){ Draw.blend(Blending.normal); } - elevation = actualElevation; + if(beached > 0 && beached != 1){ + float fout = 1 - beached; + + Draw.alpha(beached * beached); + Draw.mixcol(Pal.accent, 1 - beached); + + //Get the bloom, kinda crappy but this is a way of doing it + Draw.z(Layer.effect); + Draw.rect(type.fullIcon, lastSafe.x, lastSafe.y, angleTo(lastSafe) - 90); + + Draw.z(Layer.weather + 1); + Draw.rect(type.fullIcon, lastSafe.x, lastSafe.y, angleTo(lastSafe) - 90); + + Draw.reset(); + + if(Vars.player.unit() == this){ + Lines.stroke(fout * 8); + Draw.color(Pal.accent); + Draw.alpha(beached); + Lines.circle(lastSafe.x, lastSafe.y, Vars.tilesize * 8 * (1 - beached * beached)); + } + } } //Attempt to draw the build beam from the unit itself. If that fails, draw it to the core instead, then draw the build beam from the core diff --git a/src/meld/entities/unit/abilities/BeachedAbility.java b/src/meld/entities/unit/abilities/BeachedAbility.java new file mode 100644 index 0000000..d62c9af --- /dev/null +++ b/src/meld/entities/unit/abilities/BeachedAbility.java @@ -0,0 +1,14 @@ +package meld.entities.unit.abilities; + +import mindustry.entities.abilities.Ability; +import mindustry.gen.Unit; + +public class BeachedAbility extends Ability { + @Override + public void update(Unit unit) { + super.update(unit); + if(unit.tileOn() != null && !unit.tileOn().floor().isLiquid){ + unit.reloadMultiplier = unit.buildSpeedMultiplier = 0; + } + } +} diff --git a/src/meld/fluid/AspectGroup.java b/src/meld/fluid/AspectGroup.java index d76282b..bc33b80 100644 --- a/src/meld/fluid/AspectGroup.java +++ b/src/meld/fluid/AspectGroup.java @@ -12,6 +12,8 @@ public class AspectGroup { public static Seq groups = new Seq<>(); public String name, localizedName; + public boolean hidden = false; + public AspectGroup(String name){ //hgjkgvjgfh this.name = Vars.content.transformName(name); @@ -33,6 +35,11 @@ public static void put(Liquid liquid, AspectGroup group, AspectStats stats){ group.stats.put(liquid, stats); } + public AspectGroup hide(){ + hidden = true; + return this; + } + public static AspectGroup aether = new AspectGroup("aether"), aspect = new AspectGroup("aspect"), diff --git a/src/meld/meta/MeldStats.java b/src/meld/meta/MeldStats.java index 7a4afbd..19b754c 100644 --- a/src/meld/meta/MeldStats.java +++ b/src/meld/meta/MeldStats.java @@ -24,6 +24,8 @@ public static void aspectStats(Liquid aspect, Stats stats){ table.row(); AspectGroup.groups.each(g -> { + if(g.hidden) return; + AspectGroup.AspectStats aspectStat = g.stats.get(aspect); if(aspectStat == null) return; table.table(Styles.grayPanel, pannel -> { diff --git a/src/meld/world/blocks/Bruisekit.java b/src/meld/world/blocks/Bruisekit.java index c07fa71..2961852 100644 --- a/src/meld/world/blocks/Bruisekit.java +++ b/src/meld/world/blocks/Bruisekit.java @@ -1,12 +1,22 @@ package meld.world.blocks; +import arc.Core; import arc.graphics.g2d.Draw; import arc.graphics.g2d.Lines; +import arc.graphics.g2d.TextureRegion; +import arc.math.Angles; import arc.math.Mathf; +import arc.math.geom.Vec2; import arc.struct.Seq; import arc.util.Log; +import arc.util.Time; +import arc.util.Tmp; +import meld.content.MeldFx; +import mindustry.content.Fx; import mindustry.entities.Units; import mindustry.gen.Building; +import mindustry.graphics.Layer; +import mindustry.graphics.Pal; public class Bruisekit extends FieldPulsar{ @@ -14,10 +24,32 @@ public class Bruisekit extends FieldPulsar{ int targetTimer = timers++; - public float healSpeed = 2; + public float rotateSpeed = 2f; + public float shootCone = 10f; + public float shootY = 6; + + public float healAmount = 20; public float retargetInterval = 5; - public float recentDamageMultiplier = 0.1f, smallMultiplier = 0.5f; + public float recentDamageMultiplier = 0.5f, smallMultiplier = 0.25f; + + public float bruiseMulti = 4; + + public TextureRegion baseRegion, turretRegion; + + public float reload = 90; + + @Override + public void load() { + super.load(); + baseRegion = Core.atlas.find(name + "-base", name); + turretRegion = Core.atlas.find(name + "-turret", name); + } + + @Override + protected TextureRegion[] icons() { + return new TextureRegion[]{baseRegion, turretRegion}; + } public Bruisekit(String name) { super(name); @@ -26,6 +58,10 @@ public Bruisekit(String name) { public class BruisekitBuild extends PulsarBuild{ public Building target; + public float rotation = 90; + public float reloadTime = 0; + public boolean shooting = false; + public Vec2 shootOffset = new Vec2(); @Override public boolean shouldConsume() { @@ -35,15 +71,75 @@ public boolean shouldConsume() { @Override public void updateTile() { super.updateTile(); + shooting = false; + shootOffset.trns(rotation, shootY).add(x, y); + + reloadTime = Math.min(reloadTime + edelta(), reload); + if(timer.get(targetTimer, retargetInterval)) findTarget(); - if(target != null){ - if(target.isValid() && target.damaged()) { - float healAmount = healSpeed * edelta(); - if(target.wasRecentlyDamaged()) healAmount *= recentDamageMultiplier; - if(target.block.size == 0) healAmount *= smallMultiplier; - target.heal(healAmount); + if(target != null && target.isValid()) { + + if(target.damaged()){ + float angleTowards = angleTo(target); + rotation = Angles.moveToward(rotation, angleTowards, rotateSpeed); + + if(Angles.angleDist(rotation, angleTowards) <= shootCone){ + + + shooting = true; + + if(reloadTime >= reload) { + reloadTime = 0; + Vec2 end = new Vec2(target.x, target.y); + + MeldFx.chainLightning.at(target.x, target.y, 0, Pal.heal, + new MeldFx.VisualLightningHolder(){ + @Override + public Vec2 start() { + return shootOffset; + } + + @Override + public Vec2 end() { + return end; + } + + @Override + public float width() { + return 4; + } + + @Override + public float segLength() { + return 8; + } + + @Override + public float arc() { + return 0.2f; + } + + @Override + public int coils() { + return 2; + } + }); + + float healed = healAmount * edelta(); + if(target.wasRecentlyDamaged()) healed *= recentDamageMultiplier; + if(target.block.size == 0) healed *= smallMultiplier; + + healed *= Mathf.lerp(1, bruiseMulti, Math.min(2 - 2 * target.healthf(), 1)); + + target.heal(healed); + + Fx.healBlockFull.at(target.x, target.y, 0, Pal.heal, target.block); + } + + } } + else target = null; } } @@ -55,15 +151,22 @@ public void findTarget(){ if(b.team == team() && b.damaged()) tmpDamaged.add(b); }); - tmpDamaged.sort(b -> b.block.size * 10 + (1 - b.healthf()) + Mathf.log(10, b.block.health)/10); + tmpDamaged.sort(b -> b.block.size * 10 + (1 - b.healthf()) + Mathf.log(10, b.block.health)/10 + b.block.priority); 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); + Draw.reset(); + Draw.z(Layer.blockOver); + Draw.rect(baseRegion, x, y); + Draw.z(Layer.turret); + Draw.rect(turretRegion, x, y, rotation - 90); + Draw.z(Layer.buildBeam); + if(target != null && shooting){ + Lines.line(shootOffset.x, shootOffset.y, target.x, target.y); + } } } } diff --git a/src/meld/world/blocks/Gauze.java b/src/meld/world/blocks/Gauze.java index aff2d37..436c0e7 100644 --- a/src/meld/world/blocks/Gauze.java +++ b/src/meld/world/blocks/Gauze.java @@ -38,6 +38,7 @@ public class Gauze extends Block { public Gauze(String name) { super(name); update = true; + solid = true; } @Override diff --git a/src/meld/world/blocks/MeldNode.java b/src/meld/world/blocks/MeldNode.java index de904dc..4b77b91 100644 --- a/src/meld/world/blocks/MeldNode.java +++ b/src/meld/world/blocks/MeldNode.java @@ -1,9 +1,13 @@ package meld.world.blocks; import arc.func.*; +import arc.util.Log; import meld.*; import meld.core.*; +import mindustry.Vars; import mindustry.content.Blocks; +import mindustry.content.Fx; +import mindustry.gen.Unit; import mindustry.world.blocks.storage.CoreBlock; //Like a core but spawns melting overlays near it on destruction @@ -13,12 +17,10 @@ public MeldNode(String name) { } public class MeldNodeBuild extends CoreBuild{ + @Override public void killed() { - /// start melting before killing - /// otherwise {@link mindustry.world.Tile#getLinkedTiles(Cons)} won't work - Meld.melting.start(tileOn()); - + Meld.melting.start(tile); super.killed(); } } diff --git a/src/meld/world/blocks/consumers/StupidConsumeAspects.java b/src/meld/world/blocks/consumers/StupidConsumeAspects.java index 551711b..0e63f1a 100644 --- a/src/meld/world/blocks/consumers/StupidConsumeAspects.java +++ b/src/meld/world/blocks/consumers/StupidConsumeAspects.java @@ -7,6 +7,7 @@ import arc.struct.IntMap; import arc.struct.ObjectFloatMap; import arc.util.Log; +import arc.util.Time; import meld.fluid.AspectGroup; import meld.world.blocks.crafting.MeldGenericCrafter; import mindustry.Vars; @@ -68,20 +69,17 @@ public Liquid getConsumed(Building build){ @Override public float efficiency(Building build) { Liquid liq = this.getConsumed(build); - float ed = build.edelta(); + float ed = build.timeScale() * Time.delta; if(Mathf.zero(ed) || liq == null) return 0; else { - - float multi = group.getEfficiency(liq); - - return Math.min(build.liquids.get(liq) / (this.amount * ed * multi), multi); + return Math.min(build.liquids.get(liq) / (this.amount * ed), 1); } } @Override public float efficiencyMultiplier(Building build) { Liquid liq = this.getConsumed(build); - return liq == null ? 0.0f : group.getEfficiency(liq); + return liq == null ? 1 : group.getEfficiency(liq); } @Override diff --git a/src/meld/world/blocks/crafting/RecipeCrafter.java b/src/meld/world/blocks/crafting/RecipeCrafter.java index 80527b5..418cc10 100644 --- a/src/meld/world/blocks/crafting/RecipeCrafter.java +++ b/src/meld/world/blocks/crafting/RecipeCrafter.java @@ -81,23 +81,13 @@ public void getRegionsToOutline(Seq out){ @Override public void init() { super.init(); + //TODO: let the recipies tell the block which items and liquids can be used as I/O - //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); - } + inputItems.each(i -> { + itemFilter[i.id] = true; + }); + inputLiquids.each(i -> { + liquidFilter[i.id] = true; }); } @@ -218,24 +208,33 @@ public void updateTile() { 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; + findRecipe(); } times[last] = time; } else { - recipe = recipes.find(r -> r.valid(crafter, this)); - if(recipe != null) last = recipes.indexOf(recipe); + findRecipe(); } dumpOutputs(); } + public void findRecipe(){ + recipe = recipes.find(r -> r.valid(crafter, this)); + if(recipe != null) last = recipes.indexOf(recipe); + } + public void dumpOutputs(){ + outputItems.each(this::dump); + if(outputSlots.size > 0){ for(Liquid output: outputSlots){ diff --git a/src/meld/world/blocks/crafting/recipe/TimedRecipe.java b/src/meld/world/blocks/crafting/recipe/TimedRecipe.java index f935a84..89382b0 100644 --- a/src/meld/world/blocks/crafting/recipe/TimedRecipe.java +++ b/src/meld/world/blocks/crafting/recipe/TimedRecipe.java @@ -1,10 +1,76 @@ package meld.world.blocks.crafting.recipe; +import arc.struct.Seq; import meld.world.blocks.crafting.RecipeCrafter; +import meld.world.blocks.producer.Produce; +import mindustry.gen.Building; +import mindustry.world.Block; +import mindustry.world.consumers.Consume; -public class TimedRecipe extends ItemRecipe { +public class TimedRecipe extends Recipe { + public Seq consumers = new Seq<>(); + public Seq producers = new Seq<>(); public float craftTime = 60; + public TimedRecipe() { + } + public TimedRecipe(float craftTime){ + this.craftTime = craftTime; + } + + public TimedRecipe addConsumers(Consume... list){ + consumers.addAll(list); + return this; + } + public TimedRecipe addProducers(Produce... list){ + producers.addAll(list); + return this; + } + + @Override + public void update(Block block, Building building) { + + building.efficiency = efficiency(block, building); + + consumers.each(c -> c.update(building)); + producers.each(p -> p.update(building)); + + building.efficiency = building.efficiency * boostEfficiency(block, building); + } + + public float efficiency(Block block, Building building){ + float minEfficiency = 1; + + for(Consume consumer: consumers){ + minEfficiency = Math.min(consumer.efficiency(building), minEfficiency); + } + for(Produce producer: producers){ + minEfficiency = Math.min(producer.efficiency(building), minEfficiency); + } + + return minEfficiency; + } + + public float boostEfficiency(Block block, Building building){ + float efficiency = 1; + + for(Consume consumer: consumers){ + efficiency *= consumer.efficiencyMultiplier(building); + } + + return efficiency; + } + + @Override + public void apply(Block block, Building building) { + consumers.each(c -> c.trigger(building)); + producers.each(p -> p.trigger(building)); + } + + @Override + public boolean valid(Block block, Building build) { + return efficiency(block, build) > 0; + } } diff --git a/src/meld/world/blocks/producer/Produce.java b/src/meld/world/blocks/producer/Produce.java index 15476b0..c6d2e64 100644 --- a/src/meld/world/blocks/producer/Produce.java +++ b/src/meld/world/blocks/producer/Produce.java @@ -1,4 +1,40 @@ package meld.world.blocks.producer; +import arc.scene.ui.layout.Table; +import mindustry.gen.Building; +import mindustry.world.Block; +import mindustry.world.consumers.Consume; +import mindustry.world.meta.Stats; + +/** + * A copy of Consume but for production + */ public class Produce { + + /** @return if true, this consumer will be ignored in the production list (no updates or valid() checks) */ + public boolean ignore(){ + return false; + } + + public void build(Building build, Table table){ + + } + + /** Called when a production is triggered manually. */ + public void trigger(Building build){ + + } + + public void update(Building build){ + + } + + /** @return [0, 1] efficiency multiplier based on input. Returns 0 if not valid in subclasses. Should return fraction it can partially output. */ + public float efficiency(Building build){ + return 1f; + } + + public void display(Stats stats){ + + } } diff --git a/src/meld/world/blocks/producer/ProduceItem.java b/src/meld/world/blocks/producer/ProduceItem.java new file mode 100644 index 0000000..e0ee284 --- /dev/null +++ b/src/meld/world/blocks/producer/ProduceItem.java @@ -0,0 +1,22 @@ +package meld.world.blocks.producer; + +import mindustry.gen.Building; +import mindustry.type.ItemStack; + +public class ProduceItem extends Produce{ + public ItemStack output; + + public ProduceItem(ItemStack output){ + this.output = output; + } + + @Override + public float efficiency(Building build) { + return build.getMaximumAccepted(output.item) - build.items.get(output.item) >= output.amount ? 1 : 0; + } + + @Override + public void trigger(Building build) { + build.items.add(output.item, output.amount); + } +} diff --git a/src/meld/world/blocks/producer/ProduceLiquid.java b/src/meld/world/blocks/producer/ProduceLiquid.java new file mode 100644 index 0000000..81b74c7 --- /dev/null +++ b/src/meld/world/blocks/producer/ProduceLiquid.java @@ -0,0 +1,33 @@ +package meld.world.blocks.producer; + +import arc.math.Mathf; +import mindustry.gen.Building; +import mindustry.type.ItemStack; +import mindustry.type.Liquid; +import mindustry.type.LiquidStack; + +//Continuously produces liquid +public class ProduceLiquid extends Produce{ + + public LiquidStack output; + + public ProduceLiquid(Liquid liquid, float amount){ + output = new LiquidStack(liquid, amount); + } + + public ProduceLiquid(LiquidStack output){ + this.output = output; + } + + @Override + public float efficiency(Building build) { + return Mathf.clamp(build.block.liquidCapacity - build.liquids.get(output.liquid) / output.amount); + } + + + @Override + public void update(Building build) { + super.update(build); + build.handleLiquid(build, output.liquid, output.amount); + } +} diff --git a/src/meld/world/blocks/production/SingleBeamDrill.java b/src/meld/world/blocks/production/SingleBeamDrill.java index eea2d9f..faadb00 100644 --- a/src/meld/world/blocks/production/SingleBeamDrill.java +++ b/src/meld/world/blocks/production/SingleBeamDrill.java @@ -38,7 +38,7 @@ public class SingleBeamDrill extends Block { //Additional items mined for each tile unused in the range public int distanceProductivity = 5; - public float selfDamage = 400; + public float selfDamage; public float targetDamage = 2400; public ObjectFloatMap itemMultipliers = new ObjectFloatMap<>(); public ObjectMap transformItems = new ObjectMap<>(); @@ -62,6 +62,7 @@ public SingleBeamDrill(String name) { envEnabled |= 2; flags = EnumSet.of(new BlockFlag[]{BlockFlag.drill}); bigExplosion = MeldBullets.pulsarBlast; + selfDamage = 400; } public class SingleBeamBuild extends Building{ @@ -75,7 +76,7 @@ public boolean shouldConsume() { @Override public void updateTile() { super.updateTile(); - if(healthf() >= minHealthf) time += efficiency; + if(healthf() >= minHealthf) time += edelta(); if(time >= drillTime){ drill(); time %= drillTime;