Jump to content

Looping through a table of all recipes


ethanwdp

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?

Link to comment
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
Link to comment
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()

Link to comment
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)

Link to comment
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.

Link to comment
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
Link to comment
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

Link to comment
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.

Link to comment
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.

Link to comment
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.

Link to comment
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.

Link to comment
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.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...