uecasm / colony4cc

MineColonies for ComputerCraft integration addon mod for Minecraft
GNU General Public License v3.0
7 stars 8 forks source link

Colony.getCitizens() codes not working #28

Closed LionoftheWest closed 7 months ago

LionoftheWest commented 7 months ago

When running a script to pull status' and citizens jobs, they weren't able to be processed. They came up as a nil value. Other commands still work (age for example)

Here is the SS of the error: image

here is the Line it is talking about: mPrintRowJustified(monitor, row, "right", citizen.status, textColor)

According to the wiki, citizen.status should be the correct usage. This also applies to citizen.job.

I have only tested the string related commands so not sure if there are other ones that are coming up as nil values.

Modpack ATM 8 v1.1.0 Minecolonies 1.19.2-1.1.352-BETA.jar Colony4CC 1.19.2-2.3.4.jar

LionoftheWest commented 7 months ago

Computer.txt Here is a copy of the entire code

LionoftheWest commented 7 months ago

Continuing on this, it seems that when you pull the citizens job status, it comes over as nil. So the string citizen.job does not work and needs to be fixed

LionoftheWest commented 7 months ago

Updated script: Computer (Working).txt

uecasm commented 7 months ago

The "colony integrator" is not from this mod. You're probably using Advanced Peripherals instead, which copied my API but not precisely. So the wiki docs here don't apply.

LionoftheWest commented 7 months ago

I fixed and used the colony peripheral and still ran into the same problem with strings. Here is the error code: image

and the script being ran

Computer.txt

It works for the 'type' string but does not work for 'upgrade', 'upgradeLevel', and 'structureName'

uecasm commented 7 months ago

Again, this mod does not contain a "colony integrator" peripheral. At all.

    local colony = peripheral.find("colonyIntegrator")

This line means you are not using this mod.

LionoftheWest commented 7 months ago

It uploaded the incorrect one, here is the actual code that I am using that is using the correct mod: This script works with the "type" string however when you input the "upgrade", "structureName", and "upgradeLevel", the script no longer works and gets the nil value

local expect = require "cc.expect".expect

-- Find and initialize the peripheral monitor local monitor = peripheral.find("monitor") if not monitor then print("Monitor not found.") return end monitor.setTextScale(.5)

-- Function to print strings left, centered, or right justified at a specific row and specific foreground/background color function mPrintRowJustified(mon, y, pos, text, ...) expect(1, mon, "table") expect(2, y, "number") expect(3, pos, "string") expect(4, text, "string") expect(5, arg[1], "number", "nil") expect(6, arg[2], "number", "nil")

local w, h = mon.getSize()
local fg = mon.getTextColor()
local bg = mon.getBackgroundColor()

local x
if pos == "left" then 
    x = 1 
elseif pos == "center" then 
    x = math.floor((w - #text) / 1.8) 
elseif pos == "right" then 
    x = w - #text 
end

if #arg > 0 then 
    mon.setTextColor(arg[1]) 
end
if #arg > 1 then 
    mon.setBackgroundColor(arg[2]) 
end

mon.setCursorPos(x, y)
if text then -- Only write text if it's not nil
    mon.write(text)
end
mon.setTextColor(fg)
mon.setBackgroundColor(bg)

end

-- Function to get builder statuses and display them on the monitor function displayBuilderStatusesOnMonitor(monitor) -- Get the list of citizens local citizens = colony.getCitizens() if not citizens then monitor.clear() monitor.setCursorPos(1, 1) monitor.write("No citizens found.") return end

-- Initialize variables for row and header
local row = 2
local headerShown = false

-- Show title
mPrintRowJustified(monitor, row, "center", "Builder Status:", colors.white)
row = row + 2

-- Loop through citizens to display builder statuses
for _, citizen in ipairs(citizens) do
    -- Check if the citizen is a builder
    if citizen.job == "Builder" then
        -- Show header if not shown already
        if not headerShown then
            mPrintRowJustified(monitor, row, "left", "Name", colors.white)
            mPrintRowJustified(monitor, row, "center", "Status", colors.white)
            mPrintRowJustified(monitor, row, "right", "Work Order", colors.white)
            row = row + 1
            headerShown = true
        end

        -- Fetch work orders
        local workOrders = colony.getWorkOrders()
        local currentWorkOrder = "None"
        if workOrders and #workOrders > 0 then
            currentWorkOrder = workOrders[1].type
        end

        -- Display citizen name, status, and current work order
        mPrintRowJustified(monitor, row, "left", citizen.name, colors.yellow)
        mPrintRowJustified(monitor, row, "center", citizen.status, colors.yellow)
        mPrintRowJustified(monitor, row, "right", currentWorkOrder, colors.yellow)
        row = row + 1
    end
end

end

-- Loop to continuously update the monitor every 10 seconds while true do -- Call the function to display builder statuses on the monitor displayBuilderStatusesOnMonitor(monitor) -- Wait for 10 seconds before updating again sleep(10) end

uecasm commented 7 months ago

This script works with the "type" string however when you input the "upgrade", "structureName", and "upgradeLevel", the script no longer works and gets the nil value

I don't know what you mean by this, that isn't anywhere in your code. If you want help, you do need to supply the actual code you're having trouble with and the exact error you're getting.

Though FWIW, your code to get the work orders looks wrong; you're asking for the first work order in the colony regardless of who it's assigned to. If you want the work order for a specific builder, you need to match the claimedByBuilding against the builder's work.location.

It's probably also worth mentioning that the format of a work order's details may differ in different versions of Minecolonies and different types of work order. For best results, try running textutils.serialize(order) and examine the output to see what properties exist on it, or otherwise inspect the data you get back rather than making assumptions.

LionoftheWest commented 7 months ago

Okay, this is what I'm talking about when it comes to inputting the strings: image

My intention with this program is to be able to grab the status of the builder AND if they aren't currently working on something since having 16+ builders in a colony, its hard to keep track of who is doing what.

I have inputted these exact commands into the script to pull that info, using what is in the wiki and they come out as a nil value. The ONLY one that does not come through as a nil value is the "type" command in the wiki screenshot.

Here are the scripts for EACH of the other strings ("upgrade, "structureName", "upgradeLevel") from the WIKI Screenshot and their results showing up as nil values: (I recognize the screenshots all look the same but each were from the individual runs)

Upgrade:

image upgrade Script.txt

StructureName:

image structureName Script.txt

UpgradeLevel

upgradeLevel Script.txt image

As for your suggestion, (thank you for it!) I of course would like the work orders to be assigned to the respective builder who's doing it, how would you recommend I rewrite it so that the work order is placed to the correct builder and shows up? Because the current way it works is it just shows that they are "building" under the type string vs actually showing what they are working on (Screenshot)

2024-02-17_18 34 38

Here is the script that works to provide the screenshot, you'll see that it is using the 'type' in it on line 84: Computer (Working).txt

uecasm commented 7 months ago

Here are the scripts for EACH of the other strings ("upgrade, "structureName", "upgradeLevel") from the WIKI Screenshot

That was the point of "different order types will have different data, this is just an example" above the table. Unlike most of the other methods (which have a more well-defined structure), getWorkOrders returns the internal data of the orders, which is highly dependent on the order type (and the MineColonies version).

Currently, the wiki is documenting what the format mostly looked like in 1.16. As of 1.19, though, things changed very significantly, and the data structure is now entirely different from that. Try running the following in a lua prompt (or a program):

for k,v in pairs(colony.getWorkOrders()[1]) do print(k) done

This will print the keys that are actually present in the work order, most of which should not be nil. Or, as I said before, you can just serialize it. Note that they will still be different between builder work orders, miner work orders, removal orders, etc.

Having said that, this has given me some ideas for improvements in this area.

LionoftheWest commented 7 months ago

Okay I ran 'for k,v in pairs(colony.getWorkOrders()[1]) do print(k) done' and got this Screenshot: 2024-02-19_12 51 07

I went through the original code (Computer (Working).txt)to ln 84 and put in 'workOrders[1].translationKey' and got this result: 2024-02-19_12 57 59

So it looks like 'translationKey' might be the new format for getting the work order on what the builder is actually working on. Now the key would be to have it run for each individual builder because with the previous mention script, its only pulling the 1 order and pushing it out to all the other builders. I tried removing the '[1]' however it came up with a nil error.

Will continue to test to see...we're getting close!

LionoftheWest commented 7 months ago

So updates: After working through it all, it seems like in the current serialized data of work orders, there is no way to tell what builder is building it. There isn't any data on it. Here is the screenshot of the serialized work order data:

image

I am currently running this script and it originally had an "Assigned Builders" Category trying to pull from the Work Order data to see if there was any crossover. It didn't come up with anything. Here is the script for you to check:

Work.txt

This script pulls up this on the display (which is great progress!) 2024-02-21_14 52 26

However there is still no way that I can see a way to connect the Work Order ID and the Builder actually doing it based on the data provided.

Any insights on your end?

uecasm commented 7 months ago

As I said above, the claimedByBuilding is which builder is working on it, matching the work.location of the builder themselves, or the location of their actual building.

Note that it's valid for this to be nil, if nobody has started working on it yet.

You can use the vector lib to do quick comparisons of locations.

LionoftheWest commented 7 months ago

We finally got it going! Yayyyy after all this haha Here's the script that finally did it all: Work.txt 2024-02-22_17 47 58

I also configured it to work on the pocket computer as well so it makes life very much easier.

So now my next question is, with the getbuilderresources command, does that give the entire work orders resources that you can access from the gui on the builder block?

uecasm commented 7 months ago

Yep.