Page 1 of 2

Party starting items.

Posted: Wed Dec 17, 2014 11:15 pm
by Thorham
Seeing how the original thread author removed their scripts, I've made a new thread with a new script.

Currently allows defining of left and right hand weapons per class, including stack size for throwing items and ammo (both hands). Allows defining equipable items for all non-weapon slots per class. Allows defining one or more food items per race. Allows defining one or more items for the party. Party items must fit in the inventory of one single champion, and the first available champion is selected for this. The script currently doesn't check if there is enough inventory space for items.

Call the function startItems() to equip the party.

Don't hesitate to ask for additions and changes :)

Code: Select all

classWeapons = {}
classWeapons["alchemist"] = {
    leftHand = "rock", leftStack = 3,
    rightHand = "", rightStack = 0
    }

classWeapons["barbarian"] = {
    leftHand = "bone_club", leftStack = 0,
    rightHand = "", rightStack = 0
    }

classWeapons["battle_mage"] = {
    leftHand = "rock", leftStack = 3,
    rightHand = "", rightStack = 0
    }

classWeapons["farmer"] = {
    leftHand = "rock", leftStack = 3,
    rightHand = "", rightStack = 0
    }

classWeapons["fighter"] = {
    leftHand = "branch", leftStack = 0,
    rightHand = "", rightStack = 0
    }

classWeapons["knight"] = {
    leftHand = "branch", leftStack = 0,
    rightHand = "", rightStack = 0
    }

classWeapons["rogue"] = {
    leftHand = "rock", leftStack = 3,
    rightHand = "", rightStack = 0
    }

    classWeapons["wizard"] = {
    leftHand = "rock", leftStack = 3,
    rightHand = "", rightStack = 0
    }

classArmor = {}

classArmor["alchemist"] = {
    head     = "",
    necklace = "",
    cloak    = "",
    chest    = "tattered_shirt",
    gloves   = "",
    bracers  = "",
    legs     = "torn_breeches",
    feet     = "sandals"
    }

classArmor["barbarian"] = {
    head     = "",
    necklace = "",
    cloak    = "",
    chest    = "tattered_shirt",
    gloves   = "",
    bracers  = "",
    legs     = "torn_breeches",
    feet     = "sandals"
    }

classArmor["battle_mage"] = {
    head     = "",
    necklace = "",
    cloak    = "",
    chest    = "tattered_shirt",
    gloves   = "",
    bracers  = "",
    legs     = "torn_breeches",
    feet     = "sandals"
    }

classArmor["farmer"] = {
    head     = "",
    necklace = "",
    cloak    = "",
    chest    = "tattered_shirt",
    gloves   = "",
    bracers  = "",
    legs     = "torn_breeches",
    feet     = "sandals"
    }

classArmor["fighter"] = {
    head     = "",
    necklace = "",
    cloak    = "",
    chest    = "tattered_shirt",
    gloves   = "",
    bracers  = "",
    legs     = "torn_breeches",
    feet     = "sandals"
    }

classArmor["knight"] = {
    head     = "",
    necklace = "",
    cloak    = "",
    chest    = "tattered_shirt",
    gloves   = "",
    bracers  = "",
    legs     = "torn_breeches",
    feet     = "sandals"
    }

classArmor["rogue"] = {
    head     = "",
    necklace = "",
    cloak    = "",
    chest    = "tattered_shirt",
    gloves   = "",
    bracers  = "",
    legs     = "torn_breeches",
    feet     = "sandals"
    }

classArmor["wizard"] = {
    head     = "",
    necklace = "",
    cloak    = "",
    chest    = "tattered_shirt",
    gloves   = "",
    bracers  = "",
    legs     = "torn_breeches",
    feet     = "sandals"
    }

partyItems = {
    "torch",
    "compass",
    "timepiece",
    "rope",
    "sack"
    }

raceItems = {}
raceItems["human"] = {"rotten_pitroot_bread"}
raceItems["insectoid"] = {"baked_maggot"}
raceItems["lizardman"] = {"boiled_beetle"}
raceItems["minotaur"] = {"mole_jerky"}
raceItems["ratling"] = {"cheese"}

function startItems()
    local a
    for a = 1, 4 do
        local champion = party.party:getChampion(a)
        if champion:getEnabled() == true then
            unequipChampion(champion)
            addChampionItems(champion)
        end
    end
    addPartyItems()
end

function unequipChampion(champion)
    local b
    for b=1,32,1 do
        champion:removeItemFromSlot(b)
    end
end

function addItem(champion,slot,itemName,stackSize)
    if itemName ~= "" then
        local item = spawn(itemName)
        if stackSize > 0 then
            item.item:setStackSize(stackSize)
        end
        champion:insertItem(slot,item.item)
    end
end

function getFirstEmptySlot(champion)
    local a
    for a = 13, 32 do
        if champion:getItem(a) == nil then
            return a
        end
    end
    return 0
end

function addChampionItems(champion)
    local cWeapons = classWeapons[champion:getClass()]
    local cArmor = classArmor[champion:getClass()]
    local rItems = raceItems[champion:getRace()]

    addItem(champion,  1, cWeapons.leftHand, cWeapons.leftStack)
    addItem(champion,  2, cWeapons.rightHand, cWeapons.rightStack)
    addItem(champion,  3, cArmor.head, 0)
    addItem(champion,  4, cArmor.chest, 0)
    addItem(champion,  5, cArmor.legs, 0)
    addItem(champion,  6, cArmor.feet, 0)
    addItem(champion,  7, cArmor.cloak, 0)
    addItem(champion,  8, cArmor.necklace, 0)
    addItem(champion,  9, cArmor.gloves, 0)
    addItem(champion, 10, cArmor.bracers, 0)

    local slot = getFirstEmptySlot(champion)
    local a
    for a, item in ipairs(rItems) do
        addItem(champion, slot, item, 0)
        slot = slot + 1
    end
end

function addPartyItems()
    local a
    for a = 1, 4 do
        local champion = party.party:getChampion(a)
        if champion:getEnabled() then
            local slot = getFirstEmptySlot(champion)
            if slot > 0 then
                for b, itemName in ipairs(partyItems) do
                    addItem(champion, slot, itemName, 0)
                    slot = slot + 1
                end
                break
            end
        end
    end
end

Re: Party starting items.

Posted: Wed Dec 17, 2014 11:42 pm
by msyblade
Good stuff, 3 Kudos awarded!

Re: Party starting items.

Posted: Wed Dec 17, 2014 11:55 pm
by Batty
Nice script, for my party init scripts, I call them all with delayedCall because if they execute on start they conflict with the editor's new feature of remembering your party's state. I was getting some odd errors.

An in-editor issue only, I think. Just mentioning in case someone else has the same errors.

Re: Party starting items.

Posted: Sat Feb 28, 2015 2:39 am
by Grimfan
So I come back after a break from my Grimrock 2 mod and start it up again. However, when I do so, this script keeps throwing up an error telling me that it "cannot serialize table 'champion' with metatable". This error popping up next to classWeapons. Now, the script was working perfectly beforehand and I haven't changed anything else, so has one of the updates changed something about how tables and metatables interact?

By the way, the script is virtually identical to Thorham's script above with the exception of a few items. In other words, the nuts and bolts of the script are unchanged and was working previously without a hitch.

Re: Party starting items.

Posted: Sat Feb 28, 2015 6:12 am
by Frenchie
Show us the script. Maybe you accidentally added an item on a wrong slot or the item doesn't exist in-game

Re: Party starting items.

Posted: Sat Feb 28, 2015 6:24 am
by minmay
That error means that you are storing a reference to an instance of the Champion class which is unserializable. You're storing it in a field named "champion". See this thread.

Re: Party starting items.

Posted: Sat Feb 28, 2015 10:00 am
by Grimfan
Damn, I remember reading that post several weeks ago and since I've been out of the game I promptly forgot about it. Of course, what still confuses me is that I ran the editor several times with this script running without a problem and it suddenly decides to make it an error? What changed between the second, third or fourth time I ran the script and the time it decided to stop functioning?

So, would Thorham's script be saved through judicious use of the local keyword, or does the script need a complete overhaul from the bones up?

Re: Party starting items.

Posted: Sat Feb 28, 2015 11:00 am
by minmay
Serialization errors only occur when the game is saved, since that's the only time anything gets serialized. The script in Thorham's post looks clean to me (though I haven't tested it). The offending line in your code will be something like:

Code: Select all

champion = [something unserializable]
If this variable is in a block, and you don't need to store this reference after its block ends, use the "local" keyword to make it a temporary variable and solve the problem:

Code: Select all

local champion = [something unserializable, which doesn't matter now that it's temporary]
If you do need to store this reference after its block ends, or it's not in a block at all, then you need to overhaul your code, because you can't do that. Instead, try storing the ordinal number of the champion and retrieving them with party.party:getChampionByOrdinal(). Numbers can be serialized.

Re: Party starting items.

Posted: Sun Mar 01, 2015 9:54 am
by Grimfan
Thanks minmay. As you suggested it was a simple omission that caused the error. The script is now running smoothly (at least in the editor).

Re: Party starting items.

Posted: Mon Mar 02, 2015 5:00 pm
by Thorham
minmay wrote:The script in Thorham's post looks clean to me (though I haven't tested it).
It is. I just tested it to make sure and it allows saving properly. It's supposed to be a basic replacement for an earlier starting items script that the author removed because of serialization problems.