Jump to content
ethanwdp

Looping through a table of all recipes

Recommended Posts

(sorry for the double post!)

I've been trying to get the string ID for recipes and making the player learn it, by looping through a table of all recipes.

Problem is, getAllRecipes() returns userdata. Converting it to a string doesn't do jack, converting it to a number doesn't do jack, and it returns the Java location. Problem is, anything after zombie.scripting.objects.Recipe is just gibberish, for example zombie.scripting.objects.Recipe@287cbb10.

 

Am I on the wrong track here?

Share this post


Link to post
Share on other sites

(sorry for the double post!)

I've been trying to get the string ID for recipes and making the player learn it, by looping through a table of all recipes.

Problem is, getAllRecipes() returns userdata. Converting it to a string doesn't do jack, converting it to a number doesn't do jack, and it returns the Java location. Problem is, anything after zombie.scripting.objects.Recipe is just gibberish, for example zombie.scripting.objects.Recipe@287cbb10.

 

Am I on the wrong track here?

Have you tried iterating over the "userdata" returned by getAllRecipes()? Chances are, it's a java array.

 

local function convertUserdata(ud)    local t = {};    for i = 1, ud:size() do        t[i] = ud:get(i - 1);    end    return t;end

Share this post


Link to post
Share on other sites

local recipes = getAllRecipes();

for i = 0, recipes:size()-1 do

    local recipe = recipes:get(i);

    print("Recipe ["..recipe:getOriginalname().."] from module "..recipe:getModule():getName());

end

Share this post


Link to post
Share on other sites

Oh, so that's what I've been missing. I'm not familiar with size(), guess I'll read up on it.

 

By the way, by userdata I meant what type(getAllRecipes()) returned. I didn't know what to do with it :P

 

All of my other attempts included looping through it, but I didn't use size()

Share this post


Link to post
Share on other sites

It's an ArrayList of Recipes though I guess that function was added in build 32 and so it's not in the public javadocs.

 

Not really sure why it was added tbh given that scriptmanager is already exposed and it's just a copy of the stack in ArrayList form from ScriptManager's getAllRecipes()

 

I don't think userdata is really relevant here.

Share this post


Link to post
Share on other sites

Problem:

 

Adding the recipe to knownRecipes causes errors galore, and corrupts the save.

 

Code:
 

local recipe = getAllRecipes()
for i = 0,recipe:size() - 1 do
    getPlayer():getKnownRecipes():add(recipe:get(i))
end

 

Error:

 

Aug 21, 2015 6:10:25 PM zombie.GameWindow run
SEVERE: null
java.lang.ClassCastException: zombie.scripting.objects.Recipe cannot be cast to java.lang.String
    at zombie.characters.IsoGameCharacter.save(IsoGameCharacter.java:4740)
    at zombie.characters.IsoPlayer.save(IsoPlayer.java:900)
    at zombie.iso.IsoCell.savePlayer(IsoCell.java:5365)
    at zombie.GameWindow.savePlayer(GameWindow.java:1731)
    at zombie.iso.IsoWorld.render(IsoWorld.java:2036)
    at zombie.gameStates.IngameState.renderframe(IngameState.java:769)
    at zombie.gameStates.IngameState.render(IngameState.java:913)
    at zombie.gameStates.GameStateMachine.render(GameStateMachine.java:37)
    at zombie.GameWindow.render(GameWindow.java:685)
    at zombie.GameWindow.run(GameWindow.java:1193)
    at zombie.GameWindow.maina(GameWindow.java:991)
    at zombie.gameStates.MainScreenState.main(MainScreenState.java:165)

Share this post


Link to post
Share on other sites

Can't access the link, but I'd say yes. What I meant to tell ethan is that size() is not a lua function, but instead a java function which is accessible through the metatables in the userdata.

Aug 21, 2015 6:10:25 PM zombie.GameWindow run

SEVERE: null

java.lang.ClassCastException: zombie.scripting.objects.Recipe cannot be cast to java.lang.String

This means the add() function wants a string. Check Brybry's post again: You need to get the recipe's name.

Share this post


Link to post
Share on other sites

For efficiency you can do something like this:

local recipes = getAllRecipes();local knownRecipes = getPlayer():getKnownRecipes();for i = 0, recipes:size()-1 do    local recipe = recipes:get(i);    if recipe:needToBeLearn() and not knownRecipes:contains(recipe:getOriginalname()) then        knownRecipes:add(recipe:getOriginalname());        --print("Added Recipe ["..recipe:getOriginalname().."] from module "..recipe:getModule():getName());    endend

Share this post


Link to post
Share on other sites

Efficiency doesn't really matter that much, though.

Do what you're comfortable with at first. :)

I usually go with efficiency, mainly because it looks all shiny and fancy. :P

 

Something like:

print(1)print(2)print(3)print(4)print(5)

looks much less shiny than

for i = 1,5 do   print(i)end

EDIT:

 

Also, completed recipe learning code:

 

CheatCoreCM.DoLearnRecipes = function()

    local recipes = getAllRecipes()

    for i = 0,recipes:size() - 1 do

        local recipe = recipes:get(i)

        if not getPlayer():isRecipeKnown(recipe) and recipe:needToBeLearn() then

            getPlayer():getKnownRecipes():add(recipe:getOriginalname())

            getPlayer():Say("All recipes learned.")

        end

    end

end

Share this post


Link to post
Share on other sites

Just curious, is there a way to change a variable that isn't in an array?

 

For example, the public Capacity variable in the ItemContainer returned by getPlayer():getInventory().

 

I could return it with getCapacity(), but I don't know what to do from there.

Share this post


Link to post
Share on other sites

Just curious, is there a way to change a variable that isn't in an array?

 

For example, the public Capacity variable in the ItemContainer returned by getPlayer():getInventory().

 

I could return it with getCapacity(), but I don't know what to do from there.

You used to be able to with java reflection but that was a security issue and so was taken out.

 

Since there is no setCapacity() you have to be clever and use something else to get the same effect. In this case you can probably use some combination of getPlayer():setMaxWeight, getPlayer():setMaxWeightBase, and getPlayer():setMaxWeightDelta and/or getPlayer():getWeightMod()

 

Something like:

local targetWeight = 50;getPlayer():setMaxWeightBase(targetWeight / getPlayer:getWeightMod());

Note that BodyDamage:UpdateStrength() still applies modifiers from hunger and well fed and strength (getWeightMod() is the strength modifier) so if you have to also potentially detect and adjust for those.

 

Also, of the player has god mode that might not work (as I think it might then ignore BodyDamage:UpdateStrength()'s modifiers) and so a simple getPlayer():setMaxWeight(50); would probably work in that case.

I don't think the weight values save between sessions either so they probably have to be applied when appropriate.

Share this post


Link to post
Share on other sites

 

Just curious, is there a way to change a variable that isn't in an array?

 

For example, the public Capacity variable in the ItemContainer returned by getPlayer():getInventory().

 

I could return it with getCapacity(), but I don't know what to do from there.

You used to be able to with java reflection but that was a security issue and so was taken out.

 

Since there is no setCapacity() you have to be clever and use something else to get the same effect. In this case you can probably use some combination of getPlayer():setMaxWeight, getPlayer():setMaxWeightBase, and getPlayer():setMaxWeightDelta and/or getPlayer():getWeightMod()

 

Something like:

local targetWeight = 50;getPlayer():setMaxWeightBase(targetWeight / getPlayer:getWeightMod());

Note that BodyDamage:UpdateStrength() still applies modifiers from hunger and well fed and strength (getWeightMod() is the strength modifier) so if you have to also potentially detect and adjust for those.

 

Also, of the player has god mode that might not work (as I think it might then ignore BodyDamage:UpdateStrength()'s modifiers) and so a simple getPlayer():setMaxWeight(50); would probably work in that case.

I don't think the weight values save between sessions either so they probably have to be applied when appropriate.

 

Capacity itself has to be set above 50. I want to achieve infinite carryweight.

 

Problem is, when your current inventory weight is over the capacity (50), you can't take or store items from a container.

Share this post


Link to post
Share on other sites

For infinite carry weight then you could hook the item transfer timed action and make the items weigh 0 when putting them on a player and then put them back to their original weight when transferring them to a container/ground/anywhere that's not the player. Might have to be done on game start as well depending if item weight saves or not.

Or you could even do something crazy like add an invisible item with negative weight to the player's inventory.

 

And there's probably something that can be hooked to fix the weight transfer over capacity issue but I haven't looked into it for the cause of that yet.

Most of that stuff is done in lua and thus mutable.

Share this post


Link to post
Share on other sites

As for making items have 0 weight, there would be a problem if somebody quit the game with the cheat on. Since weight does not reset back to normal on game load (AFAIK, at least), this would cause permanent changes to a save - something I'd want to avoid.

 

As for an invisible item with negative weight, that's very interesting. I'll see if that works or not.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...