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.