SquidDev-CC / plethora

A peripheral provider for ComputerCraft
https://plethora.madefor.cc/
MIT License
57 stars 21 forks source link

Tinker's Construct Peripheral #114

Closed shelbykauth closed 6 years ago

shelbykauth commented 6 years ago

This is an enhancement request. Would it be possible to add peripheral support for TConstruct Smeltry and Tank controllers?

Currently, the methods available on these controllers are all the same as the chest peripheral. Granted, that is useful for the Smeltry and Furnace controllers. But I want to automate the production of tconstruct parts (and maybe the production of whole tools as well). Like, allowing a player to request an iron tool binding and ten manyllyum sharpening kits. Currently, if I want to do this, I have to have a separate tank for each liquid. I can't change the order of the liquids without right clicking on the tank controller. Now, I can see the bottom-most "tank" of the TinkerTank via wrapping to a drain and using p.getTanks(), and that does enable some possibilities. But it's a bit clunky.

My current plan is to either have a large number of in-place TinkerTanks, one for each liquid, and use either casting channels or "Thirsty Turtles" from Peripherals Plus One to transport the liquid, or to store stacks of seared tanks with the appropriate liquid in them in chests, bring them out (using my inventory system), place them with turtles, and cast from the tanks. To use the seared tanks, though, my inventory system would grow by quite a bit because I'm storing info based on nbtHash where available. So every different volume of every different liquid would end up getting its own inventory slot. And I'd have to keep track of which nbtHash has each liquid. To use casting channels or Thirsty Turtles, it would take a fair amount of time to get to and from the appropriate TinkerTanks. Casting Channels can break sometimes, and I don't really like Peripherals Plus One that much (the docs are so broken) I would prefer to require as few mods as possible for the Program/API I'm writing, and prefer Plethora over Peripherals Plus One. I could use two tanks and transfer liquid back and forth between them, cycling it through until I find the right liquid. But that would take even more time.

The solution I'm looking for is to be able to hook into the tank part of the Smeltry and TinkerTank blocks, have an ordered list of each liquid p.getTanks(), and have a method to select which one to move to the bottom. p.selectLiquid(7), for instance. (assuming p is the wrapped peripheral). It would preferably do the same thing as right-clicking the liquid in the Smeltry/TinkerTank GUI. And perhaps a p.capacity() to get the max limit of liquid.

Perhaps the Smeltry and Furnace would have p.getFuel() and p.getMaxFuel() as well, to check how much lava is available for heating. That could be applied evenly to the TinkerTank where p.getMaxFuel() returns 0. (Like how p.size() returns 0)

This enhancement would allow automation of casting with a single Smeltry or TinkerTank, reducing the time to two ticks (to get the order and change the order) plus however long it takes to fill up the casting table. I have no idea where to look for figuring out which files would be added or changed. And I'm not sure how difficult this is to accomplish. But it would be awesome.

shelbykauth commented 6 years ago

Well... I am leaps and bounds closer than I was yesterday to being able to contribute to a mod. Tinker's is open source on Github, too. So that bodes well. Unfortunately, I have no idea how to build with Gradle, so I'm kinda at a loss as to how to test any code for this. I'm not entirely sure that I'm doing this right, but I found what seems to be the reordering method in TConstruct from this file.

I'm basing this code off of the IC2 integration MethodsEnergy.java (and other method integration files). So far, this is what I've got:

package org.squiddev.plethora.integration;

import slimeknights.tconstruct.smeltery.network.SmelteryFluidClicked;

public class MethodsControllers {
    @BasicObjectMethod.Inject(
        value = SmelteryFluidClicked.class, worldThread = true, modId = TConstruct.modID,
        doc = "function(integer)-- Move the selected fluid to the bottom of the tank for retrieval."
    )
    public static Object[] selectFluid(IContext<SmelteryFluidClicked> target, Object[] args) {
        target.getTarget().SmelteryFluidClicked(args[0]);
        return new Object[]{};
    }
}

I'm not looking for a code review or anything.(that will come if I get this working. That's a big if.) Though I would like some pointers on how to build gradle and test. (I'm using Atom, not Eclipse, so the tutorials don't really apply as well as I had hoped.)

SquidDev commented 6 years ago

Sorry for the delay in responding. Yeah, this is definitely possible to add though I'm not entirely sure how I'd want selectLiquid to behave (just chucking in an index seems a little ugly, but I'm not sure of an alternative).

WRT Gradle, it should be possible to use ./gradlew runClient to launch an instance of Minecraft with your modifications. You may need to run ./gradlew setupDecompWorkspace first (be patient, this takes 4-5 minutes to run). I would heartily recommend installing Eclipse or IntelliJ though, as they do make life easier.

WRT your method, it should probably look a something like:

public static MethodResult selectFluid(IUnbakedContext<TileSmelteryComponent> smeltery, Object[] args) throws LuaException {
    int index = getInt(args, 0);
    return MethodResult.nextTick(() -> {
        TileSmelteryComponent component = smeltery.bake().getTarget();
        if (!component.getHasMaster()) throw new LuaException("Cannot find smeltery");

        TileEntity te = component.getWorld().getTileEntity(component.getMasterPosition());
        if (!(te instanceof ISmelteryTankHandler)) throw new LuaException("Cannot find smeltery");

        SmelteryTank tank = ((ISmelteryTankHandler) te).getTank();
        // TODO: Add bounds checks
        tank.moveFluidToBottom(index);

        return null;
    });
}

I'm happy to provide any additional pointers if needed, I'm fully aware Plethora's internals are not especially well documented (nor is the actual mod come to think of it). That being said, don't feel you have to - I will get round to it, but I am always happy to see new people contributing!

shelbykauth commented 6 years ago

Yyeeaaahhh... this looks a fair bit more complicated than I thought. For instance, I can't figure out why it's ISmelteryTankHandler that we want instead of SmelteryFluidClicked. Though I'm a decent general programmer (everything from C#, PHP, and JavaScript to Lua, actual Fanuc robots, and PLCs), I struggle with the setup. Things like building, making sure I have all the files, import statements, etc. It took me two years on and off of trying to reverse engineer minecraft mods to make my own, including following a bunch of not-so-great tutorials, before I gave up, took a course in Java, and found out the difference between precompiled and compiled-at-runtime, excelling in all the coursework after that. Still haven't been able to apply it outside of school though. But taking that course did help me learn Unity C#.

And maybe it's just been a long day, but trying to figure out why these things goes there (and therefore what goes where) is making my brain melt. The amount of time I've spent around Minecraft mods, combined with my lack of success in modding the mods, is kinda embarrassing. I've been programming (javaScript) since I was eight, with all sorts of programming languages thrown at me, and I've handled it all well. Until I get to mc mods. Then it all goes to the wolves. I've got to hand it to you, it takes a lot of knowledge, patience, and persistence to do mods. Keep up the good work.

SquidDev commented 6 years ago

I've added the following couple of methods, just to check this fits what you need? I've put together a build just in case you want to try it out in-game.

I'm not entirely sure about the method names (or the interface for that matter), so do tell me if there's changes you'd like to see made.

And maybe it's just been a long day, but trying to figure out why these things goes there (and therefore what goes where) is making my brain melt.

Yeah, the ecosystem is a bit of a mess. You get used to the quirks of how everyone implements things pretty quickly, but it's grotty :).

shelbykauth commented 6 years ago

So I tried out the new build. It doesn't seem to have changed anything. I disabled PeripheralsPlusOne, just to be sure it wasn't overwriting Plethora's peripheral stuff. But I'm still only getting the following functions when I wrap to a tinker_tank or to a smeltery: drop, getDocs, getItem, getItemMeta, getMetadata, getTransferLocations, list, pullItems, pushItems, size, suck

As for the method names, I was thinking selectFluid and getFluids was more intuitive, as water, blood, milk, forestry beer and sap, and other fluids can also be in smelteries and tanks, but your names still make sense.

I'm not sure what getFuels() returns exactly, though. Would it typically be a list of one? {{name="minecraft:lava", amount=1000,}}, something like that?

==Edit== Uh, heh heh... Found the functions! They're attached to Seared Tanks instead of Smelteries and Tinker_Tank structures. Will test to see if it's also attached to Seared Gauges and Seared Windows. I think it probably will be.

SquidDev commented 6 years ago

Uh, heh heh... Found the functions! They're attached to Seared Tanks instead of Smelteries

Ahhh right, I entirely forgot about the actual controller. The methods should appear on any block in the multiblock aside from the controller - I'll fix that shortly so it appears on all of them.

shelbykauth commented 6 years ago

Okay, so upon further testing. Yes, all the blocks I've tried that can be part of the smeltery or tank (so seared bricks, seared tanks, drains, seared gauge, etc) has these functions. Even if they're not currently part of a structure. I don't currently see a way to tell code-wise if it's actually connected or not, until the error comes up.

Also, I believe that turtles could place buckets of fluid into drains and tanks/gauges/windows before. But I'm not sure. It certainly cannot now. Maybe I'm mixing up memories with PeripheralsPlusOne Thirsty Turtle. If it could not before, then that is a separate issue enhancement, and this paragraph can be ignored.