Starting Items for Party

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
Post Reply
User avatar
Sutekh
Posts: 129
Joined: Sun Nov 25, 2012 9:58 am
Location: UK

Starting Items for Party

Post by Sutekh »

I was going to post this in NutJob's topic on the subject, but he appears to have abandoned it, so I figured I'd make a fresh start.
I'm not even going to try anything clever or complicated (at least not yet anyway), I'd rather just begin with the simple basics.


1: WHAT GOES WHERE
1 = Current active Left Hand
2 = Current active Right Hand
3 = Head
4 = Chest
5 = Legs
6 = Feet
7 = Cloak
8 = Necklace
9 = Gloves
10 = Bracers
11 = Current inactive Left Hand
12 = Current inactive Right Hand
13 - 32 = Backpack
SpoilerShow
Image
2: ADDING SOME BASIC ITEMS
While it is possible to do this outside of a function, I found the editor isn't always happy if I do, and gives some interesting error messages, especially the first time I load it. So, I've used a function triggered by a timer to avoid this problem.
First, place a timer and set the timerInterval to 0.01 seconds and make sure the timer and disableSelf boxes are both checked.
Now place a script_entity and add the following script:

Code: Select all

function startItems()

local i = 1
   repeat
   if party.party:getChampion(1):getEnabled() then
      party.party:getChampion(1):removeItemFromSlot(i)
      end
   if party.party:getChampion(2):getEnabled() then
      party.party:getChampion(2):removeItemFromSlot(i)
      end
   if party.party:getChampion(3):getEnabled() then
      party.party:getChampion(3):removeItemFromSlot(i)
      end
   if party.party:getChampion(4):getEnabled() then
      party.party:getChampion(4):removeItemFromSlot(i)
      end
   i = i + 1
   until i == 33

if party.party:getChampion(1):getEnabled() then
   party.party:getChampion(1):insertItem(1,spawn("compass").item)
   party.party:getChampion(1):insertItem(2,spawn("dagger").item)
   party.party:getChampion(1):insertItem(4,spawn("peasant_tunic").item)
   party.party:getChampion(1):insertItem(5,spawn("peasant_breeches").item)
   party.party:getChampion(1):insertItem(6,spawn("sandals").item)
   end

if party.party:getChampion(2):getEnabled() then
   party.party:getChampion(2):insertItem(1,spawn("torch").item)
   party.party:getChampion(2):insertItem(4,spawn("peasant_tunic").item)
   party.party:getChampion(2):insertItem(5,spawn("peasant_breeches").item)
   party.party:getChampion(2):insertItem(6,spawn("sandals").item)
   end

if party.party:getChampion(3):getEnabled() then
   party.party:getChampion(3):insertItem(2,spawn("rock").item)
   party.party:getChampion(3):insertItem(4,spawn("peasant_tunic").item)
   party.party:getChampion(3):insertItem(5,spawn("peasant_breeches").item)
   party.party:getChampion(3):insertItem(6,spawn("sandals").item)
   end

if party.party:getChampion(4):getEnabled() then
   party.party:getChampion(4):insertItem(4,spawn("peasant_tunic").item)
   party.party:getChampion(4):insertItem(5,spawn("peasant_breeches").item)
   party.party:getChampion(4):insertItem(6,spawn("sandals").item)
   end

end
Now you just simply connect the timer to the script_entity to trigger the startItems function when the dungeon is loaded / refreshed.

Trying to insert an item into a slot that isn't empty will result in the item being spawned on the floor, which is why I added the little loop to remove all existing items first, otherwise you'll end up with a heap of gear on the floor if you refresh / restart the dungeon in the editor:
SpoilerShow
Image
Obviously, you can remove this loop if you don't want or need it, especially when exporting the dungeon, but you shouldn't get any errors if you leave it in.
You will also end up with items on the floor if you try to insert an item into the wrong slot, such as trying to place a pair of boots on a champion's head!


3: A BIT MORE COMPLICATED
Now that I've managed to get the basic principle working, I wanted to see if I could find a fairly simple and easy way to make the items more tailor-made to each champion.
Like everything else in life, it's easy when you know how, I just had to try and figure out what works and what doesn't first.
So, without further ado, here's the new script that I managed to get working:

Code: Select all

function startItems()

local i
local i = 1
   repeat
   if party.party:getChampion(1):getEnabled() then
      party.party:getChampion(1):removeItemFromSlot(i)
      end
   if party.party:getChampion(2):getEnabled() then
      party.party:getChampion(2):removeItemFromSlot(i)
      end
   if party.party:getChampion(3):getEnabled() then
      party.party:getChampion(3):removeItemFromSlot(i)
      end
   if party.party:getChampion(4):getEnabled() then
      party.party:getChampion(4):removeItemFromSlot(i)
      end
   i = i + 1
   until i > 32

local i = 1
   repeat
   if party.party:getChampion(i):getEnabled() then

-- CHECK FOR SOME BASIC CHAMPION STATS --
      local champ_ord = party.party:getChampion(i):getOrdinal()
      local champ_race = party.party:getChampion(i):getRace()
      local champ_class = party.party:getChampion(i):getClass()

-- MAKE THE MAIN HAND THE ONE CLOSEST TO THE CENTRE --
      if champ_ord == 1 or champ_ord == 3 then
         mainhand_slot = 2
         offhand_slot = 1
      else
         mainhand_slot = 1
         offhand_slot = 2
         end

-- SOME SIMPLE CLOTHING --
      party.party:getChampion(i):insertItem(4,spawn("peasant_tunic").item)
      party.party:getChampion(i):insertItem(5,spawn("peasant_breeches").item)
      party.party:getChampion(i):insertItem(6,spawn("sandals").item)

-- SOME EXTRA FOOD FOR MINOTAURS --
      if champ_race == "minotaur" then
         party.party:getChampion(i):insertItem(13,spawn("mole_jerky").item)
         end

-- ALCHEMIST ITEMS --
      if champ_class == "alchemist" then
         local alchemist_mainhand = spawn("dart")
            alchemist_mainhand.item:setStackSize(5)
         party.party:getChampion(i):insertItem(mainhand_slot,alchemist_mainhand.item)
         end

-- BARBARIAN ITEMS --
      if champ_class == "barbarian" then
         party.party:getChampion(i):insertItem(mainhand_slot,spawn("bone_club").item)
         end

-- BATTLE MAGE ITEMS --
      if champ_class == "battle_mage" then
         local battle_mage_offhand = spawn("rock")
            battle_mage_offhand.item:setStackSize(2)
         party.party:getChampion(i):insertItem(offhand_slot,battle_mage_offhand.item)
         end

-- FARMER ITEMS --
      if champ_class == "farmer" then
         party.party:getChampion(i):insertItem(mainhand_slot,spawn("shovel").item)
         end

-- FIGHTER ITEMS --
      if champ_class == "fighter" then
         party.party:getChampion(i):insertItem(mainhand_slot,spawn("dagger").item)
         end

-- KNIGHT ITEMS --
      if champ_class == "knight" then
         party.party:getChampion(i):insertItem(mainhand_slot,spawn("dagger").item)
         end

-- ROGUE ITEMS --
      if champ_class == "rogue" then
         local rogue_mainhand = spawn("dart")
            rogue_mainhand.item:setStackSize(5)
         party.party:getChampion(i):insertItem(mainhand_slot,rogue_mainhand.item)
         end

-- WIZARD ITEMS --
      if champ_class == "wizard" then
         local wizard_offhand = spawn("rock")
            wizard_offhand.item:setStackSize(2)
         party.party:getChampion(i):insertItem(offhand_slot,wizard_offhand.item)
         end

      end
      i = i + 1
   until i > 4
   end
Just to briefly explain what's changed here...
1: I put everything in a repeat, so I wouldn't end up with a separate block of script for each champion (DRY!).
2: The script now gathers some basic information about the champions (classes and races) that we can use to decide what kind of items we want to give them.
3: The mainhand slot will always be the one closest to the middle, based on the champions' initial starting positions within the party.
Last edited by Sutekh on Mon Sep 05, 2016 10:40 pm, edited 8 times in total.
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: Starting Items for Party

Post by Drakkan »

Sutekh I think that in simplicity is geniality and exactly that is this script. Easy and understable equip for starting party. Thanks a lot for it. In case you will have some time, please do something similar to modify starting stats / skills / traits for party, I think many players would welcome that.
Breath from the unpromising waters.
Eye of the Atlantis
User avatar
Thorham
Posts: 80
Joined: Sat May 04, 2013 5:12 pm

Re: Starting Items for Party

Post by Thorham »

You can use lists in Lua that are indexable using strings to make things easier. The following script uses a list to set class specific starting main hand items and defines the stack size as well. Stack size 0 is for stack less items, such as swords. Also adds party items and race items.

Code: Select all

classItems = {}
classItems["alchemist"]={item="dart", stack=5}
classItems["barbarian"]={item="bone_club", stack=0}
classItems["battle_mage"]={item="rock", stack=5}
classItems["farmer"]={item="shovel", stack=0}
classItems["fighter"]={item="dagger", stack=0}
classItems["knight"]={item="dagger", stack=0}
classItems["rogue"]={item="dart",stack=5}
classItems["wizard"]={item="rock", stack=5}

partyItems = {}
partyItems[1]="torch"
partyItems[2]="compass"

raceItems = {}
raceItems["human"]={item1="sausage", item2="", item3=""}
raceItems["insectoid"]={item1="baked_maggot", item2="", item3=""}
raceItems["lizardman"]={item1="boiled_beetle", item2="", item3=""}
raceItems["minotaur"]={item1="mole_jerky", item2="", item3=""}
raceItems["ratling"]={item1="cheese", item2="", item3=""}

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

    addPartyItems()
end

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

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

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

function addChampionItems(champion)
    cItems = classItems[champion:getClass()]
    rItems = raceItems[champion:getRace()]

    addItem(champion, 1, cItems.item, cItems.stack)
    addItem(champion, 4, "peasant_tunic", 0)
    addItem(champion, 5, "peasant_breeches", 0)
    addItem(champion, 6, "sandals", 0)

    addItem(champion, 13, rItems.item1, 0)
    addItem(champion, 14, rItems.item2, 0)
    addItem(champion, 15, rItems.item3, 0)
end

function addPartyItems()
    for a = 1, 4 do
        champion = party.party:getChampion(a)
        if champion:getEnabled() then
            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
bongobeat
Posts: 1076
Joined: Thu May 16, 2013 5:58 pm
Location: France

Re: Starting Items for Party

Post by bongobeat »

Hello,
I'm trying your script for my party, but everytime I start the dungeon in the editor or in the game, all items are spawned 2 times, on the floor, and in the inventory

I don't understand what's wrong, I simply copy paste your script, and changed the name of some items. I ve tryed with and wihtout the loop.

did I miss something?
My asset pack: viewtopic.php?f=22&t=9320

Log1 mod : Toorum Manor: viewtopic.php?f=14&t=5505
User avatar
Sutekh
Posts: 129
Joined: Sun Nov 25, 2012 9:58 am
Location: UK

Re: Starting Items for Party

Post by Sutekh »

Hmm, strange... did you set the timer to disable self?
User avatar
Isaac
Posts: 3188
Joined: Fri Mar 02, 2012 10:02 pm

Re: Starting Items for Party

Post by Isaac »

Thorham wrote:You can use lists in Lua that are indexable using strings to make things easier. The following script uses a list to set class specific starting main hand items and defines the stack size as well. Stack size 0 is for stack less items, such as swords. Also adds party items and race items.
That's a very cool script! 8-)
Sutekh wrote:Hmm, strange... did you set the timer to disable self?
Why the timer? (curious)

*The reason I ask is that instead of a timer, couldn't you have added the function name startItems() to the end of the script?
It would call the script function as soon as it loaded.

[I've not tried this... is a delay necessary?]
Last edited by Isaac on Sun Dec 07, 2014 10:52 pm, edited 1 time in total.
bongobeat
Posts: 1076
Joined: Thu May 16, 2013 5:58 pm
Location: France

Re: Starting Items for Party

Post by bongobeat »

Sutekh wrote:Hmm, strange... did you set the timer to disable self?
here is what i ve done:

the timer (called timer_22), is set to "on", "disable self", time interval is set to 0.1, and when activate, it trigger the script below (on activate : script_entity_19 : startItem)
the script: (the item listed are some custom items)

Code: Select all

    function startItems()

    local i = 1
       repeat
       if party.party:getChampion(1):getEnabled() then
          party.party:getChampion(1):removeItemFromSlot(i)
          end
       if party.party:getChampion(2):getEnabled() then
          party.party:getChampion(2):removeItemFromSlot(i)
          end
       if party.party:getChampion(3):getEnabled() then
          party.party:getChampion(3):removeItemFromSlot(i)
          end
       if party.party:getChampion(4):getEnabled() then
          party.party:getChampion(4):removeItemFromSlot(i)
          end
       i = i + 1
       until i == 33

    if party.party:getChampion(1):getEnabled() then
       party.party:getChampion(1):insertItem(2,spawn("torch").item)
       party.party:getChampion(1):insertItem(4,spawn("lurker_vest").item)
       party.party:getChampion(1):insertItem(5,spawn("voyager_pants").item)
       party.party:getChampion(1):insertItem(6,spawn("voyager_boots").item)
       party.party:getChampion(1):insertItem(7,spawn("voyager_cloak").item)
       party.party:getChampion(1):insertItem(9,spawn("voyager_gloves").item)
       party.party:getChampion(1):insertItem(13,spawn("bread").item)
       party.party:getChampion(1):insertItem(14,spawn("water_flask").item)
       party.party:getChampion(1):insertItem(15,spawn("water_flask").item)
       party.party:getChampion(1):insertItem(16,spawn("turtle_eggs").item)
       end

    if party.party:getChampion(2):getEnabled() then
       party.party:getChampion(2):insertItem(4,spawn("voyager_valor").item)
       party.party:getChampion(2):insertItem(5,spawn("silk_hose").item)
       party.party:getChampion(2):insertItem(6,spawn("voyager_boots").item)
       party.party:getChampion(2):insertItem(7,spawn("voyager_cloak").item)
       party.party:getChampion(2):insertItem(9,spawn("voyager_gloves").item)
       end

    if party.party:getChampion(3):getEnabled() then
       party.party:getChampion(3):insertItem(4,spawn("voyager_valor").item)
       party.party:getChampion(3):insertItem(5,spawn("voyager_pants").item)
       party.party:getChampion(3):insertItem(6,spawn("shoes").item)
       party.party:getChampion(3):insertItem(7,spawn("voyager_cloak").item)
       party.party:getChampion(3):insertItem(9,spawn("voyager_gloves").item)
       end

    if party.party:getChampion(4):getEnabled() then
       party.party:getChampion(4):insertItem(4,spawn("doublet").item)
       party.party:getChampion(4):insertItem(5,spawn("silk_hose").item)
       party.party:getChampion(4):insertItem(6,spawn("pointy_shoes").item)
       party.party:getChampion(4):insertItem(7,spawn("voyager_cloak").item)
       party.party:getChampion(4):insertItem(9,spawn("voyager_gloves").item)
       end

    end


  
My asset pack: viewtopic.php?f=22&t=9320

Log1 mod : Toorum Manor: viewtopic.php?f=14&t=5505
User avatar
Sutekh
Posts: 129
Joined: Sun Nov 25, 2012 9:58 am
Location: UK

Re: Starting Items for Party

Post by Sutekh »

@Isaac: Yeah, I ended up using the timer because without it you get a set of errors the first time you run it in the editor, and it won't work at all if you export it. As far as I can tell, it's the torch that causes the problem, as the error messages mention things like 'maxFuel', "TorchItem.lua" and so on.

@Bongobeat: Try checking that your version of LoG2 is up to date, because there was a problem with spawning items a while ago that was fixed. Other than that, it's possible it could be something to do with those custom 'Voyager' items, so make sure they're set to the correct item slots in the object definitions.
bongobeat
Posts: 1076
Joined: Thu May 16, 2013 5:58 pm
Location: France

Re: Starting Items for Party

Post by bongobeat »

thanks for answering,

before I set some custom items, I have tested the script unchanged.

I don't know if me version is the latest, ->> going to check! :D

edit:
OK: version 2.1.13 out of date! it works now! thank you ;)
My asset pack: viewtopic.php?f=22&t=9320

Log1 mod : Toorum Manor: viewtopic.php?f=14&t=5505
Post Reply