Mod almost done - check promo pics

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
Lord_Foul
Posts: 49
Joined: Wed Dec 09, 2015 6:05 am

Mod almost done - check promo pics

Post by Lord_Foul »

thanks to minmay I am working on my final scripts :)

4 problems, a few touches and a final run away from posting my dungeon.

(i may need 3 or 4 volunteer/peeps to final test run it, about a week of playing
as there is around 24 hrs total playtime req. - but not sure yet as it has
been heavily tested on all difficulty settings and with a wide variety of party compositions
--but without the above mentioned problems solved, non of which are req for completion.)

if interested in participating in my final test run just post a message here.


some promo pics


"The Crack of Doom"


Beat, mash, hack, pummel, bleed and harry potter your way to the
final showdown with Pope Doom!

-light on puzzles
-very heavy on action/exploration

average play time on normal setting 24hrs
average level on completion 21
Image


a few examples of some funky stuff i've been able to do
Image

Image

Image

Image

location stills
Image

Image

Image

Image
Last edited by Lord_Foul on Sun Dec 13, 2015 5:16 am, edited 2 times in total.
minmay
Posts: 2789
Joined: Mon Sep 23, 2013 2:24 am

Re: Mod almost done - need script help

Post by minmay »

Lord_Foul wrote:1. First a non scripting issue
I have created a custom race "dark elf" and a "musketeer" class as a firearms alt to the alchemist.

my problem: how in the heck do you get custom icons to show for race and class?
i have tried my standard custom atlas that works for everything else but they just dont show up.

gfxAtlas = "mod_assets/textures/foul_atlas.dds",
gfxIndex = 2,
i get nojoy when i specify the above.
All races and classes have a matching trait that applies their actual effects - check out traits.lua in the asset pack. For example:

Code: Select all

defineTrait{
  name = "musketeer",
  iconAtlas = "mod_assets/textures/foul_atlas.dds",
  icon = 2,
}
Lord_Foul wrote: 2. Boss fight issue
specifically the boss fight health bar. If i have a boss that is scaled higher than lvl1
the boss fight health bar does not appear/start at full health. Any fix for this?
You need to call BossFightComponent:recomputeTotal() any time you add, change, or remove monsters belonging to the boss fight.
Lord_Foul wrote: 3. scripting issue
I have spent almost half the time it took to design a 21 level dungeon on this script.OMG:brainDisable() == true

I have a mithril forge. Players collect lumps of mithril and forge weapons and armor. You put xAmount
of mithril rocks in an alcove, hit a button and you get an item spawned on an altar. Foolish me thought this one would be easy.
...
But it is easy. In fact, several people have wanted this exact mechanic. Here is the script I gave the last time someone asked about it:

Code: Select all

    -- Check a surface for a specific combination of items.
    -- surface: the surface to search.
    -- itemNames: an array of strings that should correspond to the names
    --   of the items you want. Duplicates are not allowed.
    -- If all the items were found, an array of arrays of item
    -- references is returned. The arrays of item references are
    -- in the same order as the strings in itemNames, so if
    -- itemNames[1] is "rock", the first array will be an array of
    -- references to all rocks on the surface.
    -- If not all of the items were found, false is returned.
    function surfaceContains(surface,itemNames)
       local found = {}
       for _,item in surface:contents() do
          for index,itemName in ipairs(itemNames) do
             if item.go.name == itemName then
                if found[index] then
                   table.insert(found[index],item)
                else
                   found[index] = {item}
                end
                break
             end
          end
       end
       for i = 1,#itemNames do
          if not found[i] then return false end
       end
       return found
    end

    -- Check a surface for eligible item combinations, and turn them
    -- into a new item if any are found.
    function forgeSurface(surface)

       -- Example: make a boulder from 3 rocks.
       local foundItems = surfaceContains(surface,{"rock"})
       if foundItems then
          -- We found at least one "rock" item on the surface, but
          -- we still need to count the rocks and see how many we
          -- have.
          if countItems(foundItems[1]) >= 3 then
             -- We have 3 rocks.
          
             -- Destroy exactly 3 rocks.
             destroySomeOf(foundItems[1],3)
             
             -- Add the boulder.
             surface:addItem(spawn("boulder").item)
             
             -- We don't need to do anything else.
             -- (Here is where you might add a sound,
             -- special effect, etc.)
             return
          end
       end
       
       -- Example 2: make a spiked club from 2 rocks, 3 branches,
       -- and a warhammer.
       -- Note: since Example 1 is checked first, and uses 3 rocks,
       -- if there are 3 rocks on the altar then a boulder will
       -- always be created from them, even if there are enough
       -- items to make a spiked club instead. To prevent this, you
       -- can easily just switch the order.
       local foundItems = surfaceContains(surface,{"rock","branch","warhammer"})
       if foundItems then
          -- We found at least one "rock" item on the surface, but
          -- we still need to count the rocks and see how many we
          -- have.
          local rocks = countItems(foundItems[1]) >= 2

          -- Branches are NOT stackable items. Therefore, the number
          -- of elements in the array will always be the number of
          -- branches; we do not need countItems().
          local branches = #foundItems[2] >= 3
          
          -- We only wanted 1 warhammer, so we don't need any extra
          -- checks: surfaceContains would have returned false in
          -- the first place if there were no warhammers at all.
          if rocks and branches then
                -- Destroy exactly 2 rocks.
                destroySomeOf(foundItems[1],2)
                
                -- Destroy exactly 3 branches.
                destroySomeOf(foundItems[2],3)
                
                -- Destroy exactly 1 warhammer.
                destroySomeOf(foundItems[3],1)
                
                -- Add the club.
                surface:addItem(spawn("spiked_club").item)
                
                -- We don't need to do anything else.
                -- (Here is where you might add a sound,
                -- special effect, etc.)
                return
          end
       end
    end

    -- Count the items in an array.
    -- items: array of items to be counted
    -- Returns the total number of items in the array, accounting for
    -- stack size, so an array of one rock object with a stack size
    -- of 3 would return 3.
    function countItems(items)
       local total = 0
       for _,item in ipairs(items) do
          total = total+item:getStackSize()
       end
       return total
    end

    -- Destroy some of the items in an array. Items appearing
    -- later in the array will be destroyed first.
    -- items: array of items to be destroyed
    -- quantity: number of items to destroy
    -- Returns true if the requested number of items was destroyed,
    -- false if the array did not contain enough items to satisfy the
    -- quantity (all the items in the array were still destroyed).
    function destroySomeOf(items,quantity)
       local destroyed = 0
       for i = #items,1,-1 do
          local diff = quantity-destroyed
          local item = items[i]
          if diff < item:getStackSize() then
             item:setStackSize(item:getStackSize()-diff)
             return true
          else
             destroyed = destroyed+item:getStackSize()
             item.go:destroy()
          end
          if quantity == destroyed then return true end
       end
       return false
    end
Just add a connector from your surface to the forgeSurface() function and replace the examples with whatever items/effects you want.
Lord_Foul wrote: 4. last script issue
this pertains to custom spells.
I know spells are hardcoded and that when you create a custom spell you
must create a function to spawn the item or projectile for "onCast"

onCast = function(shootProjectile)
local projectile = ("ether_ball", 1.3, 7, 0).projectile
end,

^^that was my last attempt but it doesnt work like my other 60 million attempts.

My new spell works fine when spawned via trigger etc but not when i cast it.

So what is the proper scripting for this?
Here is the skeleton you want for a projectile spell:

Code: Select all

    onCast = function(champion, x, y, direction, elevation, skillLevel)
      local spl = spawn("ether_ball",party.level,party.x,party.y,party.facing,party.elevation)
      spl.projectile:setIgnoreEntity(party)

      -- Set cast by champion so that experience is awarded for kills.
      local ord = champion:getOrdinal()
      spl.projectile:setCastByChampion(ord)

      -- Simulate the position of a player-cast spell.
      local left = nil
      for i = 1,4 do
        if party.party:getChampion(i):getOrdinal() == ord then
          left = i == 1 or i == 3
          break
        end
      end
      local wpos = party:getWorldPosition()
      local dx = nil
      local dz = nil
      if party.facing == 0 then
        dx = left and -0.1 or 0.1
        dz = -1
      elseif party.facing == 1 then
        dz = left and 0.1 or -0.1
        dx = -1
      elseif party.facing == 2 then
        dx = left and 0.1 or -0.1
        dz = 1
      else -- party.facing == 3
        dz = left and -0.1 or 0.1
        dx = 1
      end

      spl:setWorldPosition(vec(wpos[1]+dx,wpos[2]+1.35,wpos[3]+dz))
    end,
This does not include e.g. changing the object spawned depending on skill level (this is how the default projectile spells such as frostbolt work; there are 5 different frostbolt objects, one for each skill level, each one with increased freezing chance and duration). It just creates the projectile at the correct position and assigns it to the champion for experience purposes.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Post Reply