diff --git a/assets/bundles/bundle.properties b/assets/bundles/bundle.properties index 34732a3..65671d6 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 shrapnel at enemy targets with slight piercing.\n[accent]Spread is focused towards the aim direction\n\nEffects vary based on ammo type[] +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![] @@ -101,7 +101,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 can't target 1x1s. +block.meld-bruisekit.description = Regenerates target block's health.\n\nPrioritises large, functional blocks and works at half speed on 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. @@ -189,7 +189,7 @@ block.meld-compartmentalized-node.description = Acts as a fluid router. Liquid c block.meld-compartmentalized-node.details = Yes, it's dumb that the name goes one character off the UI frag. I'm triggered by this too. block.meld-channel-hub.name = Channel Hub -block.meld-channel-hub.description = Acts as a fluid router. Liquid can be input or output from any side.\n\nStores 100 nodes worth of fluid. +block.meld-channel-hub.description = Acts as a fluid router. Liquid can be input or output from any side.\n\nStores 100 nodes worth of fluid.\n\n[accent]Plated![] block.meld-filtration-unit.name = Filtration Unit block.meld-filtration-unit.description = Acts as a filter. Outputs [#89828c]Mercury[] to any side.\n\nWhen powered with [#cbdbfc]Aspect[] while containing [#89828c]Mercury[], filters out Debris and Starving masses from [#7d312f]Blood[] and [#b89f47]Nectar[], producing some [#89828c]Mercury[] in the process.\n\n[accent]Halts when fully pressurized with [#89828c]Mercury[]![] @@ -444,7 +444,7 @@ block.meld-pointago-coffer.name = Pointago Coffer block.meld-pointago-coffer.description = Bursts open into multiple Pointago upon destruction. Locks onto a target's, then fires a 3 round burst of sharp rocks. block.meld-meld-cannon.name = Meld Cannon -block.meld-meld-cannon.description = Lobs clusters of highly compressed Aether at enemies. +block.meld-meld-cannon.description = Lobs globs of [meld-meld]Meld[] at enemies, suppressing them. block.meld-meld-spewer.name = Meld Spewer block.meld-meld-spewer.description = Sprays focused jets of [#e6c700]Ichor[] toward targets doing huge focused knockback, healing any allied building in the way. @@ -743,10 +743,18 @@ 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-thundering-aether.name = [#e98b66]Thundering Aether[] +liquid.meld-thundering-aether.description = Cackles and crackles, an energy inbetween.\n\nCan be used in place of [#cb8650]Aether[] +liquid.meld-thundering-aether.details = Crickling and crackling, cackling and cack- auegh... dammit\n\nwait, is this thing still on?\n\nFith... fith- sixed? nono... has t-[red][] + 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-storming-aspect.name = [#ffffff]Storming Aspect[] +liquid.meld-storming-aspect.description = Sparks and flashes, dancing on the monitor.\n\nCan be used in place of [#cbdbfc]Aspect[] +liquid.meld-storming-aspect.details = Hexing dance 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. @@ -784,18 +792,11 @@ liquid.meld-meld.name = [#ea9ad6]Meld[] liquid.meld-meld.description = Slowly disolves most metals and organics, save for a group of materials. liquid.meld-meld.details = The original lifeform on Ikaru in gaseous state. -liquid.meld-waste.name = Waste -liquid.meld-waste.description = Slurry of unusable gunk - -liquid.meld-cold-waste.name = Cold waste -liquid.meld-cold-waste.description = Cold slurry of unusable gunk - -liquid.meld-valid.name = Valid Placement -liquid.meld-deposit.name = Deposit -liquid.meld-progress.name = Progress -liquid.meld-charge = Charge -liquid.meld-dissonance = Charge - +//Aspect Groups +aspect-group.meld-aether = [meld-aether]Aether +aspect-group.meld-aspect = [meld-aspect]Aspect +aspect-group.meld-fumes = [meld-fumes]Fumes +aspect-group.meld-outlet-fuel = Outlet Fuel //Units @@ -808,7 +809,7 @@ unit.meld-observer. //Strata units unit.meld-bulbhead.name = Bulbhead -unit.meld-bulbhead.description = Commander of the Raft core. Shoots sonar pulses and [accent]Rallies[] nearby allies. Repairs allied structures. Can reconstitute itself using appropriate liquids, or with enough time. +unit.meld-bulbhead.description = Commander of the Raft core. Shoots sonar pulses and [accent]Rallies[] nearby allies. Repairs allied structures. Can reconstitute itself using appropriate liquids, or with enough time.\n\nHovers over buildings and solid floors at a reduced speed. unit.meld-bulbhead.details = The classic. unit.meld-bulbhead-sonar.name = Bulbhead Overseer @@ -942,7 +943,7 @@ unit.meld-uwubba.details = Yknow theres probably a joke to be made here. unit.meld-ontragga.name = Ontragga unit.meld-ontragga.description = [#ea9ad6]Second form seige worm[]\nConstruct creeps foward shielding numerous wuba inside from harm whilst sporting a heavy aether cannon which fires in three round bursts.\n\nThis construct is a [accent]high priority target[] and [red]must[] be taken out before it breaches a defensive perimeter, [red]DO NOT LET IT LEAK.[]\n\n[red]Plated![]\n\n[orange]Biomechanical![] -unit.meld-uwubba.details = Yknow theres probably a joke to be made here. +unit.meld-ontragga.details = Yknow theres probably a joke to be made here. unit.meld-globkin.name = Globkin unit.meld-globkin.description = [#ea9ad6]Guardian skirmisher nest construct[]\n\nConstruct jolts backwards after launching a blast of shrapnel from its cannons, containing several blobs that detonate if not dealt with.\n\nDistract with moble units or drop overseer pings on it to prevent it from recoiling past defensive lines.\n\n[red]Plated![] @@ -1013,94 +1014,6 @@ unit.meld-soontm.name = Coming Soon! //research categories -//Liquid logistics tree - -status.meld-liquid-logistics.name = [accent]Liquid Logistics[] -status.meld-liquid-logistics.description = Schematics for a basic [accent]liquid distribution network[] and an [#cb8650]Aether[] source.\nThe network is comprised of four components.\n\n\n-[accent]Channel Nodes[] which form the corners and outlets of the network\n-[accent]Channel Faces[] which connect parts of the network.\n-[accent]Channel Directors[] which control the direction and pressure of fluids\n-[accent]Aspect Outlets[] which serve as the endpoint for [#cb8650]Aether[] networks.\n\nChannels can be walked on freely and are stable enough to be placed on deep patches of liquid. The Backdrop will [red]not[] support Channels. - -status.meld-murk-handling.name = [accent]Murk Handling[] -status.meld-murk-handling.description = The Mercury Swamp has proven to be quite hostile in numerous ways, but bessides the outright hostile threats, there have been issues reguarding excess Starving Masses and fluid filtration...\n\nTheese schematics detail a number of ways to handle this, ranging from [accent]Compartmentalized Nodes[], [accent]Filtration Units[], [accent]Neutralization/Purification Chambers[].\n\n[accent]Pressurized Dispersion[] would be helpful to control any accidents. - -status.meld-pressure-control.name = [accent]Pressure Control[] -status.meld-pressure-control.description = Advanced means of [accent]pressure control[] involving [accent]large fluid hubs, pressurized directors, and fluid siphons[]. - -status.meld-pressurized-dispersion.name = [accent]Pressurized Dispersion[] -status.meld-pressurized-dispersion.description = Getting fluids from point A to B was previously only possible with Channels. Any attempts to shoot Fluids out into the world only created puddles.\n\nWith advances in [accent]Pressure Control[] combined with observations about the Mercury Swamp's flora, fluids can now be dispersed into the world with more control over longer distances.\n\n[red]Further advances in technology are required to bridge gaps inside Channel networks or to utalize solid atomized jets.[]\n\n[accent]Murk Handling[] is greatly helpful to filter out fluids for use by Fluid Sprayers. - -status.meld-fluid-extraction.name = [accent]Fluid Extraction[] -status.meld-fluid-extraction.description = Filtration methods inspired off Blossoming Elderflesh give way to means of [accent]directly[] obtaining fluids from [accent]surface deposits[] with varying expirimental methods. -status.meld-fluid-extraction.details = Finally, a direct way to directly harvest [#89828c]Mercury[] pools. A means of extracting massive quantities of liquid [#ea9ad6]Meld[] if I feel like it. - -status.meld-crude-crackers.name = [accent]Crude Crackers[] -status.meld-crude-crackers.description = Schematics taking advantage of the badland's catalytic features.\n\n[#8166f0]More observation may be required to fully defragment this entry's buildings.[] -status.meld-crude-crackers.details = The implications of having to resort to such primitive technology to aquire [#cb8650]Aether[] are not ot be taken lightly. - -liquid-logistics.unlock = [accent]Liquid Logistics Unlocked![]\n[gray] - -//Item logistics tree - -status.meld-item-logistics.name = [accent]Item Logistics[] -status.meld-item-logistics.description = Schematics for a basic [accent]item distribution system[] and an [accent]Item[] source.\n\nThis system is comprised of a system of [accent]Chute[] components which route items from place to place. - -item-logistics.unlock = [accent]Item Logistics Unlocked![]\n[gray] - -status.meld-storage-hubs.name = [accent]Storage Hubs[] -status.meld-storage-hubs.description = Details about [accent]Buffers[] and [accent]Unloaders[], thought to be lost to time.\n\nPlans for massive storage warehouses are [red]encrypted[] for now... - -status.meld-fissure-tapping.name = [accent]Fissure Tapping[] -status.meld-fissure-tapping.description = Schematics for buildings which can utalize Ikaru's various crevices like [accent]Vents[], [accent]Fissures[] and [accent]Growths[].\n\n[#8166f0]More observation may be required to fully defragment this entry's buildings.[] -status.meld-fissure-tapping.details = Ikaruian vents have strange properties. Most vents emit fumes which are key in a number of different processes, but the main two are creating a concrete substitute and synthesizing carbolith in times of deficit.\n\nCertain vents run with [#e6c700]Ichor[] emitting coloured sparkles alongside the regular dull brown smoke swirls. - -fissure-tapping.unlock = [accent]Fissure Tapping Unlocked![]\b[gray] - -status.meld-building-foundations.name = Building Foundations -status.meld-building-foundations.description = For too long structures have been made with Debris and Carbolith as foundations, only using refined materials for moving parts...\n\nWith new data about [#e6c700]Ichor[]'s properties, and observations about how [#ea9ad6]Meld[] constructs form their shells, a new way to industrially cement Carbolith dust into mock Carbon Stone has been prototyped and is ready to deploy.\n\n[accent]Brick Conglomerators and Earthen Crushers[] produce the bricks and motar for building foundations with a variety of materials and deposits, allowing certain buildings to take on some natural [accent]armor[] and be built far quicker.\n\n[accent]Boulders are a good source of Bricks/Gloop and will return some when deconstructed.[] - -status.meld-mercurial-extraction.name = [accent]Mercurial Extraction[] -status.meld-mercurial-extraction.description = A group of schematics, all revolving around one thing: Refining raw material into Mercury over geothermal spots.\n\nIntrestingly, there is an outlier. The [accent]Electrum Amalgamator[]. -mercurial-extraction.unlock = [accent]Mercurial Extraction Unlocked![]\n[gray] - - - -//Utility tree - -status.meld-aspect-channeling.name = [#cbdbfc]Aspect Channeling[] -status.meld-aspect-channeling.description = Details about how to contain and channel Aspect into a variety of uses like [accent]Sonar Pings[], [accent]self regeneration[] and even [red]NULLIFICATION[].\n\nContains some schematics for buildings which use Silver & Resonarum to achieve this, but the rest are scattered through other entries... -status.meld-aspect-channeling.details = Aspect was deemed too dangerous to be converted into power en-mass, but there is rumor of an entry heavly encrypted which allowed for this type of conversion.\n\nThe Temple guarding this secret was to be hidden away from Strata, hidden from you, but there is still hope that it hasn't completely sunken into the backdrop... - -aspect-channeling.unlock = [accent][#cbdbfc]Aspect Channeling[] Unlocked![]\n[gray] - -status.meld-power-transmission.name = [accent]Power Transmission[] -status.meld-power-transmission.description = Schematics for buildings which use Electrum to focus power into lasers, allowing transmission without physical connection. This entry is comprised of three buildings.\n\n-[accent]Connectors[] are a stock standard power node which use Stony Gloop & Compacted Bricks as compared to more abundant materials, allowing them to be built quickly.\n-[accent]Substations[] are able to both connect over longer distances (but to fewer targets) and store small amounts of power.\n-[accent]Continental Links[] are able to bridge large sections of the sector in a cardinal direction, and can withstand a large amount of damage.\n\n[#8166f0]More observation may be required to fully defragment this entry's buildings.[] - -//sector categories - -//Todo: Unify Unlocked text? - -status.meld-ruins.name = Ruins -status.meld-ruins.description = This data point marks the last known location of a Strata instance, and seems to branch out into an almost endless amount of sector groups.\n\n[accent]As the campaign is a WIP right now, no sector groups are accessable yet![] -status.meld-ruins.details = It's time. - -ruins.unlocked = [accent]Ruins Unlocked![]\n[gray] - - -status.meld-lonely-creek.name = Lonely Creek -status.meld-lonely-creek.description = This data point leads toward a secluded creek woven between monolithic rock formations.\n\n[red]There are hundreds, maybe thousands of heat signatures in the distance, none of which are recognisable through the fog.[]\n\nWhat is this place? -status.meld-lonely-creek.details = [lightgray]This is not the way out you were looking for, and you don't have much else to go off.\n\nTime to get yourself together and explore your suroundings.[] - -beginnings.unlocked = [accent]Lonely Creek Unlocked![]\n[gray] - - -status.meld-barrens.name = Carbonic Barrens -status.meld-barrens.description = This data point appears to mark the entrance to a large expanse of carbon stone.\n\nThere is a heavy pink fog in the area lowering visibility dramatically, though there appears to be plentiful [accent]carbolith[] deposits scattered throughout. -status.meld-barrens.details = [lightgray]It's too clouded to recognize anything from a distance.[]\n\nMythical daemons were rumored to inhabit the lands of unseen planets. Though I've never seen one, I'd assume this place may have some answers. -barrens.unlocked = [accent]Carbonic Barrens Unlocked![]\n[gray] - -status.meld-glacier.name = Glacier's Edge -status.meld-glacier.description = This data point leads to a giant formation of crystalline megaliths.\n\n[accent]The fog isn't as thick here, allowing full vission of the terrain.[]\n\nConversely, there seem to be [red]trace amounts of resources available[], though many [accent]friendly[] signals pop up within the datapoint's bounds. -status.meld-glacier.details = They're trapped. As soon as it assumed there were no hostiles around, the spikes grew. Nobody's ever seen this before, and I pray that nobody suffers the same fate. -glacier.unlocked = [accent]Glacier's Edge Unlocked![]\n[gray] - //Status effects status.meld-aspect-burn.name = Aspect Burn @@ -1178,60 +1091,6 @@ status.meld-storm-a1-enabled.description = Increased mobility, damage and reload //Sectors -sector.meld-a-1a-resurgence.name = Resurgence -sector.meld-a-1a-resurgence.description = [accent]Strata has awoken.[]\n\nPlay out its journy. Linger in the confusion. -sector.meld-a-1a-resurgence.details = Nobody left but you.\nOne of two Strata housing facilities. - -sector.meld-creek.name = Creek -sector.meld-creek.description = Incursion point for Ikaru. Practise basic production and ways to push into enemy teritory.\n\n[accent]Objective: Attack\nWeather: Drizzle -sector.meld-creek.details = Something's wrong here... - -sector.meld-scrapyard.name = Scrapyard -sector.meld-scrapyard.description = Filled with Debris and Silver, but [red]lacking[] in Carbolith. Deploy new infusion technology.\n\nThe landing area is [red]resource deprived[], be ready to [accent]attack[]!\n\n[accent]Objective: Survive\nWeather: Hazy\n\n[gray][][accent]\n-Carbolith depleted[]\n\n[#ea9ad6]-1 Meld Amplifier spotted![] -sector.meld-scrapyard.details = The wildlife explodes? - -sector.meld-dead-end.name = Dead End? -sector.meld-dead-end.description = Scrapyard leaves no further routes to explore Ikaru.\nA new data point is encrypted inside a nearby facility, but the keys are in other locations.\n\nCome back when either [accent]Hedge[] or [accent]Shear[] have been completed!\n\n[accent]Objective: Explore\nWeather: None\n\n[gray][][accent]\n-Carbolith depleted[] -sector.meld-dead-end.details = An old checkpoint where Fringe used to rest at between sessions of work. - -sector.meld-hedge.name = Hedge -sector.meld-hedge.description = Scrapyard leaves no further routes to explore Ikaru.\nBacktracking from Creek is the only way fowards.\nThe branching path ahead will [red]further provoke the [#ea9ad6]Meld[].[]\n\n[red]Aerial threats[] will come from the [accent]north[]. Use [accent]Sunder[] turrets to counter them.\n\n[accent]Objective: Survive\nWeather: Foggy\n\n[gray]\n[accent]-Carbolith depleted[][]\n[#ea9ad6]-3 Meld Amplifiers spotted![] -sector.meld-hedge.details = ...why does it sound like missiles are inbound? - -sector.meld-shear.name = Shear -sector.meld-shear.description = Scrapyard leaves no further routes to explore Ikaru.\nBacktracking from Creek is the only way fowards.\nThe branching path ahead will [red]further provoke the [#ea9ad6]Meld[].[]\n\n[#ea9ad6]Meld[] attacks will switch sides after every burst, starting from the west front.\n\n[accent]Friendly signals have been detected... be ready for anything![]\n\n[accent]Objective: ???\nWeather: [green]Australian[]\n\n[gray][]\n[#ea9ad6]-2 Meld Amplifiers spotted![] -sector.meld-shear.details = The tactics never grew, but the hand opened. - -block.meld-hedge-ending.name = Hedge Decryption Key -block.meld-hedge-ending.details = One of two decryption keys for [accent]Dead End[]'s facility. - -block.meld-shear-ending.name = Shear Decryption Key -block.meld-shear-ending.details = One of two decryption keys for [accent]Dead End[]'s facility. - -status.meld-hedge-or-shear.name = Hedge or Shear -status.meld-hedge-and-shear.name = [accent]Both[] Hedge and Shear -status.meld-creek-nullified.name = Creek Completed! -status.meld-creek-nullified.description = What the hell was that??? - -creek-nullified.unlock = [accent]Scrapyard unlocked![]\n[gray]<...maybe it's time to get out of here> - -sector.meld-reminant.name = Remenant -sector.meld-reminant.description = [cyan]Datamine![]\n\nAbandoned and entombed with [#ea9ad6]crystaline megaliths[].\n\nHuge swarms of flying and artillery constructs have been recorded, along with an unknown [red]eradication[] tier threat.\n\n[accent]Dredge[] and [accent]process[] as many [accent]research materials[] as you can, untill the waves overwhelm you.\n\n[red]There is no [#4bb66b]Resonarum[] in this sector. Nullifiers inaccesable![]\n\n[accent]Objective: Dredge\n\n[gray][]\n[accent]-[#4bb66b]Resonarum[] depleted[]\n[#ea9ad6]-2 Meld Amplifiers spotted!\n-Spawning pools spotted![] -sector.meld-reminant.details = An endless battle, a meaningless victory, and a story to tell.\nI can hear their voices still linger. - -sector.meld-tempest-in-a-teacup.name = [#ea9ad6]Tempest in a Teacup[] -sector.meld-tempest-in-a-teacup.description = Another [accent]Strata[] instance has already setup a base here, and moved on.\n\nHarsh weather had been observed in response to activity, so the base lies dormant in a divot.\n\nEnsure you don't get overwhelmed by the [red]heavy storms[], and keep your units repaired.\n\n[accent]Objective: Weather the storm\nWeather: Clear, then [red]Torrential[], then Clear\n\n[gray][]\n[accent]\n[#ea9ad6]-2 Meld Amplifiers spotted!\n-Quick Start! -sector.meld-tempest-in-a-teacup.details = ...there were others? - -sector.meld-slumber.name = Slumber -sector.meld-slumber.description = This planet hasn't solidified yet...\n\nYou've done well to make it this far.\n\n[accent]Objective: ???\nWeather: ??? -sector.meld-slumber.details = A meaningless victory it was not. Meaning was given the moment they started to fight.\n\n[lightgray]This isn't right.\nShoudn't there be more?\n\nMaybe im using the wrong map. - -sector.meld-the-end.name = The End? -sector.meld-the-end.description = A point of interest has been located in the far reaches of Ikaru. Discover what lingers in the sector.\n\n[accent]Objective: Explore - -sector.meld-coming-soon.name = Coming Soon! - planet.meld-ikaru.name = Ikaru planet.meld-ikaru.description = A wartorn planet with scraps of usable unrefined resources. Inhabited by the [#ea9ad6]Meld[].\n\nHeavy fog lingers everywhere. planet.meld-ikaru.details = The [#ea9ad6]Meld[] was always here. There was no beginning or end to life on Ikaru. from the planet's inception to its destruction, there will be always [#ea9ad6]Meld[]. @@ -1387,3 +1246,16 @@ sectors.underattack.nodamage = [accent]In Progress... status.disarmed.name = Disarmed +database-category.aspect = Aspecti +database-tag.aspect-powergen = Potential/Power family +database-tag.aspect-omnipotence = Progress +database-tag.aspect-vita = Vita + +database-tag.heavy-industry = Heavy Industry + +unit.ticks = ticks + +bar.spool = Spool + +stat.aspect-efficiency = Efficiency +stat.aspect-density = Density \ No newline at end of file diff --git a/assets/bundles/bundle.shitpost b/assets/bundles/bundle.shitpost index 4806279..a674a1b 100644 --- a/assets/bundles/bundle.shitpost +++ b/assets/bundles/bundle.shitpost @@ -5,4 +5,7 @@ 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 +block.meld-pressure-vent.name = Amogus Escape route + +unit.meld-bulbhead.name = Bulbster +unit.meld-bulbhead.description = Meldieps the allied blocks as it Meldarras.io the enemies \ No newline at end of file diff --git a/assets/maps/gameplay-testmap-2.msav b/assets/maps/gameplay-testmap-2.msav index 541753e..21ce5bc 100644 Binary files a/assets/maps/gameplay-testmap-2.msav and b/assets/maps/gameplay-testmap-2.msav differ diff --git a/assets/sprites/blocks/fluid/channel-director.png b/assets/sprites/blocks/fluid/channel-director.png index 35b1b96..4962d05 100644 Binary files a/assets/sprites/blocks/fluid/channel-director.png and b/assets/sprites/blocks/fluid/channel-director.png differ diff --git a/assets/sprites/blocks/fluid/channel-hub-bottom.png b/assets/sprites/blocks/fluid/channel-hub-bottom.png index 7b94cfe..a228327 100644 Binary files a/assets/sprites/blocks/fluid/channel-hub-bottom.png and b/assets/sprites/blocks/fluid/channel-hub-bottom.png differ diff --git a/assets/sprites/blocks/fluid/channel-hub.png b/assets/sprites/blocks/fluid/channel-hub.png index ccb968b..f32c61f 100644 Binary files a/assets/sprites/blocks/fluid/channel-hub.png and b/assets/sprites/blocks/fluid/channel-hub.png differ diff --git a/assets/sprites/blocks/meld/coffer/billa-coffer.png b/assets/sprites/blocks/meld/coffer/billa-coffer.png new file mode 100644 index 0000000..f2dbb1d Binary files /dev/null and b/assets/sprites/blocks/meld/coffer/billa-coffer.png differ diff --git a/assets/sprites/blocks/turrets/shredstorm/shredstorm-barrel.png b/assets/sprites/blocks/turrets/shredstorm/shredstorm-barrel.png new file mode 100644 index 0000000..6f8d4d8 Binary files /dev/null and b/assets/sprites/blocks/turrets/shredstorm/shredstorm-barrel.png differ diff --git a/assets/sprites/blocks/turrets/shredstorm/shredstorm-plate-l.png b/assets/sprites/blocks/turrets/shredstorm/shredstorm-plate-l.png new file mode 100644 index 0000000..e07bb71 Binary files /dev/null and b/assets/sprites/blocks/turrets/shredstorm/shredstorm-plate-l.png differ diff --git a/assets/sprites/blocks/turrets/shredstorm/shredstorm-plate-r.png b/assets/sprites/blocks/turrets/shredstorm/shredstorm-plate-r.png new file mode 100644 index 0000000..acfa703 Binary files /dev/null and b/assets/sprites/blocks/turrets/shredstorm/shredstorm-plate-r.png differ diff --git a/assets/sprites/blocks/turrets/shredstorm/shredstorm-preview.png b/assets/sprites/blocks/turrets/shredstorm/shredstorm-preview.png new file mode 100644 index 0000000..efac3d8 Binary files /dev/null and b/assets/sprites/blocks/turrets/shredstorm/shredstorm-preview.png differ diff --git a/assets/sprites/blocks/turrets/shredstorm/shredstorm.png b/assets/sprites/blocks/turrets/shredstorm/shredstorm.png new file mode 100644 index 0000000..4b0f7c1 Binary files /dev/null and b/assets/sprites/blocks/turrets/shredstorm/shredstorm.png differ diff --git a/assets/sprites/blocks/turrets/viv/sawblade-large-glow.png b/assets/sprites/blocks/turrets/viv/sawblade-large-glow.png new file mode 100644 index 0000000..e691eb3 Binary files /dev/null and b/assets/sprites/blocks/turrets/viv/sawblade-large-glow.png differ diff --git a/assets/sprites/blocks/turrets/viv/sawblade-large-l.png b/assets/sprites/blocks/turrets/viv/sawblade-large-l.png new file mode 100644 index 0000000..d43b267 Binary files /dev/null and b/assets/sprites/blocks/turrets/viv/sawblade-large-l.png differ diff --git a/assets/sprites/blocks/turrets/viv/sawblade-large-r.png b/assets/sprites/blocks/turrets/viv/sawblade-large-r.png new file mode 100644 index 0000000..49b055f Binary files /dev/null and b/assets/sprites/blocks/turrets/viv/sawblade-large-r.png differ diff --git a/assets/sprites/blocks/turrets/viv/sawblade-large.png b/assets/sprites/blocks/turrets/viv/sawblade-large.png new file mode 100644 index 0000000..b81142e Binary files /dev/null and b/assets/sprites/blocks/turrets/viv/sawblade-large.png differ diff --git a/assets/sprites/blocks/turrets/viv/vivisection-base.png b/assets/sprites/blocks/turrets/viv/vivisection-base.png new file mode 100644 index 0000000..ccd090e Binary files /dev/null and b/assets/sprites/blocks/turrets/viv/vivisection-base.png differ diff --git a/assets/sprites/blocks/turrets/viv/vivisection-body-heat.png b/assets/sprites/blocks/turrets/viv/vivisection-body-heat.png new file mode 100644 index 0000000..67a6099 Binary files /dev/null and b/assets/sprites/blocks/turrets/viv/vivisection-body-heat.png differ diff --git a/assets/sprites/blocks/turrets/viv/vivisection-body.png b/assets/sprites/blocks/turrets/viv/vivisection-body.png new file mode 100644 index 0000000..a418d43 Binary files /dev/null and b/assets/sprites/blocks/turrets/viv/vivisection-body.png differ diff --git a/assets/sprites/blocks/turrets/viv/vivisection-center.png b/assets/sprites/blocks/turrets/viv/vivisection-center.png new file mode 100644 index 0000000..f02fbf3 Binary files /dev/null and b/assets/sprites/blocks/turrets/viv/vivisection-center.png differ diff --git a/assets/sprites/blocks/turrets/viv/vivisection-jaw-l.png b/assets/sprites/blocks/turrets/viv/vivisection-jaw-l.png new file mode 100644 index 0000000..d8c40a2 Binary files /dev/null and b/assets/sprites/blocks/turrets/viv/vivisection-jaw-l.png differ diff --git a/assets/sprites/blocks/turrets/viv/vivisection-jaw-r.png b/assets/sprites/blocks/turrets/viv/vivisection-jaw-r.png new file mode 100644 index 0000000..8f8b04e Binary files /dev/null and b/assets/sprites/blocks/turrets/viv/vivisection-jaw-r.png differ diff --git a/assets/sprites/blocks/turrets/viv/vivisection-plate-l.png b/assets/sprites/blocks/turrets/viv/vivisection-plate-l.png new file mode 100644 index 0000000..81f33bc Binary files /dev/null and b/assets/sprites/blocks/turrets/viv/vivisection-plate-l.png differ diff --git a/assets/sprites/blocks/turrets/viv/vivisection-plate-r.png b/assets/sprites/blocks/turrets/viv/vivisection-plate-r.png new file mode 100644 index 0000000..436240a Binary files /dev/null and b/assets/sprites/blocks/turrets/viv/vivisection-plate-r.png differ diff --git a/assets/sprites/bullet/crystalline-smog.aseprite b/assets/sprites/bullet/crystalline-smog.aseprite new file mode 100644 index 0000000..6d9a5d6 Binary files /dev/null and b/assets/sprites/bullet/crystalline-smog.aseprite differ diff --git a/assets/sprites/bullet/crystalline-smog.png b/assets/sprites/bullet/crystalline-smog.png new file mode 100644 index 0000000..f8278c7 Binary files /dev/null and b/assets/sprites/bullet/crystalline-smog.png differ diff --git a/assets/sprites/bullet/dual-spike.aseprite b/assets/sprites/bullet/dual-spike.aseprite new file mode 100644 index 0000000..dfbf661 Binary files /dev/null and b/assets/sprites/bullet/dual-spike.aseprite differ diff --git a/assets/sprites/bullet/dual-spike.png b/assets/sprites/bullet/dual-spike.png new file mode 100644 index 0000000..34de25b Binary files /dev/null and b/assets/sprites/bullet/dual-spike.png differ diff --git a/assets/sprites/bullet/thorn-back.png b/assets/sprites/bullet/thorn-back.png new file mode 100644 index 0000000..57cdc89 Binary files /dev/null and b/assets/sprites/bullet/thorn-back.png differ diff --git a/assets/sprites/bullet/thorn.aseprite b/assets/sprites/bullet/thorn.aseprite new file mode 100644 index 0000000..1152fb7 Binary files /dev/null and b/assets/sprites/bullet/thorn.aseprite differ diff --git a/assets/sprites/bullet/thorn.png b/assets/sprites/bullet/thorn.png new file mode 100644 index 0000000..04f4391 Binary files /dev/null and b/assets/sprites/bullet/thorn.png differ diff --git a/assets/sprites/effect/sparkle.aseprite b/assets/sprites/effect/sparkle.aseprite deleted file mode 100644 index d2245d8..0000000 Binary files a/assets/sprites/effect/sparkle.aseprite and /dev/null differ diff --git a/assets/sprites/effects/chain.aseprite b/assets/sprites/effects/chain.aseprite index 6abb0be..570ec24 100644 Binary files a/assets/sprites/effects/chain.aseprite and b/assets/sprites/effects/chain.aseprite differ diff --git a/assets/sprites/effects/chain.png b/assets/sprites/effects/chain.png index 257f6b0..ad9274d 100644 Binary files a/assets/sprites/effects/chain.png and b/assets/sprites/effects/chain.png differ diff --git a/assets/sprites/liquids/storming-aspect.png b/assets/sprites/liquids/storming-aspect.png new file mode 100644 index 0000000..eb1b314 Binary files /dev/null and b/assets/sprites/liquids/storming-aspect.png differ diff --git a/assets/sprites/liquids/thundering-aether.png b/assets/sprites/liquids/thundering-aether.png new file mode 100644 index 0000000..b2b024a Binary files /dev/null and b/assets/sprites/liquids/thundering-aether.png differ diff --git a/assets/sprites/units/meld/afraig-joint.png b/assets/sprites/units/meld/afraig/afraig-joint.png similarity index 100% rename from assets/sprites/units/meld/afraig-joint.png rename to assets/sprites/units/meld/afraig/afraig-joint.png diff --git a/assets/sprites/units/meld/afraig-leg.png b/assets/sprites/units/meld/afraig/afraig-leg.png similarity index 100% rename from assets/sprites/units/meld/afraig-leg.png rename to assets/sprites/units/meld/afraig/afraig-leg.png diff --git a/assets/sprites/units/meld/afraig-spurter-cell.png b/assets/sprites/units/meld/afraig/afraig-spurter-cell.png similarity index 100% rename from assets/sprites/units/meld/afraig-spurter-cell.png rename to assets/sprites/units/meld/afraig/afraig-spurter-cell.png diff --git a/assets/sprites/units/meld/afraig-spurter.png b/assets/sprites/units/meld/afraig/afraig-spurter.png similarity index 100% rename from assets/sprites/units/meld/afraig-spurter.png rename to assets/sprites/units/meld/afraig/afraig-spurter.png diff --git a/assets/sprites/units/meld/afraig.png b/assets/sprites/units/meld/afraig/afraig.png similarity index 100% rename from assets/sprites/units/meld/afraig.png rename to assets/sprites/units/meld/afraig/afraig.png diff --git a/assets/sprites/units/meld/billa/billa-crystals-glow.png b/assets/sprites/units/meld/billa/billa-crystals-glow.png new file mode 100644 index 0000000..8d12b4a Binary files /dev/null and b/assets/sprites/units/meld/billa/billa-crystals-glow.png differ diff --git a/assets/sprites/units/meld/billa/billa-crystals.png b/assets/sprites/units/meld/billa/billa-crystals.png new file mode 100644 index 0000000..09d61f7 Binary files /dev/null and b/assets/sprites/units/meld/billa/billa-crystals.png differ diff --git a/assets/sprites/units/meld/billa/billa-joint.png b/assets/sprites/units/meld/billa/billa-joint.png new file mode 100644 index 0000000..546be1c Binary files /dev/null and b/assets/sprites/units/meld/billa/billa-joint.png differ diff --git a/assets/sprites/units/meld/billa/billa-leg-base.png b/assets/sprites/units/meld/billa/billa-leg-base.png new file mode 100644 index 0000000..d79773d Binary files /dev/null and b/assets/sprites/units/meld/billa/billa-leg-base.png differ diff --git a/assets/sprites/units/meld/billa/billa-leg.png b/assets/sprites/units/meld/billa/billa-leg.png new file mode 100644 index 0000000..0a070a4 Binary files /dev/null and b/assets/sprites/units/meld/billa/billa-leg.png differ diff --git a/assets/sprites/units/meld/billa/billa.png b/assets/sprites/units/meld/billa/billa.png new file mode 100644 index 0000000..808b6d2 Binary files /dev/null and b/assets/sprites/units/meld/billa/billa.png differ diff --git a/assets/sprites/units/meld/braig-cannon-cell.png b/assets/sprites/units/meld/braig/braig-cannon-cell.png similarity index 100% rename from assets/sprites/units/meld/braig-cannon-cell.png rename to assets/sprites/units/meld/braig/braig-cannon-cell.png diff --git a/assets/sprites/units/meld/braig-cannon.png b/assets/sprites/units/meld/braig/braig-cannon.png similarity index 100% rename from assets/sprites/units/meld/braig-cannon.png rename to assets/sprites/units/meld/braig/braig-cannon.png diff --git a/assets/sprites/units/meld/braig-leg-base.png b/assets/sprites/units/meld/braig/braig-leg-base.png similarity index 100% rename from assets/sprites/units/meld/braig-leg-base.png rename to assets/sprites/units/meld/braig/braig-leg-base.png diff --git a/assets/sprites/units/meld/braig-leg.png b/assets/sprites/units/meld/braig/braig-leg.png similarity index 100% rename from assets/sprites/units/meld/braig-leg.png rename to assets/sprites/units/meld/braig/braig-leg.png diff --git a/assets/sprites/units/meld/braig.png b/assets/sprites/units/meld/braig/braig.png similarity index 100% rename from assets/sprites/units/meld/braig.png rename to assets/sprites/units/meld/braig/braig.png diff --git a/assets/sprites/units/meld/craig-gun-cell.png b/assets/sprites/units/meld/craig/craig-gun-cell.png similarity index 100% rename from assets/sprites/units/meld/craig-gun-cell.png rename to assets/sprites/units/meld/craig/craig-gun-cell.png diff --git a/assets/sprites/units/meld/craig-gun.png b/assets/sprites/units/meld/craig/craig-gun.png similarity index 100% rename from assets/sprites/units/meld/craig-gun.png rename to assets/sprites/units/meld/craig/craig-gun.png diff --git a/assets/sprites/units/meld/craig-joint.png b/assets/sprites/units/meld/craig/craig-joint.png similarity index 100% rename from assets/sprites/units/meld/craig-joint.png rename to assets/sprites/units/meld/craig/craig-joint.png diff --git a/assets/sprites/units/meld/craig-leg.png b/assets/sprites/units/meld/craig/craig-leg.png similarity index 100% rename from assets/sprites/units/meld/craig-leg.png rename to assets/sprites/units/meld/craig/craig-leg.png diff --git a/assets/sprites/units/meld/craig.png b/assets/sprites/units/meld/craig/craig.png similarity index 100% rename from assets/sprites/units/meld/craig.png rename to assets/sprites/units/meld/craig/craig.png diff --git a/assets/sprites/units/meld/globkin-gun-blob.png b/assets/sprites/units/meld/globkin-gun-blob.png deleted file mode 100644 index fb9be7a..0000000 Binary files a/assets/sprites/units/meld/globkin-gun-blob.png and /dev/null differ diff --git a/assets/sprites/units/meld/jilla-segment0.png b/assets/sprites/units/meld/jilla/jilla-segment0.png similarity index 100% rename from assets/sprites/units/meld/jilla-segment0.png rename to assets/sprites/units/meld/jilla/jilla-segment0.png diff --git a/assets/sprites/units/meld/jilla-segment1.png b/assets/sprites/units/meld/jilla/jilla-segment1.png similarity index 100% rename from assets/sprites/units/meld/jilla-segment1.png rename to assets/sprites/units/meld/jilla/jilla-segment1.png diff --git a/assets/sprites/units/meld/jilla-segment2.png b/assets/sprites/units/meld/jilla/jilla-segment2.png similarity index 100% rename from assets/sprites/units/meld/jilla-segment2.png rename to assets/sprites/units/meld/jilla/jilla-segment2.png diff --git a/assets/sprites/units/meld/jilla.png b/assets/sprites/units/meld/jilla/jilla.png similarity index 100% rename from assets/sprites/units/meld/jilla.png rename to assets/sprites/units/meld/jilla/jilla.png diff --git a/assets/sprites/units/meld/kathid-base-joint.png b/assets/sprites/units/meld/kathid/kathid-base-joint.png similarity index 100% rename from assets/sprites/units/meld/kathid-base-joint.png rename to assets/sprites/units/meld/kathid/kathid-base-joint.png diff --git a/assets/sprites/units/meld/kathid-cell.png b/assets/sprites/units/meld/kathid/kathid-cell.png similarity index 100% rename from assets/sprites/units/meld/kathid-cell.png rename to assets/sprites/units/meld/kathid/kathid-cell.png diff --git a/assets/sprites/units/meld/kathid-crystal-heat.png b/assets/sprites/units/meld/kathid/kathid-crystal-heat.png similarity index 100% rename from assets/sprites/units/meld/kathid-crystal-heat.png rename to assets/sprites/units/meld/kathid/kathid-crystal-heat.png diff --git a/assets/sprites/units/meld/kathid-crystal.png b/assets/sprites/units/meld/kathid/kathid-crystal.png similarity index 100% rename from assets/sprites/units/meld/kathid-crystal.png rename to assets/sprites/units/meld/kathid/kathid-crystal.png diff --git a/assets/sprites/units/meld/kathid-joint.png b/assets/sprites/units/meld/kathid/kathid-joint.png similarity index 100% rename from assets/sprites/units/meld/kathid-joint.png rename to assets/sprites/units/meld/kathid/kathid-joint.png diff --git a/assets/sprites/units/meld/kathid-leg-base.png b/assets/sprites/units/meld/kathid/kathid-leg-base.png similarity index 100% rename from assets/sprites/units/meld/kathid-leg-base.png rename to assets/sprites/units/meld/kathid/kathid-leg-base.png diff --git a/assets/sprites/units/meld/kathid-leg.png b/assets/sprites/units/meld/kathid/kathid-leg.png similarity index 100% rename from assets/sprites/units/meld/kathid-leg.png rename to assets/sprites/units/meld/kathid/kathid-leg.png diff --git a/assets/sprites/units/meld/kathid.png b/assets/sprites/units/meld/kathid/kathid.png similarity index 100% rename from assets/sprites/units/meld/kathid.png rename to assets/sprites/units/meld/kathid/kathid.png diff --git a/assets/sprites/units/meld/pointago/pointago-foot.png b/assets/sprites/units/meld/pointago/pointago-foot.png new file mode 100644 index 0000000..99fcfae Binary files /dev/null and b/assets/sprites/units/meld/pointago/pointago-foot.png differ diff --git a/assets/sprites/units/meld/pointago/pointago-leg-base.png b/assets/sprites/units/meld/pointago/pointago-leg-base.png new file mode 100644 index 0000000..feeb45e Binary files /dev/null and b/assets/sprites/units/meld/pointago/pointago-leg-base.png differ diff --git a/assets/sprites/units/meld/pointago/pointago-leg.png b/assets/sprites/units/meld/pointago/pointago-leg.png new file mode 100644 index 0000000..ed9f9b4 Binary files /dev/null and b/assets/sprites/units/meld/pointago/pointago-leg.png differ diff --git a/assets/sprites/units/meld/pointago/pointago-sniper-barrel.png b/assets/sprites/units/meld/pointago/pointago-sniper-barrel.png new file mode 100644 index 0000000..d62d875 Binary files /dev/null and b/assets/sprites/units/meld/pointago/pointago-sniper-barrel.png differ diff --git a/assets/sprites/units/meld/pointago/pointago-sniper-full.png b/assets/sprites/units/meld/pointago/pointago-sniper-full.png new file mode 100644 index 0000000..a267a80 Binary files /dev/null and b/assets/sprites/units/meld/pointago/pointago-sniper-full.png differ diff --git a/assets/sprites/units/meld/pointago/pointago-sniper.png b/assets/sprites/units/meld/pointago/pointago-sniper.png new file mode 100644 index 0000000..cea1969 Binary files /dev/null and b/assets/sprites/units/meld/pointago/pointago-sniper.png differ diff --git a/assets/sprites/units/meld/pointago/pointago.png b/assets/sprites/units/meld/pointago/pointago.png new file mode 100644 index 0000000..f25895d Binary files /dev/null and b/assets/sprites/units/meld/pointago/pointago.png differ diff --git a/assets/sprites/units/meld/scorcher/scorcher-crystal-shine-heat.png b/assets/sprites/units/meld/scorcher/scorcher-crystal-shine-heat.png new file mode 100644 index 0000000..f6f6fb0 Binary files /dev/null and b/assets/sprites/units/meld/scorcher/scorcher-crystal-shine-heat.png differ diff --git a/assets/sprites/units/meld/scorcher/scorcher-crystal-shine.png b/assets/sprites/units/meld/scorcher/scorcher-crystal-shine.png new file mode 100644 index 0000000..bb00d5f Binary files /dev/null and b/assets/sprites/units/meld/scorcher/scorcher-crystal-shine.png differ diff --git a/assets/sprites/units/meld/scorcher/scorcher-crystal.png b/assets/sprites/units/meld/scorcher/scorcher-crystal.png new file mode 100644 index 0000000..ba84fbb Binary files /dev/null and b/assets/sprites/units/meld/scorcher/scorcher-crystal.png differ diff --git a/assets/sprites/units/meld/scorcher/scorcher-foot.png b/assets/sprites/units/meld/scorcher/scorcher-foot.png new file mode 100644 index 0000000..ed23461 Binary files /dev/null and b/assets/sprites/units/meld/scorcher/scorcher-foot.png differ diff --git a/assets/sprites/units/meld/scorcher/scorcher-joint.png b/assets/sprites/units/meld/scorcher/scorcher-joint.png new file mode 100644 index 0000000..9e20d4f Binary files /dev/null and b/assets/sprites/units/meld/scorcher/scorcher-joint.png differ diff --git a/assets/sprites/units/meld/scorcher/scorcher-leg.png b/assets/sprites/units/meld/scorcher/scorcher-leg.png new file mode 100644 index 0000000..fa35da6 Binary files /dev/null and b/assets/sprites/units/meld/scorcher/scorcher-leg.png differ diff --git a/assets/sprites/units/meld/scorcher/scorcher.png b/assets/sprites/units/meld/scorcher/scorcher.png new file mode 100644 index 0000000..8caba18 Binary files /dev/null and b/assets/sprites/units/meld/scorcher/scorcher.png differ diff --git a/mod.hjson b/mod.hjson index f78e66c..6ca2d3f 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 expirimental v1 +version: gameplay expirimental v3 #the minimum game build required to run this mod minGameVersion: 154 diff --git a/src/meld/Meld.java b/src/meld/Meld.java index 112f64a..c78ca77 100644 --- a/src/meld/Meld.java +++ b/src/meld/Meld.java @@ -2,6 +2,7 @@ import arc.*; import arc.graphics.Color; +import arc.graphics.Colors; import arc.math.geom.Geometry; import arc.math.geom.Point2; import arc.struct.IntSeq; @@ -10,24 +11,38 @@ import arc.util.Tmp; import meld.content.*; import meld.core.*; +import meld.entities.unit.abilities.BezerkAbility; +import meld.fluid.AspectGroup; +import meld.graphics.MeldRegions; +import meld.meta.MeldStatUnit; import mindustry.Vars; import mindustry.content.Blocks; +import mindustry.content.Bullets; import mindustry.content.Fx; +import mindustry.content.UnitTypes; +import mindustry.ctype.UnlockableContent; +import mindustry.game.EventType; import mindustry.game.EventType.*; import mindustry.mod.*; import mindustry.world.Tile; import mindustry.world.blocks.environment.Floor; +import mindustry.world.meta.Stat; +import mindustry.world.meta.StatUnit; import rhino.ImporterTopLevel; import rhino.NativeJavaPackage; + public class Meld extends Mod{ public static final String name = "meld"; public static NativeJavaPackage p = null; public static Melting melting; - + public Meld(){ + Events.on(EventType.ClientLoadEvent.class, e -> { + MeldRegions.load(); + }); } public static String prefix(String in){ @@ -69,7 +84,8 @@ public void init() { Seq packages = Seq.with( "meld", "meld.content", - "meld.world" + "meld.world", + "meld.fluid" ); packages.each(name -> { @@ -91,11 +107,22 @@ public void loadContent(){ MeldLiquids.load(); MeldBlocks.load(); MeldEnvironment.load(); + + //Just loads localised names + AspectGroup.loadAll(); + + Vars.content.items().each(c -> { + c.stats.add(Stat.buildCost, c.cost, MeldStatUnit.ticks); + }); Vars.content.blocks().each(b -> { if(b.minfo.mod != null && b.minfo.mod.name.equals("meld")){ b.deconstructDropAllLiquid = true; } }); + + Vars.content.liquids().each(l -> { + Colors.put(l.name, l.color); + }); } } diff --git a/src/meld/content/MeldBlocks.java b/src/meld/content/MeldBlocks.java index d31db7d..1bd4e98 100644 --- a/src/meld/content/MeldBlocks.java +++ b/src/meld/content/MeldBlocks.java @@ -1,13 +1,21 @@ package meld.content; +import arc.graphics.Blending; import arc.graphics.Color; +import arc.math.Angles; 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; import meld.world.blocks.crafting.RecipeCrafter; import meld.world.blocks.crafting.recipe.ItemRecipe; @@ -26,12 +34,16 @@ import mindustry.entities.bullet.*; import mindustry.entities.effect.MultiEffect; import mindustry.entities.effect.ParticleEffect; +import mindustry.entities.part.DrawPart; import mindustry.entities.part.HaloPart; import mindustry.entities.part.RegionPart; import mindustry.entities.part.ShapePart; import mindustry.entities.pattern.ShootAlternate; +import mindustry.entities.pattern.ShootBarrel; import mindustry.entities.pattern.ShootSpread; +import mindustry.gen.Bullet; import mindustry.gen.Sounds; +import mindustry.gen.Statusc; import mindustry.graphics.Layer; import mindustry.graphics.Pal; import mindustry.type.*; @@ -73,17 +85,21 @@ public class MeldBlocks { public static ModularCrafter gasKiln, rotaryKiln, pneumaticExtruder; - public static Block channelNode, channelFace, aspectOutlet, aspectChannel, channelDirector, channelVent, manualValve, intakeValve, valveController, pipebox; + public static Block channelNode, channelHub, channelFace, aspectOutlet, aspectChannel, channelDirector, channelVent, manualValve, intakeValve, valveController, pipebox; - public static Block sunder, molotov, vivisection; + public static Block sunder, shredstorm, molotov, vivisection; public static Block silverHusk, shadesteelShingles; //Meld blocks public static Block pipeline, pipelineRouter, pipelineCrossing, pipelineBridge, - meldCannon, meldMortar, - jillaCoffer, craigCoffer, braigCoffer, + + //More for areas outside glacier + meldCannon, meldMortar, meldNailgun, + jillaCoffer, billaCoffer, craigCoffer, braigCoffer, meldCultivator, meldNode, meldSuppressor, meldSynapse, + + //Mostly for glacier meldAmplifier, meldCapsule; public static Block crystalBarrier, crystalBarrierLarge, carbonicBarrier, carbonicBarrierLarge @@ -97,11 +113,13 @@ public static Item item(String name){ public static void load(){ + int channelHealth = 120; + channelFace = new FlexibleSizeJunction("channel-face"){{ requirements(Category.liquid, with( MeldItems.debris, 2 )); - health = 120; + health = channelHealth; solid = false; placeableLiquid = true; usePassedOffset = false; @@ -111,7 +129,7 @@ public static void load(){ requirements(Category.liquid, with( MeldItems.debris, 5 )); - health = 120; + health = channelHealth; liquidCapacity = 200; solid = false; @@ -119,13 +137,13 @@ public static void load(){ }}; aspectOutlet = new RecipeCrafter("aspect-outlet"){{ - outputDirections.putAll(MeldLiquids.aspect, new int[]{0}, MeldLiquids.boundAspect, new int[]{0}); + outputDirections.putAll(MeldLiquids.aspect, new int[]{0}, MeldLiquids.boundAspect, new int[]{0}, MeldLiquids.stormingAspect, new int[]{0}); requirements(Category.liquid, with( MeldItems.debris, 7 )); - health = 200; + health = channelHealth * 2; solid = false; hasLiquids = true; @@ -151,6 +169,8 @@ public static void load(){ //consumeLiquid(MeldLiquids.aether, outletRate/10); + + liquidCapacity = 100; inputLiquidSlots = 1; @@ -169,6 +189,13 @@ public static void load(){ float density = MeldLiquids.aetherDensities.get(MeldLiquids.pollutantMixture, 1); inputLiquids = LiquidStack.with(MeldLiquids.pollutantMixture, outletRate/density); outputLiquids = LiquidStack.with(MeldLiquids.boundAspect, outletRate * multi * 10); + }}, + new TimedRecipe(){{ + craftTime = 10; + float multi = MeldLiquids.aetherEfficiencies.get(MeldLiquids.thunderingAether, 1); + float density = MeldLiquids.aetherDensities.get(MeldLiquids.thunderingAether, 1); + inputLiquids = LiquidStack.with(MeldLiquids.thunderingAether, outletRate/density); + outputLiquids = LiquidStack.with(MeldLiquids.stormingAspect, outletRate * multi * 10); }} ); }}; @@ -177,8 +204,9 @@ public static void load(){ requirements(Category.liquid, with( MeldItems.annealedSilver, 5, MeldItems.glassMallows, 2 )); + underBullets = false; leaks = false; - health = 200; + health = channelHealth * 2; armor = 2; insulated = true; @@ -190,12 +218,21 @@ public static void load(){ junctionReplacement = channelFace; }}; + channelHub = new LiquidRouter("channel-hub"){{ + requirements(Category.liquid, with(MeldItems.debris, 80, MeldItems.shadesteel, 120)); + size = 4; + + health = channelHealth * 16; + armor = 8; + liquidCapacity = 100 * 100; + }}; + channelDirector = new ChannelDirector("channel-director"){{ requirements(Category.liquid, with( MeldItems.debris, 5 )); - health = 200; + health = channelHealth; placeableLiquid = true; liquidPressure = 0.5f; @@ -209,7 +246,7 @@ public static void load(){ requirements(Category.liquid, with( MeldItems.debris, 8 )); - health = 180; + health = channelHealth; armor = 1; minPressure = -0.25f; @@ -225,7 +262,7 @@ public static void load(){ MeldItems.debris, 8 )); - health = 120; + health = channelHealth; solid = false; placeableLiquid = true; @@ -238,7 +275,7 @@ public static void load(){ )); size = 3; - health = 800; + health = channelHealth * 10; armor = 8; solid = false; @@ -252,7 +289,7 @@ public static void load(){ )); size = 1; - health = 120; + health = channelHealth; solid = false; placeableLiquid = true; @@ -265,7 +302,7 @@ public static void load(){ )); size = 1; - health = 120; + health = channelHealth; solid = false; placeableLiquid = true; @@ -277,7 +314,7 @@ public static void load(){ MeldItems.carbolith, 60 )); size = 2; - health = 840; + health = 640; range = 200; fogRadiusMultiplier = 0.25f; @@ -325,78 +362,97 @@ public static void load(){ shots = 2; }}; - ammoTypes.put( + ammoTypes.putAll( MeldItems.debris, - new FlakBulletType(){{ - collidesGround = true; + MeldBullets.sunderDebris, + MeldItems.glassMallows, + MeldBullets.sunderGlass + ); + }}; - scaleLife = true; + shredstorm = new ItemTurret("shredstorm"){{ + requirements(Category.turret, with( + MeldItems.debris, 35, + MeldItems.silver, 50 + )); + size = 2; + health = 450; + range = 200; - speed = 6; - damage = 2; - lifetime = 30; - width = 3; - height = 8; - splashDamage = 10; - splashDamageRadius = 24; + fogRadiusMultiplier = 0.25f; + reload = 120; + shootEffect = Fx.shootBig; + shootWarmupSpeed = 0.25f; + minWarmup = 0.7f; - knockback = 1; + rotateSpeed = 15; - despawnEffect = Fx.none; - hitEffect = new MultiEffect( - new ParticleEffect(){{ - lifetime = 13; - particles = 3; - length = 15; - sizeFrom = 3; - sizeTo = 0; - sizeInterp = Interp.pow2In; - colorFrom = colorTo = MeldPal.shockwaveGray; - }}, - new ParticleEffect(){{ - lifetime = 9; - line = true; - particles = 2; - length = 24; - lenFrom = 4; - lenTo = 0; - strokeFrom = strokeTo = 2; - - interp = Interp.pow2Out; - sizeInterp = Interp.pow2In; - colorFrom = colorTo = MeldPal.sparkOrange; - }} - ); - - fragOnAbsorb = false; - shrinkY = 0.2f; - fragRandomSpread = 25; - - fragBullets = 5; - fragBullet = new BasicBulletType(){{ - lightRadius = 0; - speed = 8; - lifetime = 20; - - shrinkY = 1; - shrinkX = 1; - shrinkInterp = Interp.pow5In; - - sticky = true; - stickyExtraLifetime = 60; - pierce = true; - pierceCap = 2; - damage = 3; - splashDamage = 1; - splashDamageRadius = 2; + velocityRnd = 0.3f; + recoil = 1.5f; + shootCone = 25; + + shootSound = Sounds.shootFuse; + + rotate = quickRotate = false; + + shoot = new ShootBarrel(){{ + shotDelay = 0; + shots = 7; + + float[] spreadCone = new float[]{0, 3, 6, 15}; + barrels = new float[]{ + 0, 0, spreadCone[0], + 0, 0, -spreadCone[2], + 0, 0, spreadCone[1], + 0, 0, -spreadCone[1], + 0, 0, spreadCone[3], + 0, 0, spreadCone[2], + 0, 0, -spreadCone[3] + }; + }}; - width = 3; - height = 8; + inaccuracy = 2; + + shootY = 7; + + ammoPerShot = 4; + maxAmmo = 16; + + drawer = new DrawTurret(){{ + parts.addAll( + new RegionPart("-plate"){{ + progress = PartProgress.warmup; + mirror = true; + under = false; + moveX = 1; + moveY = -2.55f; + moveRot = -15; + }}, + new RegionPart("-plate"){{ + progress = PartProgress.warmup; + mirror = true; + under = false; + moveX = -1; + moveY = -3.55f; + moveRot = 15; + }}, + new RegionPart("-barrel"){{ + progress = PartProgress.warmup; + moveY = 1; + under = true; + + moves.addAll( + new PartMove(PartProgress.recoil, 0, -1.25f, 0) + ); + }} + ); + }}; + + ammoTypes.putAll( + MeldItems.debris, MeldBullets.shredDebris, + MeldItems.silver, MeldBullets.shredSilver, + MeldItems.annealedSilver, MeldBullets.shredSilver - collidesGround = true; - hitEffect = despawnEffect = Fx.none; - }}; - }} ); }}; @@ -427,11 +483,13 @@ public static void load(){ shootCone = 5; BulletType molBullet = new OutflowBulletType(){{ + layer = Layer.bullet + 1; //HHJKGHJGJK. - collidesTiles = false; - collides = false; + collidesTiles = true; + collides = true; collidesAir = false; scaleLife = true; + hitShake = 1.0F; hitSound = Sounds.explosionArtillery; hitEffect = Fx.flakExplosion; @@ -442,9 +500,10 @@ public static void load(){ trailEffect = Fx.artilleryTrail; trailChance = 0.35f; - speed = 7; + trailLength = 8; + speed = 3.5f; damage = 1; - lifetime = 46; + lifetime = 46 * 2; width = 18; height = 24; status = MeldStatusEffects.aspectBurn; @@ -452,10 +511,9 @@ public static void load(){ frontColor = Color.white; backColor = Color.valueOf("cbdbfc"); - splashDamage = 4; - splashDamageRadius = 8; + splashDamage = 40; + splashDamageRadius = 43; - collidesTiles = false; makeFire = true; hitShake = 2.5f; @@ -470,7 +528,7 @@ public static void load(){ fragRandomSpread = 360; - outflowBullet = new ExplosionBulletType(){{ + outflowBullet = new TransitionBulletType(){{ hitEffect = despawnEffect = Fx.none; damage = splashDamage = 0; fragBullets = 3; @@ -568,18 +626,358 @@ public static void load(){ molBullet ); - consume(new ConsumeAspects(outletRate, MeldLiquids.aspectEfficiencies, MeldLiquids.aspectDensities)); + consume( + new ConsumeAspects(outletRate, MeldLiquids.aspectEfficiencies, MeldLiquids.aspectDensities) + ); + }}; + + vivisection = new ItemTurret("vivisection"){{ + requirements(Category.turret, with(MeldItems.debris, 200, MeldItems.silver, 320, MeldItems.resonarum, 60)); + size = 4; + health = 2640; + range = 252; + + liquidCapacity = outletRate * 60 * 4; + fogRadiusMultiplier = 0.25f; + reload = 120; + + shootEffect = Fx.shootBig; + shootWarmupSpeed = 0.09f; + minWarmup = 0.7f; + + velocityRnd = 0.2f; + recoil = 1.5f; + inaccuracy = 2; + shootCone = 5; + + ammoPerShot = 12; + shootY = 8; + + rotate = quickRotate = false; + + shoot = new ShootSpread(){{ + shots = 1; + firstShotDelay = 60; + }}; + + consume(new ConsumeAspects(outletRate * 3, MeldLiquids.aspectEfficiencies, MeldLiquids.aspectDensities)); + + drawer = new DrawTurret(){{ + + parts.addAll( + new RegionPart("-jaw"){{ + mirror = true; + x = 4.5f; + y = 2; + moveRot = 180; + progress = PartProgress.charge.compress(0, 0.5f); + moves.add( + new PartMove(PartProgress.charge.compress(0.5f, 1).curve(Interp.pow2In),-0.75f, 0.5f, 0)); + }} + ); + + //Define the centers for the center of rotation and starting point + Vec2 center = new Vec2(4.5f, 2); + + //Start offset should be endpoint mirrored across the center + Vec2 startOffset = new Vec2(4, -20).scl(0.25f); + Vec2 endOffset = new Vec2(-18, 20).scl(0.25f); + float toMove = Angles.backwardDistance(startOffset.angle(), endOffset.angle()); + + float startRad = startOffset.len(); + float endRad = endOffset.len(); + + //Trust me the constant has a reason for it + DrawPart.PartProgress base = DrawPart.PartProgress.charge.compress(0, 0.5f); + DrawPart.PartMove SPINNNNNNNNBABYYYSPINSPINBABYYEEEEEEEEEE = + new DrawPart.PartMove(){{ + rot = 360 * 5; + progress = DrawPart.PartProgress.charge.compress(0.6f, 1).curve(Interp.pow5In); + }}; + for(int i = 0; i < 2; i++){ + int sign = i == 0 ? 1 : -1; + parts.add( + new RegionPart(){{ + mirror = false; + name = Meld.prefix("sawblade-large" + (sign == 1 ? "-r" : "-l")); + clampProgress = false; + + //Starting pos for the sawblades + x = center.x * sign; + y = center.y; + + moveX = moveY = 0; + growX = growY = 1; + xScl = yScl = 0; + growProgress = PartProgress.charge.compress(0, 0.5f).curve(Interp.pow2In); + + moves.addAll( + new PartMove(){{ + x = sign; + progress = p -> { + //Go from a clockwise starting position to a counterclockwise position + Tmp.v1.trns(Angles.moveToward(startOffset.angle(), endOffset.angle(), -toMove * base.get(p)), Mathf.lerp(startRad, endRad, base.get(p))); + return Tmp.v1.x; + }; + }}, + new PartMove(){{ + y = 1; + progress = p -> { + //counterclockwise rotation from start till end + Tmp.v1.trns(Angles.moveToward(startOffset.angle(), endOffset.angle(), -toMove * base.get(p)), Mathf.lerp(startRad, endRad, base.get(p))); + return Tmp.v1.y; + }; + }}, + new PartMove(){{ + rot = -180 * sign; + progress = base.inv(); + }}, + SPINNNNNNNNBABYYYSPINSPINBABYYEEEEEEEEEE + ); + }} + ); + } + + parts.addAll( + new RegionPart(){{ + name = Meld.prefix("sawblade-large-glow"); + x = 0; + y = 9; + blending = Blending.additive; + color = Color.white.cpy().a(0); + colorTo = Color.valueOf("6ed88e"); + progress = PartProgress.charge.compress(0.5f, 1).curve(Interp.pow2Out).slope(); + outline = false; + moves.addAll( + SPINNNNNNNNBABYYYSPINSPINBABYYEEEEEEEEEE + ); + }}, + new RegionPart("-plate"){{ + mirror = true; + moveX = 0.5f; + moveY = -0.5f; + moveRot = 10; + progress = PartProgress.warmup; + + moves.addAll( + new PartMove(PartProgress.recoil,1.25f, -1.25f, 15), + new PartMove(PartProgress.charge.compress(0.5f, 1).curve(Interp.pow2In),-0.75f, 0, 25) + ); + }}, + new RegionPart("-body"){{ + progress = PartProgress.charge.compress(0.75f, 1).curve(Interp.pow5In); + moveY = 0.75f; + children.addAll( + new RegionPart("-body-glow"){{ + blending = Blending.additive; + outline = false; + color = Pal.turretHeat; + colorTo = Color.valueOf("6ed88e"); + progress = PartProgress.charge.compress(0.5f, 1).curve(Interp.pow5In); + }} + ); + }} + ); + }}; + + ammoTypes.putAll( + MeldItems.resonarum, + new BasicBulletType(5, 160, Meld.prefix("sawblade-large")){{ + frontColor = Color.white; + backColor = Color.clear; + pierce = true; + pierceCap = 5; + pierceDamageFactor = 0.05f; + lifetime = 52; + knockback = 120; + impact = true; + spin = 300; + width = height = 24 * 2; + hitShake = 10.75f; + shrinkInterp = Interp.pow10In; + shrinkX = shrinkY = 0; + ammoMultiplier = 1; + + hitEffect = new ParticleEffect(){{ + lifetime = 15; + line = true; + lenTo = 8; + strokeFrom = 2; + strokeTo = 0.5f; + interp = Interp.pow5Out; + sizeInterp = Interp.pow5Out; + baseRotation = 25; + cone = 35; + colorFrom = Color.valueOf("85c799"); + colorTo = Color.valueOf("4bb66b"); + }}; + despawnEffect = Fx.none; + intervalBullet = new ExplosionBulletType(){{ + killShooter = false; + fragBullets = 2; + fragRandomSpread = 15; + fragSpread = 35; + fragAngle = 180; + fragVelocityMin = 0.5f; + fragVelocityMax = 1; + fragBullet = new BulletType(){{ + spawnBullets.addAll( + new TransitionBulletType(){{ + fragVelocityMin = 1; + fragBullets = 1; + fragBullet = new BulletType(2.5f, 5) {{ + + drag = 0.2f; + hitEffect = despawnEffect = Fx.none; + lifetime = 30; + bulletInterval = 5; + intervalBullets = 1; + lightRadius = 0; + parts.addAll( + new RegionPart() {{ + name = Meld.prefix("crystalline-smog"); + outline = false; + color = Color.white.cpy().a(0f); + colorTo = Color.white.cpy().a(0.1f); + progress = PartProgress.life.curve(Interp.slope); + moveRot = 360; + blending = Blending.additive; + layer = Layer.flyingUnitLow; + + xScl = yScl = 0.5f; + growX = growY = 0.5f; + growProgress = PartProgress.life.compress(0, 1).curve(Interp.pow2In); + }} + ); + + intervalBullet = new TransitionBulletType() {{ + fragBullets = 2; + fragVelocityMin = 0.5f; + fragVelocityMax = 1; + + fragBullet = new BasicBulletType(4.2f, 2, Meld.prefix("dual-spike")) { + @Override + public void update(Bullet b){ + if(b.stickyTarget instanceof Statusc s){ + s.apply(MeldStatusEffects.lacerated, 60); + } + } + { + width = 6; + height = 2; + frontColor = MeldPal.resoShardFront; + backColor = MeldPal.resoShardBack; + drag = 0.15f; + lifetime = 30; + + splashDamage = 5; + splashDamageRadius = 8; + hittable = false; + spin = 15; + hitEffect = despawnEffect = Fx.none; + status = MeldStatusEffects.lacerated; + statusDuration = 20; + sticky = true; + stickyExtraLifetime = 60; + + lightRadius = 0; + + float xScale = width / 20f; + float yScale = height / 20; + + parts.addAll( + new RegionPart() {{ + name = Meld.prefix("dual-spike"); + outline = false; + rotation = 60; + xScl = xScale; + yScl = yScale; + moveRot = 15 * 60; + progress = PartProgress.life; + + growX = -xScale; + growY = -yScale; + growProgress = PartProgress.life.curve(Interp.pow2In); + }}, + new RegionPart() {{ + name = Meld.prefix("dual-spike"); + outline = false; + rotation = 120; + xScl = xScale; + yScl = yScale; + moveRot = 7.5f * 60; + progress = PartProgress.life; + color = MeldPal.resoShardBack; + + growX = -xScale; + growY = -yScale; + growProgress = PartProgress.life.curve(Interp.pow5In); + }} + ); + }}; + }}; + }}; + }} + ); + damage = 5; + speed = 1.5f; + drag = 0.15f; + lifetime = 120; + homingPower = 0.05f; + frontColor = Color.valueOf("85c799"); + pierce = true; + status = MeldStatusEffects.lacerated; + statusDuration = 15; + hitEffect = Fx.none; + despawnEffect = Fx.none; + absorbable = hittable = reflectable = false; + parts.addAll( + new RegionPart(){{ + name = Meld.prefix("crystalline-smog"); + outline = false; + color = Color.clear; + colorTo = Color.white.cpy().a(1f); + progress = PartProgress.life.compress(0, 0.65f).curve(Interp.pow5Out).curve(Interp.slope); + moveRot = 360; + blending = Blending.additive; + + growX = growY = 2; + growProgress = PartProgress.life.compress(0, 0.65f).curve(Interp.pow2In); + }}, + //less glowey layer + new RegionPart(){{ + name = Meld.prefix("crystalline-smog"); + outline = false; + color = Color.clear; + colorTo = Color.white.cpy().a(0.6f); + progress = PartProgress.life.curve(Interp.pow5Out).curve(Interp.slope); + moveRot = 180 * 1.5f; + layer = Layer.flyingUnitLow; + + growX = growY = 4; + growProgress = PartProgress.life.compress(0, 0.8f).curve(Interp.pow2Out); + }} + ); + }}; + }}; + bulletInterval = 4; + intervalBullets = 1; + intervalSpread = 120; + intervalRandomSpread = 15; + }} + ); }}; shadesteelShingles = new Wall("shadesteel-shingles"){{ requirements(Category.defense, with(MeldItems.shadesteel, 64)); size = 2; - health = 2400; + health = 2000; + buildCostMultiplier = 2f; }}; silverHusk = new RegenProjector("silver-husk"){{ - requirements(Category.defense, with(MeldItems.debris, 15, MeldItems.annealedSilver, 8)); - health = 600; + requirements(Category.defense, with(MeldItems.debris, 15, MeldItems.annealedSilver, 16)); + health = 450; armor = 3; range = 1; healPercent = 0.05f; @@ -604,8 +1002,7 @@ public static void load(){ coreRaft = new CoreRaft("core-raft"){ { requirements(Category.effect, with( - MeldItems.debris, 600, - MeldItems.carbolith, 350 + MeldItems.debris, 900 )); size = 3; health = 4000; @@ -615,7 +1012,7 @@ public static void load(){ unitCapModifier = 6; unitType = MeldUnits.bulbhead; - solid = false; + solid = true; }}; aetherAccumulator = new AttributeCrafter("aether-accumulator"){{ @@ -861,7 +1258,7 @@ public static void load(){ }}; rotaryKiln = new ModularCrafter("rotary-kiln"){{ - requirements(Category.crafting, with(MeldItems.debris, 250, MeldItems.cruciblePlating, 150)); + requirements(Category.crafting, with(MeldItems.debris, 350, MeldItems.cruciblePlating, 150)); size = 5; hasItems = true; @@ -964,7 +1361,7 @@ public static void load(){ }}; pneumaticExtruder = new ModularCrafter("pneumatic-extruder"){{ - requirements(Category.crafting, with(MeldItems.debris, 60, MeldItems.cruciblePlating, 40)); + requirements(Category.crafting, with(MeldItems.debris, 120)); size = 3; hasItems = true; @@ -974,12 +1371,13 @@ public static void load(){ itemCapacity = 10; acceptedLiquids.addAll(MeldLiquids.aspect, MeldLiquids.boundAspect); - acceptedItems.addAll(MeldItems.shadesteel, MeldItems.elnarDust, MeldItems.debris, MeldItems.annealedSilver); + 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, 2), with(MeldItems.aspectPipe, 4)), - aspectPipe2 = new ItemRecipe(with(MeldItems.debris, 1, MeldItems.annealedSilver, 2), with(MeldItems.aspectPipe, 4)); + 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));; float produceTime = 30; @@ -990,29 +1388,38 @@ public static void load(){ 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 < 2; i++){ + 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.TWO, a); + b.setPin(ModOUT.THREE, a); }; }}, - new ConsumeLiquidModule(LiquidStack.with(MeldLiquids.aspect, outletRate * 2), ModIN.TWO, ModOUT.THREE), + new ConsumeLiquidModule(LiquidStack.with(MeldLiquids.aspect, outletRate * 2), ModIN.THREE, ModOUT.FOUR), new RecipeCraftingModule(){{ recipe = aspectPipe1; - efficiencyPins = new int[]{ModIN.THREE, ModIN.ZERO}; + efficiencyPins = new int[]{ModIN.FOUR, ModIN.ZERO}; progressPin = ModOUT.FOUR; craftTime = produceTime; }}, new RecipeCraftingModule(){{ recipe = aspectPipe2; - efficiencyPins = new int[]{ModIN.THREE, ModIN.ONE}; + efficiencyPins = new int[]{ModIN.FOUR, ModIN.ONE}; progressPin = ModOUT.FIVE; craftTime = produceTime; + }}, + new RecipeCraftingModule(){{ + recipe = aspectPipe3; + efficiencyPins = new int[]{ModIN.FOUR, ModIN.TWO}; + progressPin = ModOUT.SIX; + craftTime = produceTime; }} ); }}; @@ -1023,7 +1430,9 @@ public static void load(){ health = 2500; consume(new ConsumeLiquid(MeldLiquids.aspect, outletRate * 12)); - plans.addAll(new UnitPlan(MeldUnits.shark, 60 * 5, with(MeldItems.silver, 80, MeldItems.carbolith, 60))); + plans.addAll( + new UnitPlan(MeldUnits.shark, 60 * 5, with(MeldItems.silver, 80, MeldItems.carbolith, 60)) + ); }}; sonarSpire = new SonarSpire("sonar-spire"){{ @@ -1045,7 +1454,7 @@ public static void load(){ liquidCapacity = 1 * outletRate * 60; hasLiquids = true; - consume(new ConsumeAspects(outletRate * 2, MeldLiquids.aspectEfficiencies, MeldLiquids.aspectDensities)); + consume(new StupidConsumeAspects(outletRate * 2, AspectGroup.aspect)); }}; movementAnchor = new MovementAnchor("movement-anchor"){{ @@ -1080,7 +1489,7 @@ public static void load(){ size = 2; consume( - new ConsumeLiquid(MeldLiquids.fumes, 0.5f) + new StupidConsumeAspects(0.5f, AspectGroup.fumes) ); }}; @@ -1099,7 +1508,7 @@ public static void load(){ new SpoolRecipe(new ItemStack(MeldItems.resonarum, 2), 200) ); - consumeLiquid(MeldLiquids.fumes, 1f); + consume(new StupidConsumeAspects(1f, AspectGroup.fumes)); consumeItem(MeldItems.resonarum, 2); }}; @@ -1135,9 +1544,11 @@ public static void load(){ requirements(Category.distribution, with(MeldItems.debris, 450)); size = 3; health = 900; + armor = 30; + speed = 1f; - solid = false; + solid = true; }}; chuteJunction = new DuctJunction("chute-crossing"){{ @@ -1405,6 +1816,8 @@ public static void load(){ splashDamage = 25; splashDamageRadius = 16; + buildingDamageMultiplier = 2; + status = MeldStatusEffects.interference; statusDuration = 90; @@ -1455,10 +1868,11 @@ public static void load(){ }}; jillaCoffer = new Wall("jilla-coffer"){{ + requirements(Category.defense, with(MeldItems.larvalPlating, 50, MeldItems.meldShard, 35)); size = 2; health = 400; destroyBulletSameTeam = true; - destroyBullet = new ExplosionBulletType(){{ + destroyBullet = new TransitionBulletType(){{ hitEffect = despawnEffect = Fx.none; fragBullets = 3; fragBullet = new BulletType(){{ @@ -1467,7 +1881,25 @@ public static void load(){ }}; }}; + billaCoffer = new Wall("billa-coffer"){{ + requirements(Category.defense, with(MeldItems.larvalPlating, 50, MeldItems.meldShard, 35)); + size = 2; + health = 400; + armor = 80; + destroyBulletSameTeam = true; + + //TODO: WTF is the purpose of this... + destroyBullet = new TransitionBulletType(){{ + hitEffect = despawnEffect = Fx.none; + fragBullets = 1; + fragBullet = new BulletType(){{ + spawnUnit = MeldUnits.billa; + }}; + }}; + }}; + craigCoffer = new LiquidTurret("craig-coffer"){{ + requirements(Category.defense, with(MeldItems.larvalPlating, 50, MeldItems.meldShard, 35)); size = 2; health = 400; destroyBulletSameTeam = true; @@ -1506,6 +1938,7 @@ public static void load(){ }}; braigCoffer = new LiquidTurret("braig-coffer"){{ + requirements(Category.defense, with(MeldItems.larvalPlating, 200, MeldItems.meldShard, 120)); size = 3; health = 1200; destroyBulletSameTeam = true; @@ -1547,9 +1980,10 @@ public static void load(){ height = 14; pierce = true; + pierceBuilding = true; pierceCap = 2; - damage = 10; + splashDamage = 25; splashDamageRadius = 25; knockback = 4f; @@ -1557,6 +1991,26 @@ public static void load(){ hitEffect = despawnEffect = Fx.explosion; impact = true; + + fragBullets = 3; + fragRandomSpread = 45; + + fragBullet = new BasicBulletType(4, 15, Meld.prefix("clump")){{ + speed = 4; + lifetime = 10; + width = 3; + height = 8; + + pierce = true; + pierceBuilding = true; + pierceCap = 2; + + knockback = 4f; + + impact = true; + + hitEffect = despawnEffect = Fx.none; + }}; }} ); }}; diff --git a/src/meld/content/MeldBullets.java b/src/meld/content/MeldBullets.java index 84acab3..d42e747 100644 --- a/src/meld/content/MeldBullets.java +++ b/src/meld/content/MeldBullets.java @@ -1,19 +1,24 @@ package meld.content; +import arc.graphics.Color; import arc.math.Interp; import meld.Meld; +import meld.entities.bullet.RicochetBulletType; +import meld.entities.bullet.TransitionBulletType; +import meld.graphics.MeldPal; 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; +import mindustry.entities.bullet.*; +import mindustry.entities.effect.MultiEffect; +import mindustry.entities.effect.ParticleEffect; public class MeldBullets { public static BulletType - pulsarBlast, pulsarShrapnel; + pulsarBlast, pulsarShrapnel, + sunderDebris, sunderGlass, + shredDebris, shredSilver; public static void load(){ @@ -61,5 +66,243 @@ public static void load(){ killShooter = false; }}; + sunderDebris = new FlakBulletType(){{ + collidesGround = true; + + scaleLife = true; + + speed = 6; + damage = 2; + lifetime = 30; + width = 6; + height = 12; + splashDamage = 15; + splashDamageRadius = 24; + + knockback = 1; + + despawnEffect = Fx.none; + hitEffect = new MultiEffect( + new ParticleEffect(){{ + lifetime = 13; + particles = 3; + length = 15; + sizeFrom = 3; + sizeTo = 0; + sizeInterp = Interp.pow2In; + colorFrom = colorTo = MeldPal.shockwaveGray; + }}, + new ParticleEffect(){{ + lifetime = 9; + line = true; + particles = 2; + length = 24; + lenFrom = 4; + lenTo = 0; + strokeFrom = strokeTo = 2; + + interp = Interp.pow2Out; + sizeInterp = Interp.pow2In; + colorFrom = colorTo = MeldPal.sparkOrange; + }} + ); + + fragOnAbsorb = false; + shrinkY = 0.2f; + fragRandomSpread = 25; + + fragBullets = 5; + fragBullet = new BasicBulletType(8, 3){{ + lightRadius = 0; + lifetime = 20; + + shrinkY = 1; + shrinkX = 1; + shrinkInterp = Interp.pow5In; + + sticky = true; + stickyExtraLifetime = 60; + pierce = true; + pierceCap = 2; + splashDamage = 1; + splashDamageRadius = 2; + + width = 3; + height = 8; + + collidesGround = true; + hitEffect = despawnEffect = Fx.none; + }}; + }}; + + sunderGlass = new FlakBulletType(6, 1){{ + sprite = Meld.prefix("clump"); + + frontColor = MeldPal.glassMallowsFront; + backColor = MeldPal.glassMallowsBack; + collidesGround = true; + scaleLife = true; + + reloadMultiplier = 2; + rangeChange = -80; + + damage = 0.5f; + lifetime = 15; + width = 3; + height = 8; + + knockback = 1; + + despawnEffect = Fx.none; + hitEffect = new MultiEffect( + new ParticleEffect(){{ + lifetime = 9; + line = true; + particles = 2; + length = 24; + lenFrom = 4; + lenTo = 0; + strokeFrom = strokeTo = 2; + + interp = Interp.pow2Out; + sizeInterp = Interp.pow2In; + colorFrom = colorTo = MeldPal.sparkOrange; + }} + ); + + fragOnAbsorb = false; + shrinkY = 0.2f; + fragRandomSpread = 25; + + fragBullets = 5; + + fragBullet = new BasicBulletType(6, 8, Meld.prefix("clump")){{ + frontColor = MeldPal.glassMallowsFront; + backColor = MeldPal.glassMallowsBack; + lightRadius = 0; + speed = 8; + lifetime = 20; + + shrinkY = 1; + shrinkX = 1; + shrinkInterp = Interp.pow5In; + + sticky = true; + stickyExtraLifetime = 60; + splashDamage = 1; + splashDamageRadius = 2; + + width = 8; + height = 12; + + collidesGround = true; + hitEffect = despawnEffect = Fx.none; + }}; + }}; + + shredDebris = new BasicBulletType(){{ + damage = 2; + lifetime = 5; + speed = 12; + sprite = Meld.prefix("clump"); + width = 8; + height = 10; + shrinkY = 0; + + despawnHit = true; + + fragLifeMin = 0.6f; + ammoMultiplier = 2; + + fragRandomSpread = 5; + fragBullets = 3; + + fragBullet = new BasicBulletType(12, 1, Meld.prefix("clump")){{ + lifetime = 21; + drag = 0.01f; + width = 6; + height = 12; + shrinkX = 0.7f; + shrinkY = 0.2f; + + splashDamage = 1; + splashDamageRadius = 20; + knockback = 0.25f; + impact = true; + + hitEffect = Fx.none; + despawnEffect = Fx.none; + setDefaults = false; + despawnHit = false; + fragOnHit = true; + + pierce = true; + pierceCap = 2; + + fragBullets = 3; + fragRandomSpread = 60; + + bulletInterval = 2; + + fragBullet = new BasicBulletType(9, 2, Meld.prefix("clump")){{ + speed = 9; + damage = 0.5f; + lifetime = 8; + drag = 0.002f; + width = 1; + height = 6; + shrinkY = 0.2f; + shrinkX = 1; + + lightRadius = 0; + + hitEffect = Fx.none; + despawnEffect = Fx.none; + despawnHit = false; + + sticky = true; + stickyExtraLifetime = 60; + + status = MeldStatusEffects.impaled; + statusDuration = 5; + }}; + }}; + }}; + + shredSilver = new TransitionBulletType(){{ + + fragLifeMin = 0.8f; + ammoMultiplier = 2; + reloadMultiplier = 2f; + + fragRandomSpread = 5; + fragBullets = 1; + + fragBullet = new RicochetBulletType(8, 10, "shell"){{ + frontColor = Color.white; + backColor = MeldPal.aspect; + + lifetime = 40; + drag = 0.01f; + width = 8; + height = 8; + shrinkX = 1; + shrinkY = 1f; + shrinkInterp = Interp.pow10Out; + + lightRadius = 0; + + splashDamage = 5; + splashDamageRadius = 20; + + //For some reason impact + knockback on bouncy bullets doesn't work how I want it to... + knockback = 5; + + bounceEffect = Fx.none; + hitEffect = Fx.none; + despawnEffect = Fx.none; + setDefaults = false; + }}; + }}; } } diff --git a/src/meld/content/MeldEnvironment.java b/src/meld/content/MeldEnvironment.java index 2b878d1..15ccfbd 100644 --- a/src/meld/content/MeldEnvironment.java +++ b/src/meld/content/MeldEnvironment.java @@ -162,13 +162,13 @@ public static void load(){ }}; //Barrens + literallyCarbonStoneFromMindustryButSlightlyDifferent = new Floor("carbonic-stone", 4); + bedrock = new Floor("bedrock", 3); slate = new Floor("slate", 0); earthenStone = new Floor("earthen-stone", 4); carbonicPlates = new Floor("carbonic-plates", 3); - literallyCarbonStoneFromMindustryButSlightlyDifferent = new Floor("carbonic-stone", 4); - slate.blendGroup = bedrock; mixtureStone = new Floor("mixture-stone", 3); @@ -337,7 +337,7 @@ public static void load(){ }}; meldCluster = new WobbleProp("meld-cluster-small"){{ - requirements(Category.effect, ItemStack.with(MeldItems.debris, 40)); + requirements(Category.effect, ItemStack.with(MeldItems.debris, 50)); buildVisibility = BuildVisibility.sandboxOnly; @@ -347,7 +347,7 @@ public static void load(){ }}; meldClusterLarge = new AetherCluster("meld-cluster-large"){{ - requirements(Category.effect, ItemStack.with(MeldItems.debris, 150)); + requirements(Category.effect, ItemStack.with(MeldItems.debris, 300)); size = 3; buildVisibility = BuildVisibility.sandboxOnly; diff --git a/src/meld/content/MeldItems.java b/src/meld/content/MeldItems.java index b0d36ba..4a15505 100644 --- a/src/meld/content/MeldItems.java +++ b/src/meld/content/MeldItems.java @@ -1,5 +1,6 @@ package meld.content; +import arc.struct.Seq; import mindustry.type.Item; public class MeldItems { @@ -13,7 +14,7 @@ public class MeldItems { //Heavy industry content public static Item - tenbris, shadesteel, elnarDust, annealedSilver, glassMallows, cruciblePlating, aspectPipe; + tenbris, motis, shadesteel, elnarDust, annealedSilver, glassMallows, cruciblePlating, aspectPipe; public static void load(){ @@ -45,6 +46,10 @@ public static void load(){ }}; + motis = new Item("motis"){{ + + }}; + shadesteel = new Item("shadesteel"){{ }}; @@ -66,5 +71,8 @@ public static void load(){ cruciblePlating = new Item("crucible-plating"){{ }}; + + Seq heavyIndustry = Seq.with(tenbris, motis, shadesteel, elnarDust, annealedSilver, glassMallows, cruciblePlating, aspectPipe); + heavyIndustry.each(i -> i.databaseTag = "heavy-industry"); }; } diff --git a/src/meld/content/MeldLiquids.java b/src/meld/content/MeldLiquids.java index dc6e5d6..a8d130e 100644 --- a/src/meld/content/MeldLiquids.java +++ b/src/meld/content/MeldLiquids.java @@ -4,12 +4,17 @@ import arc.struct.ObjectFloatMap; import arc.struct.ObjectMap; import arc.struct.Seq; +import meld.fluid.Aspect; +import meld.fluid.AspectGroup; import mindustry.type.Liquid; +import static meld.fluid.AspectGroup.*; + public class MeldLiquids { - public static Liquid aether, aspect, meld, fumes, - pollutantMixture, boundAspect; + public static Aspect aether, aspect, meld, fumes, + pollutantMixture, boundAspect, + thunderingAether, stormingAspect; public static ObjectFloatMap aetherEfficiencies = new ObjectFloatMap<>(); public static ObjectFloatMap aetherDensities = new ObjectFloatMap<>(); @@ -24,68 +29,108 @@ public class MeldLiquids { public float outletRatio = 10; public static void load(){ - aether = new Liquid("aether"){{ + aether = new Aspect("aether"){{ gas = true; color = Color.valueOf("cb8650"); temperature = 0.6f; }}; - aspect = new Liquid("aspect"){{ + pollutantMixture = new Aspect("pollutant-mixture"){{ gas = true; - flammability = 1; - explosiveness = 2; - color = Color.valueOf("cbdbfc"); + color = Color.valueOf("6a634d"); temperature = 0.6f; }}; - meld = new Liquid("meld"){{ + thunderingAether = new Aspect("thundering-aether"){{ gas = true; - color = Color.valueOf("e4aad5"); + color = Color.valueOf("f99b76"); temperature = 0.6f; + explosiveness = 0.1f; }}; - fumes = new Liquid("fumes"){{ + aspect = new Aspect("aspect"){{ gas = true; - color = Color.valueOf("5b4739"); + flammability = 0.35f; + explosiveness = 1; + color = Color.valueOf("cbdbfc"); temperature = 0.6f; }}; - pollutantMixture = new Liquid("pollutant-mixture"){{ + stormingAspect = new Aspect("storming-aspect"){{ gas = true; - color = Color.valueOf("6a634d"); + color = Color.valueOf("aaadfd"); temperature = 0.6f; + flammability = 1; + explosiveness = 2; + }}; - boundAspect = new Liquid("bound-aspect"){{ + boundAspect = new Aspect("bound-aspect"){{ gas = true; color = Color.valueOf("d7a9ef"); temperature = 0.6f; }}; + meld = new Aspect("meld"){{ + gas = true; + color = Color.valueOf("e4aad5"); + temperature = 0.6f; + }}; + + fumes = new Aspect("fumes"){{ + gas = true; + color = Color.valueOf("5b4739"); + temperature = 0.6f; + }}; + + put(aether, AspectGroup.aether, new AspectStats(1, 1)); + put(pollutantMixture, AspectGroup.aether, new AspectStats(1, 0.5f)); + put(pollutantMixture, AspectGroup.aether, new AspectStats(1, 0.5f)); + put(thunderingAether, AspectGroup.aether, new AspectStats(2, 0.5f)); + + put(aspect, AspectGroup.aspect, new AspectStats(1, 1)); + put(boundAspect, AspectGroup.aspect, new AspectStats(1, 2)); + put(stormingAspect, AspectGroup.aspect, new AspectStats(2, 1)); + + put(fumes, AspectGroup.fumes, new AspectStats(1, 1)); + put(pollutantMixture, AspectGroup.fumes, new AspectStats(1, 0.5f)); + + outletMapping.putAll( + aether, aspect, + pollutantMixture, boundAspect, + thunderingAether, stormingAspect + ); aetherEfficiencies.put(aether, 1); aetherEfficiencies.put(pollutantMixture, 1); + aetherEfficiencies.put(thunderingAether, 2); aetherDensities.put(aether, 1); aetherDensities.put(pollutantMixture, 1/5f); + aetherDensities.put(thunderingAether, 0.5f); aspectEfficiencies.put(aspect, 1); aspectEfficiencies.put(boundAspect, 1); + aspectEfficiencies.put(stormingAspect, 2); aspectDensities.put(aspect, 1); aspectDensities.put(boundAspect, 2.5f); + aspectDensities.put(stormingAspect, 1f); - outletMapping.putAll( - aether, aspect, - pollutantMixture, boundAspect - ); + aether.databaseTag = pollutantMixture.databaseTag = thunderingAether.databaseTag = + aspect.databaseTag = boundAspect.databaseTag = stormingAspect.databaseTag = "aspect-powergen"; + meld.databaseTag = "aspect-omnipotence"; + fumes.databaseTag = "aspect-vita"; + + mapOutlet(aether, aspect); + mapOutlet(pollutantMixture, boundAspect); + mapOutlet(thunderingAether, stormingAspect); + } - Seq outletLiquids = Seq.with(aether, pollutantMixture); + public static void mapOutlet(Liquid input, Liquid output){ + outletMapping.putAll(input, output); - 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)); - }); + outletEfficiencies.put(input, aetherEfficiencies.get(input, 1) * aspectEfficiencies.get(output, 1)); + outletDensities.put(input, aetherDensities.get(input, 1) * aspectDensities.get(output, 1)); } } diff --git a/src/meld/content/MeldStatusEffects.java b/src/meld/content/MeldStatusEffects.java index dbad377..2c3d7fa 100644 --- a/src/meld/content/MeldStatusEffects.java +++ b/src/meld/content/MeldStatusEffects.java @@ -8,6 +8,8 @@ public class MeldStatusEffects { public static StatusEffect amplified, rally, anchored, aspectBurn, sentry, spurting, newborn, interference, drenched, stunned; + public static StatusEffect lacerated, impaled; + public static StatusEffect rush; public static void load(){ @@ -54,46 +56,54 @@ public void update(Unit unit, StatusEntry entry) { { speedMultiplier = 1.25f; reloadMultiplier = 2; - }}; - anchored = new StatusEffect("anchored"){ - + rush = new StatusEffect("rush"){ @Override public void update(Unit unit, StatusEntry entry) { unit.speedMultiplier /= speedMultiplier; - //Start the falloff at 150 ticks remaining + //Start the falloff at 180 ticks remaining unit.speedMultiplier *= Mathf.lerp( 1, speedMultiplier, - Interp.pow2.apply( - Mathf.clamp(Math.min(entry.time, 150)/(150)) + Interp.pow3.apply( + Mathf.clamp(Math.min(entry.time, 180)/(180)) ) ); } { - - speedMultiplier = 0.3f; - dragMultiplier = 3; + damage = -1; + healthMultiplier = 2; + speedMultiplier = 2; + disarm = true; }}; - aspectBurn = new StatusEffect("aspect-burn"){ - @Override - public void update(Unit unit, StatusEntry entry) { - super.update(unit, entry); - if(unit.armor > 0) unit.damageContinuousPierce(unit.armor/60); - } - { - damage = 0.1f; - healthMultiplier = 0.5f; - } - }; + anchored = new StatusEffect("anchored"){ + + @Override + public void update(Unit unit, StatusEntry entry) { + + unit.speedMultiplier /= speedMultiplier; + //Start the falloff at 150 ticks remaining + unit.speedMultiplier *= Mathf.lerp( + 1, speedMultiplier, + + Interp.pow2.apply( + Mathf.clamp(Math.min(entry.time, 150)/(150)) + ) + ); + } + { + + speedMultiplier = 0.3f; + dragMultiplier = 3; + }}; sentry = new StatusEffect("sentry"){{ damage = 0.1f; reloadMultiplier = 2; - speedMultiplier = 0.3f; + speedMultiplier = 0.15f; }}; spurting = new StatusEffect("spurting"){ @@ -110,6 +120,7 @@ public void update(Unit unit, StatusEntry entry) { ) ); }{ + damage = 0.2f; speedMultiplier = 0.01f; dragMultiplier = 0.3f; disarm = true; @@ -166,5 +177,33 @@ public void update(Unit unit, StatusEntry entry) { speedMultiplier = 0.5f; }}; + + //Only affects unarmored + lacerated = new StatusEffect("lacerated"){{ + damage = -0.2f; + speedMultiplier = 0.45f; + reloadMultiplier = 0.5f; + buildSpeedMultiplier = 0.5f; + }}; + + + //Only affects armored + aspectBurn = new StatusEffect("aspect-burn"){ + @Override + public void update(Unit unit, StatusEntry entry) { + super.update(unit, entry); + if(unit.armor > 0) unit.damageContinuousPierce(unit.armor/60); + } + { + damage = 0.1f; + healthMultiplier = 0.5f; + } + }; + + impaled = new StatusEffect("impaled"){{ + damage = 0.2f; + speedMultiplier = 0.45f; + buildSpeedMultiplier = 0.5f; + }}; } } diff --git a/src/meld/content/MeldUnits.java b/src/meld/content/MeldUnits.java index 3f134b2..0fed4bf 100644 --- a/src/meld/content/MeldUnits.java +++ b/src/meld/content/MeldUnits.java @@ -1,5 +1,6 @@ package meld.content; +import arc.func.Prov; import arc.graphics.Blending; import arc.graphics.Color; import arc.graphics.g2d.Draw; @@ -8,21 +9,25 @@ import arc.math.Angles; import arc.math.Interp; import arc.math.Mathf; +import arc.struct.ObjectIntMap; +import arc.util.Log; import arc.util.Tmp; import meld.*; import meld.entities.bullet.TransitionBulletType; +import meld.entities.unit.abilities.*; +import meld.entities.unit.weapons.template.BraigWeapon; +import meld.entities.unit.weapons.template.PointagoWeapon; import meld.graphics.part.*; import meld.entities.unit.*; import meld.entities.unit.type.*; import meld.graphics.*; -import meld.entities.unit.abilities.DeathBirthAbility; -import meld.entities.unit.abilities.SlipstreamHullAbility; -import meld.entities.unit.abilities.SolidSpeedAbility; import meld.entities.unit.weapons.DeathWeapon; import meld.entities.unit.weapons.ShadowVisualWeapon; import mindustry.Vars; import mindustry.ai.types.HugAI; +import mindustry.content.Blocks; import mindustry.content.Fx; +import mindustry.content.Items; import mindustry.content.StatusEffects; import mindustry.entities.Effect; import mindustry.entities.abilities.RegenAbility; @@ -32,15 +37,62 @@ import mindustry.entities.effect.ParticleEffect; import mindustry.entities.effect.WaveEffect; import mindustry.entities.part.*; +import mindustry.entities.pattern.ShootBarrel; import mindustry.entities.pattern.ShootSpread; import mindustry.gen.*; import mindustry.graphics.Layer; import mindustry.graphics.Pal; +import mindustry.type.StatusEffect; import mindustry.type.UnitType; import mindustry.type.Weapon; import mindustry.type.weapons.RepairBeamWeapon; +import arc.struct.ObjectMap.Entry; +import mindustry.world.blocks.defense.turrets.ItemTurret; public class MeldUnits { + + private static Entry, Prov>[] types = new Entry[]{ + prov(BulbheadEntity.class, BulbheadEntity::new) + }; + + private static ObjectIntMap> idMap = new ObjectIntMap<>(); + + /** + * Internal function to flatmap {@code Class -> Prov} into an {@link Entry}. + * @author GlennFolker + */ + + private static Entry, Prov> prov(Class type, Prov prov){ + Entry, Prov> entry = new Entry<>(); + entry.key = type; + entry.value = prov; + return entry; + } + + /** + * Setups all entity IDs and maps them into {@link EntityMapping}. + * Find all free ids to map to, then put the Entry(s) from types into the idMap. Starts searching after the last known index of a vanilla Entry + */ + + private static void setupID(){ + int start = 33; + int[] free = new int[types.length]; + for (int i = start, j = 0; i < EntityMapping.idMap.length; i++) { + if(EntityMapping.idMap[i] == null) free[j++] = i; + if(j > free.length - 1) break; + } + + Log.info("setting up map"); + for (int i = 0; i < free.length; i++) { + idMap.put(types[i].key, free[i]); + EntityMapping.idMap[free[i]] = types[i].value; + } + } + + public static int classID(Class type){ + return idMap.get(type, -1); + } + //player units public static UnitType bulbhead, shark, @@ -49,14 +101,17 @@ public class MeldUnits { //enemy units cannonOverseer, blob, - afraig, craig, braig, globkin, - jilla, kathid; + afraig, craig, braig, pointago, globkin, + jilla, billa, scorcher, kathid; public static void load(){ + setupID(); + bulbheadOverseer = new UnitType("bulbhead-overseer"){{ float IR = 80; health = 240; + armor = -40; lifetime = 360; speed = 0; flying = true; @@ -214,7 +269,7 @@ public static void load(){ drag = 0.15f; accel = 0.8f; - rotateSpeed = 7; + rotateSpeed = 9; trailLength = 18; trailScl = 1.2f; @@ -236,6 +291,11 @@ public static void load(){ mineRange = IR; fogRadius = IR/ Vars.tilesize; + canBoost = true; + boostMultiplier = 0.5f; + shadowElevation = 0; + shadowElevationScl = 0.5f; + weapons.add( new RepairBeamWeapon("meld-bulbhead-healer"){{ mirror = false; @@ -376,7 +436,7 @@ public static void load(){ color = Pal.accent; }} ); - constructor = UnitEdgeWaterMove::new; + constructor = BulbheadEntity::new; abilities.addAll( new RegenAbility(){{ @@ -392,6 +452,12 @@ public static void load(){ MeldStatusEffects.rally, MeldStatusEffects.drenched ); + + float ex = 34/4f, ey = 35/4f; + engines.add( + new MeldUnitType.ActivationEngine(ex, -ey, 3.2f, 315, 0.5f, 1, 0.5f, 1.5f), + new MeldUnitType.ActivationEngine(-ex, -ey, 3.2f, 225, 0.5f, 1, 0.5f, 1.5f) + ); }}; shark = new UnitType("shark"){{ @@ -424,12 +490,12 @@ public static void load(){ rotate = true; x = 0; y = -2; - reload = 90; + reload = 180; rotateSpeed = 3.5f; recoil = 1.25f; inaccuracy = 15; velocityRnd = 0.05f; - shoot.shots = 3; + shoot.shots = 5; shoot.shotDelay = 5; bullet = new MissileBulletType(){{ @@ -505,7 +571,7 @@ public static void load(){ shadowElevation = 0.1f; shadowElevationTo = 0.2f; layerOffset = -0.001f; - reload = 15; + reload = 30; parts.addAll( new AdjustableHoverPart(){{ x = 4; @@ -547,8 +613,8 @@ public static void load(){ //actually im gona make sharks faster on fluids cause like... fluids abilities.addAll( new SolidSpeedAbility(){{ - warmupSpeed = 2/60f; - speedMultiplier = 1/1.5f; + warmupSpeed = 0.05f; + speedMultiplier = 0.75f; }}, new SlipstreamHullAbility() ); @@ -885,9 +951,7 @@ public static void load(){ constructor = LegsUnit::create; }}; - craig = new UnitType("craig"){{ - outlineColor = Color.clear; - + craig = new MeldUnitType("craig"){{ speed = 0.9f; health = 320; drag = 0.12f; @@ -938,11 +1002,11 @@ public static void load(){ constructor = LegsUnit::create; }}; - braig = new UnitType("braig"){{ + braig = new MeldUnitType("braig"){{ outlineColor = Color.clear; speed = 0.8f; - health = 950; + health = 1200; drag = 0.12f; accel = 0.2f; @@ -967,7 +1031,7 @@ public static void load(){ weapons.addAll( craigWeapon(-6, 2), - braigWeapon(6, -3), + new BraigWeapon(6, -3), new DeathWeapon(){{ bullet = new ExplosionBulletType(250, 35){{ shootEffect = new MultiEffect( @@ -1066,6 +1130,62 @@ public static void load(){ constructor = LegsUnit::create; }}; + pointago = new MeldUnitType("pointago"){{ + speed = 0.8f; + + health = 1600; + + drag = 0.12f; + accel = 0.2f; + range = 40; + + hitSize = 26; + rotateSpeed = 6; + faceTarget = true; + + drawCell = false; + + legCount = 6; + legLength = 24; + + legBaseOffset = 12; + + lockLegBase = true; + legContinuousMove = true; + + legGroupSize = 2; + legExtension = 4; + legLengthScl = 0.9f; + legPairOffset = 5; + + legMoveSpace = 3; + allowLegStep = true; + legPhysicsLayer = false; + + weapons.addAll( + new PointagoWeapon(30f/4, 2){{ + rotateSpeed = 0.5f; + rotationLimit = 5; + shootCone = 180; + }}, + new PointagoWeapon(-36f/4, -11f/4){{ + rotateSpeed = 0.5f; + rotationLimit = 5; + shootCone = 180; + }} + ); + + abilities.addAll( + new BezerkAbility(){{ + deathBomb = MeldBullets.pulsarBlast; + bezerkTime = 30; + }} + ); + + immunities.addAll(MeldStatusEffects.aspectBurn); + constructor = LegsUnit::create; + }}; + globkin = new UnitType("globkin"){{ outlineColor = Color.clear; speed = 0.7f; @@ -1093,10 +1213,15 @@ public static void load(){ legContinuousMove = true; legPhysicsLayer = false; - Weapon backMount = braigWeapon(0.25f, -11); - backMount.shootStatus = StatusEffects.none; weapons.add( - backMount, + new BraigWeapon(0.25f, -11){{ + shootStatus = StatusEffects.none; + reload /= 2f; + controllable = aiControllable = false; + autoTarget = true; + targetSwitchInterval = 20; + targetInterval = 15; + }}, new Weapon(""){{ x = 16.25f; y = 4.25f; @@ -1128,6 +1253,36 @@ public static void load(){ fragRandomSpread = 45; recoil = 4.5f; rangeOverride = 160; + spawnBullets.addAll( + new TransitionBulletType(){{ + fragRandomSpread = 45; + recoil = 4.5f; + fragBullets = 12; + + fragBullet = new BasicBulletType(8.5f, 1.5f, "meld-clump"){{ + width = 5; + height = 9; + shrinkX = shrinkY = 1; + + splashDamage = 12; + splashDamageRadius = 25; + + status = MeldStatusEffects.stunned; + statusDuration = 35; + + pierce = true; + pierceCap = 2; + speed = 8.5f; + drag = 0.01f; + + lifetime = 45; + + knockback = 5.5f; + + keepVelocity = false; + }}; + }} + ); fragBullet = new ArtilleryBulletType(){{ width = 16; @@ -1193,6 +1348,7 @@ public static void load(){ }} ); + immunities.addAll(MeldStatusEffects.lacerated); constructor = LegsUnit::create; }}; @@ -1253,8 +1409,216 @@ public static void load(){ constructor = CrawlUnit::create; }}; - kathid = new UnitType("kathid"){{ - outlineColor = Color.clear; + billa = new MeldUnitType("billa"){{ + health = 450; + + armor = 120; + drag = 0.25f; + accel = 0.35f; + speed = 1.5f; + + hitSize = 32; + rotateSpeed = 8; + faceTarget = true; + + hovering = true; + + legCount = 6; + legLength = 60; + legMaxLength = 1; + legGroupSize = 2; + legSpeed = 1; + legForwardScl = 3; + legBaseOffset = 8; + drawCell = false; + legPhysicsLayer = true; + + deathExplosionEffect = Fx.none; + + weapons.add( + new Weapon(Meld.prefix("billa-crystals")){{ + x = y = 0; + mirror = alternate = rotate = false; + reload = 14; + + shootCone = 180; + recoil = 0; + + shootY = 12.5f; + continuous = alwaysContinuous = true; + shootSound = Sounds.shootSublimate; + + parts.addAll( + new RegionPart("-glow"){{ + outline = false; + progress = PartProgress.warmup; + color = Color.clear; + colorTo = Color.white; + blending = Blending.additive; + }} + ); + + shootStatus = MeldStatusEffects.sentry; + shootStatusDuration = 4; + + bullet = new ContinuousFlameBulletType(){{ + lifetime = 85; + damage = 13; + length = 75; + width = 1.5f; + knockback = 3; + pierceCap = 3; + flareLength = 0; + rangeOverride = 55; + recoil = 0.01f; + hitUnder = true; + + colors = new Color[]{ + Color.valueOf("f9e1f343"), + Color.valueOf("ee5de9a9"), + Color.valueOf("ef85e3e3"), + Color.valueOf("d22fee"), + Color.white + }; + }}; + }}, + new Weapon(){{ + alternate = rotate = false; + mirror = true; + reload = 14; + x = 10; + y = 3.75f; + baseRotation = -45; + + shootCone = 180; + recoil = 0; + + shootY = 0; + continuous = alwaysContinuous = true; + shootSound = Sounds.shootSublimate; + parts.addAll( + new RegionPart("-glow"){{ + outline = false; + progress = PartProgress.warmup; + color = Color.clear; + colorTo = Color.white; + blending = Blending.additive; + }} + ); + + shootStatus = MeldStatusEffects.sentry; + shootStatusDuration = 4; + + bullet = new ContinuousFlameBulletType(){{ + lifetime = 85; + damage = 10; + length = 75; + width = 0.5f; + knockback = 3; + pierceCap = 3; + flareLength = 0; + rangeOverride = 55; + recoil = 0.01f; + hitUnder = true; + + colors = new Color[]{ + Color.valueOf("f9e1f343"), + Color.valueOf("ee5de9a9"), + Color.valueOf("ef85e3e3"), + Color.valueOf("d22fee"), + Color.white + }; + }}; + }} + ); + + abilities.addAll( + new DeathBirthAbility(MeldUnits.jilla, 3), + new SpawnRushAbility() + ); + + constructor = LegsUnit::create; + }}; + + scorcher = new MeldUnitType("scorcher"){{ + speed = 0.4f; + + health = 200; + drownTimeMultiplier = 0.35f; + + drag = 0.08f; + accel = 0.15f; + range = 40; + + hitSize = 12; + rotateSpeed = 12; + faceTarget = true; + + legCount = 4; + legLength = 10; + legMaxLength = 1.2f; + legGroupSize = 2; + legSpeed = 1; + legForwardScl = 2; + legBaseOffset = -1f; + + drawCell = false; + legPhysicsLayer = false; + + + weapons.add( + new Weapon(Meld.prefix("scorcher-crystal")){{ + x = y = 0; + mirror = alternate = rotate = false; + reload = 14; + + shootCone = 15; + recoil = 0; + + shootY = 8; + continuous = alwaysContinuous = true; + shootSound = Sounds.shootSublimate; + parts.addAll( + //TODO: wtf is this naming + new RegionPart("-shine"){{ + outline = false; + progress = PartProgress.warmup; + color = Color.clear; + colorTo = Color.white; + blending = Blending.additive; + }} + ); + + shootStatus = MeldStatusEffects.sentry; + shootStatusDuration = 4; + + bullet = new ContinuousFlameBulletType(){{ + lifetime = 85; + damage = 13; + length = 35; + width = 3.5f; + knockback = 3; + pierceCap = 3; + flareLength = 8; + rangeOverride = 55; + recoil = -0.05f; + hitUnder = true; + + colors = new Color[]{ + Color.valueOf("f9e1f343"), + Color.valueOf("ee5de9a9"), + Color.valueOf("ef85e3e3"), + Color.valueOf("d22fee"), + Color.white + }; + }}; + }} + ); + + constructor = LegsUnit::create; + }}; + + kathid = new MeldUnitType("kathid"){{ shadowElevation = 0.1f; speed = 0.7f; @@ -1283,6 +1647,17 @@ public static void load(){ deathExplosionEffect = Fx.none; + parts.addAll( + new RegionPart(){{ + name = Meld.prefix("kathid-crystal-heat"); + progress = PartProgress.warmup; + color = Color.valueOf("11111100"); + colorTo = Color.valueOf("111111"); + blending = Blending.additive; + outline = false; + }} + ); + weapons.addAll( new Weapon(){{ x = y = 0; @@ -1293,13 +1668,14 @@ public static void load(){ shootCone = 10; shootStatus = MeldStatusEffects.sentry; - shootStatusDuration = 5; + shootStatusDuration = 25; shootSound = Sounds.shootSublimate; bullet = new ContinuousFlameBulletType(){{ + lifetime = 25; damage = 13; flareLength = 12; - length = 85; + length = 115; width = 1.7f; knockback = 1; pierceCap = 2; @@ -1311,21 +1687,10 @@ public static void load(){ Color.valueOf("d22fee"), Color.white }; - - parts.addAll( - new RegionPart(){{ - name = "kathid-crystal-heat"; - progress = PartProgress.warmup; - color = Color.valueOf("11111100"); - colorTo = Color.valueOf("111111"); - blending = Blending.additive; - outline = false; - }} - ); }}; }} ); - immunities.addAll(MeldStatusEffects.aspectBurn); + immunities.addAll(MeldStatusEffects.lacerated); constructor = LegsUnit::create; }}; @@ -1467,41 +1832,6 @@ public static Weapon afraigWeapon(float wx, float wy){ } public static Weapon braigWeapon(float wx, float wy){ - return new Weapon(Meld.prefix("braig-cannon")){{ - x = wx; - y = wy; - shootY = 5; - reload = 360; - shootCone = 60; - rotate = true; - mirror = false; - alternate = false; - parentizeEffects = false; - shootStatus = MeldStatusEffects.sentry; - shootStatusDuration = 180; - - shoot = new ShootSpread(){{ - shots = 3; - shotDelay = 7; - spread = 1; - }}; - - inaccuracy = 5; - - bullet = new BasicBulletType(){{ - sprite = Meld.prefix("clump"); - speed = 4; - lifetime = 75; - width = 10; - height = 12; - damage = 10; - splashDamage = 25; - splashDamageRadius = 25; - knockback = 6; - shootEffect = Fx.shootBig; - hitEffect = Fx.explosion; - impact = true; - }}; - }}; + return new BraigWeapon(wx, wy); } } diff --git a/src/meld/entities/bullet/OutflowBulletType.java b/src/meld/entities/bullet/OutflowBulletType.java index 6147eec..5a15d91 100644 --- a/src/meld/entities/bullet/OutflowBulletType.java +++ b/src/meld/entities/bullet/OutflowBulletType.java @@ -23,16 +23,11 @@ public void init() { } @Override - public void despawned(Bullet b) { - super.despawned(b); + public void createSplashDamage(Bullet b, float x, float y) { + super.createSplashDamage(b, x, y); outflow(b, b.x, b.y); } - @Override - public void hit(Bullet b) { - super.hit(b); - } - @Override public void createFrags(Bullet b, float x, float y) { super.createFrags(b, x, y); diff --git a/src/meld/entities/bullet/RicochetBulletType.java b/src/meld/entities/bullet/RicochetBulletType.java new file mode 100644 index 0000000..6e2d6c1 --- /dev/null +++ b/src/meld/entities/bullet/RicochetBulletType.java @@ -0,0 +1,172 @@ +package meld.entities.bullet; + +import arc.math.geom.Geometry; +import arc.math.geom.Intersector; +import arc.math.geom.Vec2; +import arc.util.Tmp; +import mindustry.Vars; +import mindustry.content.Fx; +import mindustry.entities.Effect; +import mindustry.entities.bullet.BasicBulletType; +import mindustry.gen.Building; +import mindustry.gen.Bullet; +import mindustry.gen.Hitboxc; +import mindustry.gen.Unit; + +public class RicochetBulletType extends BasicBulletType { + //how much of its velocity is kept on bounce + public float bounciness = 1; + //Cap for how many times it can bounce. Set to -1 to disable, 0 or null to stop bouncing. + public int bounceCap = -1; + public boolean bounceUnits, bounceBuildings; + //Effect displayed on bounce + public Effect bounceEffect = Fx.plasticExplosion; + + //Whether the bullet can bounce multiple times on the same entity + public boolean bounceSame = true; + + //how many ticks inbetween collisions being cleared. Set around 15/20 or lower to make bullet reliable in low fps. -1 to disable + public int bounceInternal = 2; + + public boolean useRange = true; + + public static class Bounces{ + public int bounceAmount = 0; + } + + public RicochetBulletType(float speed, float damage, String sprite) { + super(speed, damage, sprite); + this.speed = speed; + this.damage = damage; + this.pierceBuilding = this.pierce = this.bounceBuildings = this.bounceUnits = true; + this.trailWidth = width * 0.38f; + this.shrinkX = 0.8f; + } + + @Override + public void update(Bullet b){ + if(bounceSame && bounceInternal != -1 && b.timer.get(1, bounceInternal)){{ + b.collided.clear(); + }} + super.update(b); + RicochetBulletData data = (RicochetBulletData) b.data; + data.lastX = data.curX; + data.curX = b.x; + data.lastY = data.curY; + data.curY = b.y; + } + + @Override + public void init(Bullet b) { + super.init(b); + b.data = new RicochetBulletData(); + } + + @Override + public void hitEntity(Bullet b, Hitboxc entity, float health) { + b.fdata++; + if ((bounceCap == -1 || b.fdata <= bounceCap) && bounceUnits) { + if(b.collided.size >= 1 && bounceInternal == -1) b.collided.pop(); + if((entity instanceof Unit)) { + Unit unit = (Unit) entity; + //Bring bullet back to point of intersection + RicochetBulletData data = (RicochetBulletData) b.data; + entity.hitbox(Tmp.r1); + Tmp.v1.set(b.x - b.lastX, b.y - b.lastY); + Tmp.v1.setLength(Tmp.v1.len() + ((Unit) entity).hitSize).add(b.x, b.y); + + Vec2 collisionPoint = Geometry.raycastRect(b.lastX, b.lastY, Tmp.v1.x, Tmp.v1.y, Tmp.r1); + + if(collisionPoint != null) { + b.set(collisionPoint); + } + + float dx = b.lastX - entity.getX(); + float dy = b.lastY - entity.getY(); + + float angle = 270; + if(Math.abs(dx) > Math.abs(dy)){ + //Angle to the right or left + angle = 0; + if(dx > 0) angle = 180; + } + //If dy is upwards angle faces up + else if(dy > 0) angle = 90; + + float newRotation = (angle - (b.rotation() + 180)) * 2 + b.rotation() + 180; + b.rotation(newRotation); + + b.vel.add(((Unit) entity).vel()); + b.set(b.x + b.vel.x, b.y + b.vel.y); + bounceEffect.at(b.x, b.y, b.vel.angle()); + + } + } + super.hitEntity(b, entity, health); + } + + + @Override + public void hitTile(Bullet b, Building build, float x, float y, float initialHealth, boolean direct) { + b.fdata++; + if(build != null){ + float difX = b.x - build.x, + difY = b.y - build.y; + boolean flipX = false; + boolean flipY = true; + if(Math.abs(difX) > Math.abs(difY)) { + flipX = true; + flipY = false; + } + if ((bounceCap == -1 || b.fdata <= bounceCap) && bounceBuildings) { + //Flip velocity after sliding back. I swear I canot tell how anoying this was to figure out. + + //Offset from the middle to it's sides + float size = build.block.size * Vars.tilesize/2; + + //Corners of side + Tmp.v1.set(size, 0); + + //Set theese two vectors to corners on the right side + Tmp.v2.set(Tmp.v1).add(0, size); + Tmp.v1.sub(0, size); + + //Rotate apropriately + if(flipX && difX < 0){ + Tmp.v2.scl(-1); + Tmp.v1.scl(-1); + } + else if (flipY){ + //Set bottom right corner to top left + Tmp.v1.set(-size, size); + if(difY < 0){ + //Flip the corners across the middle, so that they're on bottom + Tmp.v1.scl(-1); + Tmp.v2.scl(-1); + } + } + Tmp.v1.add(build.x, build.y); + Tmp.v2.add(build.x, build.y); + Tmp.v3.set(b.x, b.y); + Intersector.intersectLines(Tmp.v1, Tmp.v2, Tmp.v3.set(b), Tmp.v4.trns(b.vel.angle() + 180, size * 2).add(b.x, b.y), Tmp.v5); + b.x = Tmp.v3.x; + b.y = Tmp.v3.y; + + if (flipX) { + b.vel.x *= -1 * bounciness; + } + if (flipY) { + b.vel.y *= -1 * bounciness; + } + b.x += b.vel.x; + b.y += b.vel.y; + bounceEffect.at(Tmp.v5.x, Tmp.v5.y, b.vel.angle()); + } + } + super.hitTile(b, build, x, y, initialHealth, direct); + } + + public static class RicochetBulletData{ + public float lastX, lastY, curX, curY; + } +} \ No newline at end of file diff --git a/src/meld/entities/bullet/TransitionBulletType.java b/src/meld/entities/bullet/TransitionBulletType.java index f8d7059..9a476b5 100644 --- a/src/meld/entities/bullet/TransitionBulletType.java +++ b/src/meld/entities/bullet/TransitionBulletType.java @@ -2,13 +2,24 @@ import mindustry.content.Fx; import mindustry.entities.bullet.BulletType; +import mindustry.gen.Bullet; +import mindustry.type.StatusEffect; public class TransitionBulletType extends BulletType { + public StatusEffect spawnStatus; + public float spawnStatusDuration = 0; + public TransitionBulletType(){ super(); + speed = 0.00001f; keepVelocity = false; instantDisappear = true; collides = absorbable = reflectable = hittable = false; shootEffect = chargeEffect = despawnEffect = hitEffect = Fx.none; } + + @Override + public void createUnits(Bullet b, float x, float y) { + super.createUnits(b, x, y); + } } diff --git a/src/meld/entities/unit/BulbheadEntity.java b/src/meld/entities/unit/BulbheadEntity.java new file mode 100644 index 0000000..7d6fcee --- /dev/null +++ b/src/meld/entities/unit/BulbheadEntity.java @@ -0,0 +1,367 @@ +package meld.entities.unit; + +import arc.Events; +import arc.graphics.Blending; +import arc.graphics.Color; +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.Geometry; +import arc.math.geom.Point2; +import arc.math.geom.Position; +import arc.util.*; +import meld.content.MeldUnits; +import meld.graphics.Draww; +import meld.graphics.MeldRegions; +import meld.world.blocks.CoreRaft; +import mindustry.Vars; +import mindustry.content.Blocks; +import mindustry.content.Fx; +import mindustry.entities.EntityCollisions; +import mindustry.entities.Units; +import mindustry.entities.units.BuildPlan; +import mindustry.game.EventType; +import mindustry.game.Team; +import mindustry.game.Teams; +import mindustry.gen.*; +import mindustry.graphics.Drawf; +import mindustry.graphics.Layer; +import mindustry.graphics.Pal; +import mindustry.world.Build; +import mindustry.world.Tile; +import mindustry.world.blocks.ConstructBlock; +import mindustry.world.blocks.storage.CoreBlock; + +//Bandaid fix for multiplayer units dying randomly because I legit have no idea how to fix it otherwise +public class BulbheadEntity extends UnitWaterMove { + + @Nullable + public CoreRaft.CoreRaftBuild nearbyRaft; + + //Actually counts upwards... kinda counter intuitively named + public float corelinkGrace = 0; + + + @Override + public EntityCollisions.SolidPred solidity() { + return (x, y) -> { + Tile tile = Vars.world.tile(x, y); + if(tile == null) return true; + + if(tile.synthetic() || !tile.solid()) return false; + + return !(tile.floor().isLiquid); + }; + } + + //skip all the logic involved and just give rotation + @Override + public float prefRotation() { + return this.moving() && this.type.omniMovement ? this.vel().angle() : this.rotation; + } + + @Override + public boolean canShoot() { + return super.canShoot(); + } + + @Override + public void update() { + getNearbyLink(); + + Tile tile = this.tileOn(); + + if (tile != null && !this.canPassOn()) { + for(int i = 0; i < 4; i++){ + Tile other = tile.nearby(i); + if(!EntityCollisions.waterSolid(other.x, other.y)){ + x = other.worldx(); + y = other.worldy(); + + Log.info("SAVED"); + } + } + } + super.update(); + + } + + public void getNearbyLink(){ + if(CoreRaft.rafts.isEmpty()) return; + nearbyRaft = CoreRaft.rafts.sort(raft -> raft.dst(this)).first(); + if(!within(nearbyRaft, type.fogRadius * Vars.tilesize)) nearbyRaft = null; + } + + //Copying a lot from vanilla's source code... yeah... + //Reuseable code I guess + @Override + public boolean activelyBuilding() { + if (this.isBuilding()) { + BuildPlan plan = this.buildPlan(); + if (!Vars.state.isEditor() && plan != null && !withinBuildRange(plan)) { + return false; + } + } + + return this.isBuilding() && this.updateBuilding; + } + + public boolean withinBuildRange(Position p){ + return Vars.state.rules.infiniteResources || within(p, type.buildRange) || nearbyRaft != null && nearbyRaft.within(p, nearbyRaft.fogRadius() * Vars.tilesize); + } + + public float buildDistance(Position p){ + return nearbyRaft != null ? Math.min(dst(p), nearbyRaft.dst(p)) : dst(p); + } + + //God this is a lot of reused code isn't it + public void updateBuildLogic() { + if (!(this.type.buildSpeed <= 0.0F)) { + if (!Vars.headless) { + if (this.lastActive != null && this.buildAlpha <= 0.01F) { + this.lastActive = null; + } + + this.buildAlpha = Mathf.lerpDelta(this.buildAlpha, this.activelyBuilding() ? 1.0F : 0.0F, 0.15F); + } + + this.validatePlans(); + if (this.updateBuilding && this.canBuild()) { + boolean infinite = Vars.state.rules.infiniteResources || this.team().rules().infiniteResources; + this.buildCounter += Time.delta; + if (Float.isNaN(this.buildCounter) || Float.isInfinite(this.buildCounter)) { + this.buildCounter = 0.0F; + } + + this.buildCounter = Math.min(this.buildCounter, 10.0F); + boolean instant = Vars.state.rules.instantBuild && Vars.state.rules.infiniteResources; + int maxPerFrame = instant ? this.plans.size : 10; + int count = 0; + CoreBlock.CoreBuild core = this.core(); + if (core != null || infinite) { + while((this.buildCounter >= 1.0F || instant) && count++ < maxPerFrame && this.plans.size > 0) { + --this.buildCounter; + boolean hasAll; + if (this.plans.size > 1) { + int total = 0; + int size = this.plans.size; + float bestDst = Float.MAX_VALUE; + hasAll = false; + + int bestIndex; + for(bestIndex = -1; total < size; ++total) { + BuildPlan plan = this.buildPlan(); + + //Tweakead so anything within the nearest raft core's build radius gets validated + float dst = plan.dst2(this); + boolean within = withinBuildRange(plan); + if (within && !this.shouldSkip(plan, core)) { + hasAll = true; + break; + } + + if (within && dst < bestDst) { + bestIndex = total; + bestDst = dst; + } + + this.plans.removeFirst(); + this.plans.addLast(plan); + } + + if (!hasAll && bestIndex > 0 && withinBuildRange(buildPlan())) { + for(int i = 0; i < bestIndex; ++i) { + this.plans.addLast(this.plans.removeFirst()); + } + } + } + + BuildPlan current = this.buildPlan(); + Tile tile = current.tile(); + this.lastActive = current; + this.buildAlpha = 1.0F; + if (current.breaking) { + this.lastSize = tile.block().size; + } + + if (withinBuildRange(tile)) { + if (!Vars.headless) { + Vars.control.sound.loop(Sounds.loopBuild, tile, 1.3F); + } + + Building var18 = tile.build; + ConstructBlock.ConstructBuild entity; + if (var18 instanceof ConstructBlock.ConstructBuild) { + entity = (ConstructBlock.ConstructBuild)var18; + if (tile.team() != this.team && tile.team() != Team.derelict || !current.breaking && (entity.current != current.block || entity.tile != current.tile())) { + this.plans.removeFirst(); + continue; + } + } else if (!current.initialized && !current.breaking && Build.validPlaceIgnoreUnits(current.block, this.team, current.x, current.y, current.rotation, true, true)) { + if (!Build.checkNoUnitOverlap(current.block, current.x, current.y)) { + this.plans.removeFirst(); + this.plans.addLast(current); + continue; + } + + hasAll = infinite || current.isRotation(this.team) || tile.team() == Team.derelict && tile.block() == current.block && tile.build != null && tile.block().allowDerelictRepair && Vars.state.rules.derelictRepair || !Structs.contains(current.block.requirements, (ix) -> { + return !core.items.has(ix.item, Math.min(Mathf.round((float)ix.amount * Vars.state.rules.buildCostMultiplier), 1)); + }); + if (hasAll) { + Call.beginPlace(this, current.block, this.team, current.x, current.y, current.rotation, current.block.instantBuild ? current.config : null); + if (!Vars.net.client() && current.block.instantBuild) { + if (this.plans.size > 0) { + this.plans.removeFirst(); + } + continue; + } + } else { + current.stuck = true; + } + } else { + if (current.initialized || !current.breaking || !Build.validBreak(this.team, current.x, current.y)) { + this.plans.removeFirst(); + continue; + } + + Call.beginBreak(this, this.team, current.x, current.y); + } + + if (tile.build instanceof ConstructBlock.ConstructBuild && !current.initialized) { + Events.fire(new EventType.BuildSelectEvent(tile, this.team, this, current.breaking)); + current.initialized = true; + } + + var18 = tile.build; + if (var18 instanceof ConstructBlock.ConstructBuild) { + entity = (ConstructBlock.ConstructBuild)var18; + float bs = 1.0F / entity.buildCost * this.type.buildSpeed * this.buildSpeedMultiplier * Vars.state.rules.buildSpeed(this.team); + if (current.breaking) { + entity.deconstruct(this, core, bs); + } else if (entity.current != null && (Vars.state.isEditor() || Vars.state.rules.waves && this.team == Vars.state.rules.waveTeam && entity.current.isVisible() || entity.current.unlockedNowHost() && entity.current.environmentBuildable() && entity.current.isPlaceable())) { + entity.construct(this, core, bs, current.config); + } + + current.stuck = Mathf.equal(current.progress, entity.progress); + current.progress = entity.progress; + } + } + } + + } + } + } + } + + public void draw(){ + super.draw(); + float actualElevation = elevation; + elevation /= 2; + + //Draww.drawChain(chain, x, y, Core.input.mouseWorldX(), Core.input.mouseWorldY(), 0); + + if(nearbyRaft != null){ + float bsize = nearbyRaft.block.size/2f * Vars.tilesize; + Draw.z(Layer.blockBuilding - 1); + Draw.quad(nearbyRaft.block.fullIcon, + nearbyRaft.x - bsize, nearbyRaft.y - bsize, Tmp.c1.set(Color.red).shiftHue(Time.time).toFloatBits(), + nearbyRaft.x - bsize, nearbyRaft.y + bsize, Tmp.c1.set(Color.green).shiftHue(Time.time).toFloatBits(), + nearbyRaft.x + bsize, nearbyRaft.y + bsize, Tmp.c1.set(Color.blue).shiftHue(Time.time).toFloatBits(), + nearbyRaft.x + bsize, nearbyRaft.y - bsize, Tmp.c1.set(Color.yellow).shiftHue(Time.time).toFloatBits()); + + Draw.blend(Blending.additive); + Draw.z(Layer.effect); + Draw.color(Pal.accent); + //How close/far the unit is away from the core on a scale of 0-1 + float dist = dst(nearbyRaft); + float stretch = 1 - dist/(type.fogRadius * Vars.tilesize); + //Draww.drawChainAlpha(MeldRegions.chain, nearbyRaft.x, nearbyRaft.y, x, y, 1 - 0.5f * stretch, 1 + 2 * stretch, 0,a -> Interp.slope.apply(1 - a)); + Draww.drawChainAlpha(MeldRegions.chain, nearbyRaft.x, nearbyRaft.y, x, y, 1 - 0.5f * Interp.pow5.apply(1-stretch), 0.5f + 0.5f * stretch, 0, f -> Interp.slope.apply((f + dist)/(type.fogRadius * Vars.tilesize) % 1 + Time.time/60)); + Draw.blend(Blending.normal); + } + + elevation = actualElevation; + } + + //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 + public void drawBuilding() { + boolean active = this.activelyBuilding(); + if (plans.size > 0 && (active || this.lastActive != null)) { + Draw.z(115.0F); + BuildPlan plan = active ? this.buildPlan() : this.lastActive; + Tile tile = plan.tile(); + CoreBlock.CoreBuild core = this.team.core(); + + Position origin = within(plan, type.buildRange) ? this : nearbyRaft; + if (tile != null && origin != null) { + if (core != null && active && !this.isLocal() && !(tile.block() instanceof ConstructBlock)) { + Draw.z(84.0F); + this.drawPlan(plan, 0.5F); + this.drawPlanTop(plan, 0.5F); + Draw.z(115.0F); + } + + if (type.drawBuildBeam) { + float focusLen = type.buildBeamOffset + Mathf.absin(Time.time, 3.0F, 0.6F); + float px = origin.getX(); + float py = origin.getY(); + if(origin == this){ + px += Angles.trnsx(rotation, focusLen); + py += Angles.trnsy(rotation, focusLen); + } + + drawBuildingBeam(px, py); + + if(origin != this){ + Draw.z(122); + Drawf.buildBeam(origin.getX(), origin.getY(), x, y, 4); + Lines.stroke(2); + + px = x + Angles.trnsx(rotation, focusLen); + py = y + Angles.trnsy(rotation, focusLen); + Lines.dashLine(px, py, plan.drawx(), plan.drawy(), 5); + } + } + } + } + } + + @Override + public void controlWeapons(boolean rotateShoot) { + super.controlWeapons(rotateShoot); + } + + public void drawBuildingBeam(float px, float py) { + + boolean active = this.activelyBuilding(); + if (active || this.lastActive != null) { + Draw.z(115.0F); + BuildPlan plan = active ? this.buildPlan() : this.lastActive; + Tile tile = Vars.world.tile(plan.x, plan.y); + if (tile != null) { + int size = plan.breaking ? (active ? tile.block().size : this.lastSize) : plan.block.size; + float tx = plan.drawx(); + float ty = plan.drawy(); + Lines.stroke(1.0F, plan.breaking ? Pal.remove : Pal.accent); + Draw.z(122.0F); + Draw.alpha(this.buildAlpha); + if (!active && !(tile.build instanceof ConstructBlock.ConstructBuild)) { + Fill.square(plan.drawx(), plan.drawy(), (float)(size * 8) / 2.0F); + } + + Drawf.buildBeam(px, py, tx, ty, (float)(8 * size) / 2.0F); + Fill.square(px, py, 1.8F + Mathf.absin(Time.time, 2.2F, 1.1F), this.rotation + 45.0F); + Draw.reset(); + Draw.z(115.0F); + } + } + } + + @Override + public int classId() { + return MeldUnits.classID(this.getClass()); + } +} diff --git a/src/meld/entities/unit/UnitEdgeWaterMove.java b/src/meld/entities/unit/UnitEdgeWaterMove.java deleted file mode 100644 index 939dd6a..0000000 --- a/src/meld/entities/unit/UnitEdgeWaterMove.java +++ /dev/null @@ -1,40 +0,0 @@ -package meld.entities.unit; - -import arc.util.Log; -import mindustry.entities.EntityCollisions; -import mindustry.gen.UnitWaterMove; -import mindustry.world.Tile; - -//Bandaid fix for multiplayer units dying randomly because I legit have no idea how to fix it otherwise -public class UnitEdgeWaterMove extends UnitWaterMove { - - //skip all the logic involved and just give rotation - @Override - public float prefRotation() { - return this.moving() && this.type.omniMovement ? this.vel().angle() : this.rotation; - } - - @Override - public boolean canShoot() { - return super.canShoot(); - } - - @Override - public void update() { - Tile tile = this.tileOn(); - - if (tile != null && !this.canPassOn()) { - for(int i = 0; i < 4; i++){ - Tile other = tile.nearby(i); - if(!EntityCollisions.waterSolid(other.x, other.y)){ - x = other.worldx(); - y = other.worldy(); - - Log.info("SAVED"); - } - } - } - super.update(); - - } -} diff --git a/src/meld/entities/unit/abilities/BezerkAbility.java b/src/meld/entities/unit/abilities/BezerkAbility.java new file mode 100644 index 0000000..ca6448a --- /dev/null +++ b/src/meld/entities/unit/abilities/BezerkAbility.java @@ -0,0 +1,116 @@ +package meld.entities.unit.abilities; + +import arc.math.Mathf; +import arc.struct.Seq; +import arc.util.Log; +import arc.util.Time; +import meld.content.MeldStatusEffects; +import mindustry.Vars; +import mindustry.content.Fx; +import mindustry.entities.Effect; +import mindustry.entities.Units; +import mindustry.entities.abilities.Ability; +import mindustry.entities.bullet.BulletType; +import mindustry.gen.Unit; +import mindustry.type.StatusEffect; +import mindustry.type.UnitType; + +public class BezerkAbility extends Ability { + + /** + Yes this is stupid, @Link{Ability#created} only fires when a unit gets made though + */ + protected boolean setup = false; + + //Time counts up while a unit is shooting, and counts down when the unit isn't/can't shoot + protected float bezerkProgress; + + //Charge up until becoming BEZERK >:D + protected float time; + + //Controls whether the unit can shoot or not, gets set to false once time = 0 + protected boolean bezerk; + + //Bezert under this hp threshold + public float bezerkHealthf = 0.5f, + //Time it takes to drop hp + bezerkTime = 60; + + //Damage/sec based on bezerk% + public float damage = 50/60; + + //Radius/damage for da boom boom prepper + public float boomRadius = Vars.tilesize * 4, boomDamage = 200/60f; + + public float reloadMultiplier = 3, speedMultiplier = 1.2f, bezerkSpeedMulti = 2; + + public BulletType deathBomb; + + public Effect bezerkSmoke = Fx.generate; + public Effect chargeEffect = Fx.lightningCharge; + + public float effectChance = 0.5f; + + + public Seq clear = new Seq<>(); + public Seq sedated = new Seq<>(); + + public BezerkAbility(){ + clear.add(MeldStatusEffects.sentry); + sedated.addAll(MeldStatusEffects.lacerated); + } + + @Override + public void update(Unit unit) { + super.update(unit); + + //Dumb stupid + if(!setup){ + setup = true; + time = unit.healthf() < bezerkHealthf ? bezerkTime : 0; + } + + if(unit.isShooting){ + unit.damageContinuousPierce(damage); + } + + time = Mathf.clamp(time + (unit.healthf() < bezerkHealthf ? Time.delta : -Time.delta), 0, bezerkTime); + + //Let em know when to ZERKIN >:DDDDDD + bezerk = time >= bezerkTime; + + sedated.each(u -> { + //Disable zerk D: + if(unit.hasEffect(u)) time = 0; + }); + + //Get more BEZERK the lower hp you have + bezerkProgress = Mathf.clamp((1-unit.healthf())/bezerkHealthf, 0, 1); + + //AAAnd a bunch of random stuff going nuts + if(bezerk){ + unit.disarmed = true; + clear.each(unit::unapply); + + if(unit.buildOn() != null && unit.buildOn().team != unit.team || Units.nearEnemy(unit.team, unit.x, unit.y, boomRadius, boomRadius)){ + unit.damageContinuousPierce(boomDamage); + } + } + + if(bezerk && Mathf.chance(effectChance)){ + bezerkSmoke.at(unit.x + Mathf.random(-unit.hitSize, unit.hitSize), unit.y + Mathf.random(-unit.hitSize, unit.hitSize)); + } + + unit.reloadMultiplier *= Mathf.lerp(1, reloadMultiplier, bezerkProgress); + unit.speedMultiplier *= Mathf.lerp(1, bezerk ? bezerkSpeedMulti : speedMultiplier, bezerkProgress); + } + + @Override + public void death(Unit unit) { + if(bezerk && deathBomb != null) { + deathBomb.create(null, unit.team, unit.x, unit.y, unit.vel.angle()); + Log.info("boomies!"); + } + super.death(unit); + } +} diff --git a/src/meld/entities/unit/abilities/DeathBirthAbility.java b/src/meld/entities/unit/abilities/DeathBirthAbility.java index 7ecd03a..8d35f2c 100644 --- a/src/meld/entities/unit/abilities/DeathBirthAbility.java +++ b/src/meld/entities/unit/abilities/DeathBirthAbility.java @@ -6,10 +6,22 @@ import mindustry.Vars; import mindustry.entities.abilities.SpawnDeathAbility; import mindustry.gen.Unit; +import mindustry.type.UnitType; //literally the same but with a status effect attached to it. yes, that's literally it. public class DeathBirthAbility extends SpawnDeathAbility { + public DeathBirthAbility(UnitType unit, int amount, float spread){ + super(unit, amount, spread); + } + public DeathBirthAbility(UnitType unit, int amount){ + super(unit, amount, 8); + } + + public DeathBirthAbility(){ + super(); + } + @Override public void death(Unit unit) { if (!Vars.net.client()) { @@ -22,7 +34,6 @@ public void death(Unit unit) { u.apply(MeldStatusEffects.newborn, 60); } } - } } diff --git a/src/meld/entities/unit/abilities/SolidSpeedAbility.java b/src/meld/entities/unit/abilities/SolidSpeedAbility.java index f11e4f6..1665b6a 100644 --- a/src/meld/entities/unit/abilities/SolidSpeedAbility.java +++ b/src/meld/entities/unit/abilities/SolidSpeedAbility.java @@ -20,8 +20,9 @@ public void update(Unit unit) { float target = 1; if(unit.tileOn() != null && unit.tileOn().floor().isLiquid) { target = 0; - unit.speedMultiplier *= Mathf.lerp(1, speedMultiplier, warmup); } warmup = Mathf.lerpDelta(warmup, target, warmupSpeed); + + unit.speedMultiplier *= Mathf.lerp(1, speedMultiplier, warmup); } } diff --git a/src/meld/entities/unit/abilities/SpawnRushAbility.java b/src/meld/entities/unit/abilities/SpawnRushAbility.java new file mode 100644 index 0000000..ebc30f4 --- /dev/null +++ b/src/meld/entities/unit/abilities/SpawnRushAbility.java @@ -0,0 +1,16 @@ +package meld.entities.unit.abilities; + +import meld.content.MeldStatusEffects; +import mindustry.entities.abilities.Ability; +import mindustry.gen.Unit; + +public class SpawnRushAbility extends Ability { + + public float duration = 240; + + @Override + public void created(Unit unit) { + super.created(unit); + unit.apply(MeldStatusEffects.rush, duration); + } +} diff --git a/src/meld/entities/unit/weapons/BaseWeapon.java b/src/meld/entities/unit/weapons/BaseWeapon.java new file mode 100644 index 0000000..08a0807 --- /dev/null +++ b/src/meld/entities/unit/weapons/BaseWeapon.java @@ -0,0 +1,9 @@ +package meld.entities.unit.weapons; + +import mindustry.type.Weapon; + +public class BaseWeapon extends Weapon { + public BaseWeapon(String name){ + super(name); + } +} diff --git a/src/meld/entities/unit/weapons/template/BraigWeapon.java b/src/meld/entities/unit/weapons/template/BraigWeapon.java new file mode 100644 index 0000000..79e9a8b --- /dev/null +++ b/src/meld/entities/unit/weapons/template/BraigWeapon.java @@ -0,0 +1,48 @@ +package meld.entities.unit.weapons.template; + +import meld.Meld; +import meld.content.MeldStatusEffects; +import meld.entities.unit.weapons.BaseWeapon; +import mindustry.content.Fx; +import mindustry.entities.bullet.BasicBulletType; +import mindustry.entities.pattern.ShootSpread; + +public class BraigWeapon extends BaseWeapon { + public BraigWeapon(float wx, float wy){ + super(Meld.prefix("braig-cannon")); + x = wx; + y = wy; + shootY = 5; + reload = 360; + shootCone = 60; + rotate = true; + mirror = false; + alternate = false; + parentizeEffects = false; + shootStatus = MeldStatusEffects.sentry; + shootStatusDuration = 180; + + shoot = new ShootSpread(){{ + shots = 3; + shotDelay = 7; + spread = 1; + }}; + + inaccuracy = 5; + + bullet = new BasicBulletType(){{ + sprite = Meld.prefix("clump"); + speed = 4; + lifetime = 75; + width = 10; + height = 12; + damage = 10; + splashDamage = 25; + splashDamageRadius = 25; + knockback = 6; + shootEffect = Fx.shootBig; + hitEffect = Fx.explosion; + impact = true; + }}; + } +} diff --git a/src/meld/entities/unit/weapons/template/PointagoWeapon.java b/src/meld/entities/unit/weapons/template/PointagoWeapon.java new file mode 100644 index 0000000..d3accdc --- /dev/null +++ b/src/meld/entities/unit/weapons/template/PointagoWeapon.java @@ -0,0 +1,64 @@ +package meld.entities.unit.weapons.template; + +import meld.Meld; +import meld.content.MeldStatusEffects; +import meld.entities.unit.weapons.BaseWeapon; +import mindustry.content.Fx; +import mindustry.entities.bullet.BasicBulletType; +import mindustry.entities.part.RegionPart; +import mindustry.entities.pattern.ShootSpread; +import mindustry.graphics.Layer; + +public class PointagoWeapon extends BaseWeapon { + public PointagoWeapon(float wx, float wy){ + super(Meld.prefix("pointago-sniper")); + + x = wx; + y = wy; + + shootY = 8; + rotateSpeed = 2.5f; + reload = 600; + + shootCone = 60; + rotate = true; + mirror = alternate = false; + shootStatus = MeldStatusEffects.sentry; + shootStatusDuration = 200; + + shoot = new ShootSpread(){{ + shots = 3; + shotDelay = 5; + spread = 1; + }}; + + bullet = new BasicBulletType(5, 65, Meld.prefix("clump")){{ + layer = Layer.fogOfWar + 1; + drag = -0.02f; + lifetime = 55; + rangeOverride = 300; + + pierce = true; + pierceCap = 2; + + width = 5; + height = 24; + knockback = 25; + impact = true; + trailEffect = Fx.smoke; + shootEffect = Fx.shootBig; + hitEffect = Fx.explosion; + }}; + + parts.addAll( + new RegionPart("-barrel"){{ + progress = PartProgress.reload; + moveY = -3; + moves.addAll( + new PartMove(PartProgress.reload, 0, -2, 0) + ); + }}, + new RegionPart() + ); + } +} diff --git a/src/meld/fluid/Aspect.java b/src/meld/fluid/Aspect.java new file mode 100644 index 0000000..5204f70 --- /dev/null +++ b/src/meld/fluid/Aspect.java @@ -0,0 +1,23 @@ +package meld.fluid; + +import arc.graphics.Color; +import arc.struct.ObjectMap; +import arc.struct.ObjectSet; +import arc.struct.Seq; +import meld.meta.MeldStatUnit; +import meld.meta.MeldStats; +import mindustry.ctype.ContentType; +import mindustry.type.Liquid; + +public class Aspect extends Liquid { + public Aspect(String name) { + super(name, Color.white); + databaseCategory = "aspect"; + } + + @Override + public void setStats() { + super.setStats(); + MeldStats.aspectStats(this, stats); + } +} diff --git a/src/meld/fluid/AspectGroup.java b/src/meld/fluid/AspectGroup.java new file mode 100644 index 0000000..9a50577 --- /dev/null +++ b/src/meld/fluid/AspectGroup.java @@ -0,0 +1,72 @@ +package meld.fluid; + +import arc.Core; +import arc.struct.*; +import mindustry.Vars; +import mindustry.type.Liquid; +import mindustry.world.blocks.Attributes; + +//Just a centralised way for me to track what does what +public class AspectGroup { + + public static Seq groups = new Seq<>(); + public String name, localizedName; + + public AspectGroup(String name){ + //hgjkgvjgfh + this.name = Vars.content.transformName(name); + groups.add(this); + } + + public static void loadAll(){ + groups.each(AspectGroup::load); + } + + //Kept separate since I want to test some things ingame and be able to reset a single group's name over calling a load function on everything + public void load(){ + localizedName = Core.bundle.get("aspect-group." + name, name); + } + + public ObjectMap stats = new ObjectMap<>(); + + public static void put(Liquid liquid, AspectGroup group, AspectStats stats){ + group.stats.put(liquid, stats); + } + + public static AspectGroup + aether = new AspectGroup("aether"), + aspect = new AspectGroup("aspect"), + outlet = new AspectGroup("outlet"), + fumes = new AspectGroup("fumes"); + + public float getDensity(Liquid liquid){ + AspectStats stat = stats.get(liquid); + return stat == null ? 0 : stat.density; + } + + public float getEfficiency(Liquid liquid){ + AspectStats stat = stats.get(liquid); + return stat == null ? 0 : stat.efficiency; + } + + public static class AspectStats{ + public AspectStats(float efficiency, float density){ + this.efficiency = efficiency; + this.density = density; + } + + //No idea if ill use this or not but I really just want something to work atp + public AspectStats efficiency(float efficiency){ + this.efficiency = efficiency; + return this; + } + + public AspectStats density(float density){ + this.density = density; + return this; + } + + public float efficiency; + public float density; + } +} diff --git a/src/meld/graphics/Draww.java b/src/meld/graphics/Draww.java index 33c691a..8957d7d 100644 --- a/src/meld/graphics/Draww.java +++ b/src/meld/graphics/Draww.java @@ -1,13 +1,20 @@ package meld.graphics; +import arc.graphics.Color; import arc.graphics.g2d.Draw; +import arc.graphics.g2d.Lines; import arc.graphics.g2d.TextureRegion; +import arc.math.Interp; import arc.math.Mathf; import arc.math.geom.Vec2; +import arc.util.Tmp; import mindustry.Vars; +import mindustry.content.Blocks; +import mindustry.graphics.Pal; +import mindustry.world.Block; public class Draww { - public static Vec2 tv1 = new Vec2(); + public static Vec2 tv1 = new Vec2(), tv2 = new Vec2(), tv3 = new Vec2(); //draws a chain of sprites public static void drawChain(TextureRegion region, float x, float y, float endx, float endy, float drawRotation){ drawChain(region, x, y, endx, endy, 1, 1, drawRotation); @@ -17,21 +24,75 @@ public static void drawChain(TextureRegion region, float x, float y, float endx, float distance = Mathf.dst(x, y, endx, endy); //This is in WU - float height = region.height/4 * hScale; + float height = region.height/4f * hScale; float width = region.width/4f * wScale; //Distance converted back to WU - float remainder = ((distance * 4) % region.height * hScale)/8; + float remainder = distance % height; - for (int i = 0; i < Math.floor((distance)/region.height * 4); i++) { - tv1.trns(angleToEnd, distance - i * height - region.height/8 * hScale).add(x ,y); + for (int i = 0; i < Math.floor((distance)/(height)); i++) { + tv1.trns(angleToEnd, distance - i * height - height/2).add(x ,y); Draw.rect(region, tv1.x, tv1.y, width, height, drawRotation + angleToEnd - 90); } - tv1.trns(drawRotation + angleToEnd, remainder); + tv1.trns(angleToEnd, remainder/2); - //Lines.line(x, y, x + tv1.x, y + tv1.y); - Draw.rect(region, x + tv1.x, y + tv1.y, width, remainder * 2, drawRotation + angleToEnd - 90); + Draw.rect(region, x + tv1.x, y + tv1.y, width, remainder, drawRotation + angleToEnd - 90); + } + + public interface AlphaProv{ + float get(float in); + } + + public static void drawChainAlpha(TextureRegion region, float x, float y, float endx, float endy, float wScale, float hScale, float drawRotation, Interp alphaProv){ + float angleToEnd = Mathf.angle(endx - x, endy - y); + float distance = Mathf.dst(x, y, endx, endy); + + //This is in WU + float height = region.height/4f * hScale; + float width = region.width/4f * wScale; + + //Distance converted back to WU + float remainder = distance % height; + + + + Tmp.c1.set(Draw.getColor()); + Tmp.c2.set(Draw.getColor()); + + tv3.trns(angleToEnd + 90, width/2); + + for (int i = 0; i < Math.floor((distance)/(height)); i++) { + tv1.trns(angleToEnd, distance - i * height - height); + tv2.trns(angleToEnd, distance - i * height); + + float baseAlpha = alphaProv.apply(tv1.len()); + float endAlpha = alphaProv.apply(tv2.len()); + + tv1.add(x, y); + tv2.add(x, y); + + Tmp.c1.a(baseAlpha); + Tmp.c2.a(endAlpha); + Draw.quad(region, + tv2.x + tv3.x, tv2.y + tv3.y, Tmp.c2.toFloatBits(), + tv1.x + tv3.x, tv1.y + tv3.y, Tmp.c1.toFloatBits(), + tv1.x - tv3.x, tv1.y - tv3.y, Tmp.c1.toFloatBits(), + tv2.x - tv3.x, tv2.y - tv3.y, Tmp.c2.toFloatBits() + ); + + //Draw.rect(region, tv1.x, tv1.y, width, height, drawRotation + angleToEnd - 90); + //Draw.quad(region, tv1.x, tv1.y, width, height, drawRotation + angleToEnd - 90); + } + + tv1.trns(angleToEnd, remainder/2f); + + Draw.alpha(alphaProv.apply(1 - tv1.len()/distance)); + Draw.rect(region, x + tv1.x, y + tv1.y, width, remainder, drawRotation + angleToEnd - 90); + Draw.alpha(1); + + Draw.color(); + Lines.stroke(Vars.tilesize); } public static void drawShine(TextureRegion region, float x, float y, float rotation, float alpha){ diff --git a/src/meld/graphics/MeldInterps.java b/src/meld/graphics/MeldInterps.java new file mode 100644 index 0000000..a507273 --- /dev/null +++ b/src/meld/graphics/MeldInterps.java @@ -0,0 +1,13 @@ +package meld.graphics; + +import arc.math.Interp; +import arc.math.Mathf; + +public class MeldInterps { + public static Interp + trueSin = Mathf::sin, + trueCos = Mathf::cos, + compressedSin = f -> Mathf.sin(f * Mathf.PI2), + compressedCos = f -> Mathf.cos(f * Mathf.PI2) + ; +} diff --git a/src/meld/graphics/MeldPal.java b/src/meld/graphics/MeldPal.java index 52d238a..3c1cb9d 100644 --- a/src/meld/graphics/MeldPal.java +++ b/src/meld/graphics/MeldPal.java @@ -14,5 +14,9 @@ public class MeldPal { flamePink = Color.valueOf("feafea"), flamePinkDark = Color.valueOf("d26ab1"), shockwaveGray = Color.valueOf("7f7f7f"), - sparkOrange = Color.valueOf("f6e096"); + sparkOrange = Color.valueOf("f6e096"), + resoShardFront = Color.valueOf("a3efba"), + resoShardBack = Color.valueOf("40a547"), + glassMallowsFront = Color.valueOf("ede0d4"), + glassMallowsBack = Color.valueOf("cd9d70"); } diff --git a/src/meld/graphics/MeldRegions.java b/src/meld/graphics/MeldRegions.java new file mode 100644 index 0000000..2f56de7 --- /dev/null +++ b/src/meld/graphics/MeldRegions.java @@ -0,0 +1,14 @@ +package meld.graphics; + +import arc.Core; +import arc.graphics.g2d.TextureRegion; +import meld.Meld; + +public class MeldRegions { + + public static TextureRegion chain; + + public static void load(){ + chain = Core.atlas.find(Meld.prefix("chain")); + } +} diff --git a/src/meld/meta/MeldStatUnit.java b/src/meld/meta/MeldStatUnit.java new file mode 100644 index 0000000..878c715 --- /dev/null +++ b/src/meld/meta/MeldStatUnit.java @@ -0,0 +1,11 @@ +package meld.meta; + +import mindustry.world.meta.StatUnit; + +public class MeldStatUnit { + public static final StatUnit + ticks = new StatUnit("ticks"), + aspectEfficiency = new StatUnit("aspect-efficiency"), + aspectDensity = new StatUnit("aspect-density"); + ; +} diff --git a/src/meld/meta/MeldStats.java b/src/meld/meta/MeldStats.java new file mode 100644 index 0000000..7a4afbd --- /dev/null +++ b/src/meld/meta/MeldStats.java @@ -0,0 +1,44 @@ +package meld.meta; + +import arc.Core; +import arc.util.Strings; +import meld.fluid.AspectGroup; +import mindustry.gen.Tex; +import mindustry.type.Liquid; +import mindustry.ui.Styles; +import mindustry.world.meta.Stat; +import mindustry.world.meta.Stats; + +public class MeldStats { + + public static Stat + aspectStats = new Stat("aspect-stats"); + + public static String percent(float number){ + return (int) (number * 100) + "%"; + } + + public static void aspectStats(Liquid aspect, Stats stats){ + stats.add(aspectStats, table -> { + + table.row(); + + AspectGroup.groups.each(g -> { + AspectGroup.AspectStats aspectStat = g.stats.get(aspect); + if(aspectStat == null) return; + table.table(Styles.grayPanel, pannel -> { + + pannel.left(); + + pannel.add(g.localizedName).left(); + pannel.row(); + pannel.add("[lightgray]" + Core.bundle.get("stat.aspect-efficiency") + ":[] " + percent(g.getEfficiency(aspect))); + pannel.row(); + pannel.add("[lightgray]" + Core.bundle.get("stat.aspect-density") + ":[] " + percent(g.getDensity(aspect))).left(); + pannel.row(); + }).growX().pad(5); + table.row(); + }); + }); + } +} diff --git a/src/meld/world/blocks/AetherCluster.java b/src/meld/world/blocks/AetherCluster.java index 0c5a0da..308f62f 100644 --- a/src/meld/world/blocks/AetherCluster.java +++ b/src/meld/world/blocks/AetherCluster.java @@ -1,6 +1,7 @@ package meld.world.blocks; import arc.graphics.g2d.TextureRegion; +import arc.math.Mathf; import arc.math.geom.Point2; import arc.scene.ui.layout.Table; import arc.util.Time; @@ -32,7 +33,7 @@ public class AetherClusterBuild extends Building{ @Override public void updateTile() { super.updateTile(); - liquids.add(outputLiquid.liquid, outputLiquid.amount * Time.delta); + liquids.set(outputLiquid.liquid, Mathf.clamp(liquids.get(outputLiquid.liquid) + outputLiquid.amount * Time.delta, 0, liquidCapacity)); if(timer.get(liquidTimer, 5)){ updateProximity(); dumpLiquid(outputLiquid.liquid); diff --git a/src/meld/world/blocks/Bruisekit.java b/src/meld/world/blocks/Bruisekit.java index a9164b0..ce14483 100644 --- a/src/meld/world/blocks/Bruisekit.java +++ b/src/meld/world/blocks/Bruisekit.java @@ -4,6 +4,7 @@ import arc.graphics.g2d.Lines; import arc.math.Mathf; import arc.struct.Seq; +import arc.util.Log; import mindustry.entities.Units; import mindustry.gen.Building; @@ -16,7 +17,7 @@ public class Bruisekit extends FieldPulsar{ public float healSpeed = 2; public float retargetInterval = 5; - public float recentDamageMultiplier = 0.1f; + public float recentDamageMultiplier = 0.1f, smallMultiplier = 0.5f; public Bruisekit(String name) { super(name); @@ -26,15 +27,22 @@ public Bruisekit(String name) { public class BruisekitBuild extends PulsarBuild{ public Building target; + @Override + public boolean shouldConsume() { + return super.shouldConsume() && target != null && lastRadius < range; + } @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.isValid() && target.damaged()) { + float healAmount = healSpeed * edelta(); if(target.wasRecentlyDamaged()) healAmount *= recentDamageMultiplier; + if(target.block.size == 0) healAmount *= smallMultiplier; + + Log.info(healAmount); target.heal(healAmount); } @@ -42,13 +50,14 @@ public void updateTile() { } public void findTarget(){ + target = null; tmpDamaged.clear(); Units.nearbyBuildings(x, y, smoothRadius, b -> { - if(b.team == team() && b.damaged() && b.block.size > 1) tmpDamaged.add(b); + if(b.team == team() && b.damaged()) tmpDamaged.add(b); }); - tmpDamaged.sort(b -> b.block.size + (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); if(!tmpDamaged.isEmpty()) target = tmpDamaged.pop(); } diff --git a/src/meld/world/blocks/CoreRaft.java b/src/meld/world/blocks/CoreRaft.java index 00d9c47..a1218f1 100644 --- a/src/meld/world/blocks/CoreRaft.java +++ b/src/meld/world/blocks/CoreRaft.java @@ -1,8 +1,10 @@ package meld.world.blocks; +import arc.Events; import arc.graphics.g2d.Draw; import arc.graphics.g2d.Lines; import arc.math.Interp; +import arc.struct.Seq; import arc.util.Nullable; import arc.util.Time; import meld.content.MeldStatusEffects; @@ -10,6 +12,8 @@ import mindustry.content.Fx; import mindustry.entities.Units; import mindustry.entities.units.WeaponMount; +import mindustry.game.EventType; +import mindustry.game.Team; import mindustry.gen.Building; import mindustry.gen.Player; import mindustry.gen.Unit; @@ -22,9 +26,11 @@ import static mindustry.Vars.tilesize; -//Rallies units nearby, +//Rallies units nearby, provides an extended build radius for core units public class CoreRaft extends CoreBlock { + public static Seq rafts = new Seq<>(); + private float nearestLen; public int spawnRange; @@ -36,6 +42,12 @@ public class CoreRaft extends CoreBlock { public CoreRaft(String name) { super(name); fogRadius = 40; + Events.on(EventType.WorldLoadEvent.class, e -> { + rafts.clear(); + Team.sharded.cores().each(c -> { + if(c instanceof CoreRaftBuild raft) rafts.add(raft); + }); + }); } @Override @@ -89,15 +101,35 @@ public static void playerSpawn(Tile tile, Player player) { public class CoreRaftBuild extends CoreBuild { public @Nullable Tile targetTile; + public boolean building = false, lastBuilding = false; + + @Override + public void onRemoved() { + super.onRemoved(); + rafts.remove(this); + } + + @Override + public Building init(Tile tile, Team team, boolean shouldAdd, int rotation) { + rafts.add(this); + return super.init(tile, team, shouldAdd, rotation); + } @Override public void updateTile() { super.updateTile(); + lastBuilding = building; + building = false; + if(timer.get(rallyTimer, 5)){ Units.nearby(team, x, y, fogRadius() * tilesize, (other) -> { other.apply(MeldStatusEffects.rally, rallyDuration); }); } + + if(lastBuilding){ + + } } @Override @@ -115,7 +147,6 @@ public void draw() { } Draw.z(layer); - } /* diff --git a/src/meld/world/blocks/FieldPulsar.java b/src/meld/world/blocks/FieldPulsar.java index 53936a9..aa2da94 100644 --- a/src/meld/world/blocks/FieldPulsar.java +++ b/src/meld/world/blocks/FieldPulsar.java @@ -51,6 +51,8 @@ public void load() { public FieldPulsar(String name) { super(name); update = true; + solid = true; + warmupSpeed = 1/60f; pulseDuration = 240; diff --git a/src/meld/world/blocks/MovementAnchor.java b/src/meld/world/blocks/MovementAnchor.java index f4daac4..ff429d9 100644 --- a/src/meld/world/blocks/MovementAnchor.java +++ b/src/meld/world/blocks/MovementAnchor.java @@ -32,12 +32,13 @@ public class MovementAnchor extends Block { public MovementAnchor(String name) { super(name); + solid = true; update = true; reload = 90; status = MeldStatusEffects.anchored; statusDuration = 240; targets = 2; - this.timerPulse = this.timers++; + timerPulse = timers++; } diff --git a/src/meld/world/blocks/consumers/StupidConsumeAspects.java b/src/meld/world/blocks/consumers/StupidConsumeAspects.java new file mode 100644 index 0000000..551711b --- /dev/null +++ b/src/meld/world/blocks/consumers/StupidConsumeAspects.java @@ -0,0 +1,102 @@ +package meld.world.blocks.consumers; + +import arc.Core; +import arc.graphics.Color; +import arc.math.Mathf; +import arc.struct.IntFloatMap; +import arc.struct.IntMap; +import arc.struct.ObjectFloatMap; +import arc.util.Log; +import meld.fluid.AspectGroup; +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.blocks.production.GenericCrafter; +import mindustry.world.consumers.*; + +public class StupidConsumeAspects extends ConsumeLiquidFilter implements MeldGenericCrafter.BarConsumer { + + //grab it from the group + public AspectGroup group; + + + public StupidConsumeAspects(float amount, AspectGroup group){ + super(); + this.amount = amount; + this.group = group; + + filter = group.stats::containsKey; + } + + private static Liquid currentBest; + + @Override + public void apply(Block block) { + block.hasLiquids = true; + Vars.content.liquids().each(filter, (item) -> { + block.liquidFilter[item.id] = true; + }); + } + + + @Override + public void update(Building build) { + Liquid consumed = getConsumed(build); + build.liquids.remove(consumed, this.amount * build.edelta()/group.getDensity(consumed)); + } + + @Override + public Liquid getConsumed(Building build){ + float highest = 0; + currentBest = null; + for(Liquid liquid: group.stats.keys()){ + if(!Mathf.zero(build.liquids.get(liquid))) { + float value = group.getEfficiency(liquid); + + 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) || liq == null) return 0; + else { + + float multi = group.getEfficiency(liq); + + return Math.min(build.liquids.get(liq) / (this.amount * ed * multi), multi); + } + } + + @Override + public float efficiencyMultiplier(Building build) { + Liquid liq = this.getConsumed(build); + return liq == null ? 0.0f : group.getEfficiency(liq); + } + + @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/recipe/ItemRecipe.java b/src/meld/world/blocks/crafting/recipe/ItemRecipe.java index 97e5644..3cf97ef 100644 --- a/src/meld/world/blocks/crafting/recipe/ItemRecipe.java +++ b/src/meld/world/blocks/crafting/recipe/ItemRecipe.java @@ -68,19 +68,19 @@ public void apply(Block block, Building building) { } //Builder methods - public ItemRecipe input(ItemStack[] items){ + public ItemRecipe input(ItemStack... items){ inputItems = items; return this; } - public ItemRecipe output(ItemStack[] items){ + public ItemRecipe output(ItemStack... items){ outputItems = items; return this; } - public ItemRecipe input(LiquidStack[] liquids){ + public ItemRecipe input(LiquidStack... liquids){ inputLiquids = liquids; return this; } - public ItemRecipe output(LiquidStack[] liquids){ + public ItemRecipe output(LiquidStack... liquids){ outputLiquids = liquids; return this; } diff --git a/src/meld/world/blocks/fluid/AspectPipe.java b/src/meld/world/blocks/fluid/AspectPipe.java index 5ca01aa..95d2502 100644 --- a/src/meld/world/blocks/fluid/AspectPipe.java +++ b/src/meld/world/blocks/fluid/AspectPipe.java @@ -2,19 +2,26 @@ import arc.math.Mathf; import arc.math.geom.Geometry; +import arc.struct.Seq; import arc.util.Log; +import meld.content.MeldLiquids; import meld.world.blocks.crafting.RecipeCrafter; import mindustry.Vars; +import mindustry.game.Team; import mindustry.gen.Building; import mindustry.type.Liquid; import mindustry.world.Block; import mindustry.world.Tile; +import mindustry.world.blocks.distribution.DuctBridge; +import mindustry.world.blocks.liquid.ArmoredConduit; import mindustry.world.blocks.liquid.Conduit; import mindustry.world.blocks.liquid.LiquidRouter; import static meld.content.MeldLiquids.*; public class AspectPipe extends Conduit { + + Seq liquidSeq = new Seq<>(); static final float rotatePad = 6, hpad = rotatePad / 2f / 4f; static final float[][] rotateOffsets = {{hpad, hpad}, {-hpad, hpad}, {-hpad, -hpad}, {hpad, -hpad}}; @@ -24,7 +31,7 @@ public AspectPipe(String name) { @Override public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock) { - return super.blends(tile, rotation, otherx, othery, otherrot, otherblock) || (otherblock.hasLiquids && !(otherblock instanceof Conduit || otherblock instanceof LiquidRouter)); + return super.blends(tile, rotation, otherx, othery, otherrot, otherblock) || (otherblock.hasLiquids && !(otherblock instanceof Conduit || otherblock instanceof LiquidRouter) && outletMapping.values().toSeq().find(l -> otherblock.consumesLiquid(l)) != null); } public class AspectPipeBuild extends ConduitBuild{ diff --git a/src/meld/world/blocks/fluid/ChannelDirector.java b/src/meld/world/blocks/fluid/ChannelDirector.java index 1cdceb4..9367148 100644 --- a/src/meld/world/blocks/fluid/ChannelDirector.java +++ b/src/meld/world/blocks/fluid/ChannelDirector.java @@ -2,9 +2,13 @@ import arc.Core; 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 meld.world.WorldUtil; import mindustry.gen.Building; +import mindustry.type.Liquid; public class ChannelDirector extends FlexibleSizeJunction{ @@ -20,9 +24,17 @@ public ChannelDirector(String name) { public class DirectorBuild extends FlexibleBuild{ + @Override + public Building getLiquidDestination(Building source, Liquid liquid, Position otherOffset) { + int dir = WorldUtil.relativeTo(source.tile.x, source.tile.y, tile.x, tile.y); + if(!acceptDirection(source, this, dir)) return this; + + return super.getLiquidDestination(source, liquid, otherOffset); + } + @Override public boolean acceptDirection(Building source, Building junction, int dir) { - return dir == rotation; + return dir != (rotation + 2) % 4; } @Override diff --git a/src/meld/world/blocks/fluid/ChannelVent.java b/src/meld/world/blocks/fluid/ChannelVent.java index 1499aca..16df53d 100644 --- a/src/meld/world/blocks/fluid/ChannelVent.java +++ b/src/meld/world/blocks/fluid/ChannelVent.java @@ -1,6 +1,7 @@ package meld.world.blocks.fluid; import arc.graphics.g2d.Draw; +import arc.math.Interp; import arc.math.Mathf; import mindustry.entities.Puddles; import mindustry.type.Liquid; @@ -15,11 +16,15 @@ public class ChannelVent extends LiquidRouter { int ventTimer = timers++; + public Interp ventScaling = Interp.pow2In; + public ChannelVent(String name) { super(name); } public class ChannelVentBuild extends LiquidRouterBuild{ + + @Override public void updateTile() { super.updateTile(); @@ -27,7 +32,7 @@ public void 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); + float ventEfficiency = ventScaling.apply((liquids.get(liquid)/liquidCapacity - minPressure)/(1 - minPressure)); if(ventEfficiency > 0){