Yeah, your debug output shows that the syndrome isn't being applied. Let's see here...
Out of a bit of desperation on my part, try putting in the DFHACK_ITEM_SYNDROME syn class.
If that doesn't work, here's an even more verbose debug version of itemsyndrome (next version will have this version with all the debug code put behind a wall that requires you to type "debug" as an argument):
-- Checks regularly if creature has an item equipped with a special syndrome and applies item's syndrome if it is. Use "disable" (minus quotes) to disable. You can also change the
local function getDelayTicks(args)
for k,v in ipairs(args) do
if tonumber(v) and tonumber(v) > 0 then
return tonumber(v)
end
end
return nil
end
local args = {...}
function processArgs(args)
if #args==0 then enable = true return end
for k,v in ipairs(args) do
if v == "enable" then enable = true end
if v == "disable" then disable = true end
if v == "force" then force = true end
if v == "plus" then delayTicks = delayTicks+1 end
if v == "minus" then delayTicks = delayTicks-1 end
end
end
delayTicks = getDelayTicks(args) or delayTicks or 499
processArgs(args)
local function getMaterial(item)
local material = dfhack.matinfo.decode(item)
if material.mode ~= "inorganic" then
return nil
else
return material.material --the "material" thing up there contains a bit more info which is all pretty important, like the creature that the material comes from
end
end
local function findItemSyndromeInorganic()
local allInorganics = {}
for matID,material in ipairs(df.global.world.raws.inorganics) do
if string.find(material.id,"DFHACK_ITEMSYNDROME_MATERIAL_") then table.insert(allInorganics,matID) end --the last underscore is needed to prevent duped raws; I want good modder courtesy if it kills me, dammit!
end
printall(allInorganics)
if #allInorganics>0 then return allInorganics else return nil end
end
local function getAllItemSyndromeMats(itemSyndromeMatIDs)
local allActualInorganics = {}
for _,itemSyndromeMatID in ipairs(itemSyndromeMatIDs) do
table.insert(allActualInorganics,df.global.world.raws.inorganics[itemSyndromeMatID].material)
end
printall(allActualInorganics)
return allActualInorganics
end
itemSyndromeMatIDs = findItemSyndromeInorganic()
if itemSyndromeMatIDs then itemSyndromeMats = getAllItemSyndromeMats(itemSyndromeMatIDs) end
local function getSyndrome(material)
if material==nil then return nil end
if #material.syndrome>0 then return material.syndrome[0]
else return nil end
end
local function syndromeIsDfHackSyndrome(syndrome)
for k,v in ipairs(syndrome.syn_class) do
if v.value=="DFHACK_ITEM_SYNDROME" then return true end
end
return false
end
local function itemHasNoSubtype(item)
local itemtype = tostring(item)
local subtypedItemTypes =
{
"armor",
"weapon",
"helm",
"shoes",
"shield",
"glove",
"pants",
"tool",
"siegeammo",
"ammo",
"trapcomp",
"instrument",
"toy"}
for _,v in ipairs(subtypedItemTypes) do
if string.find(itemtype,v) then return false end
end
return true
end
local function itemHasSyndrome(item)
if itemHasNoSubtype(item) or not itemSyndromeMat then return nil end
for _,material in ipairs(itemSyndromeMats) do
for __,syndrome in ipairs(material.syndrome) do
if syndrome.syn_name == item.subtype.name then return syndrome end
end
end
return nil
end
local function alreadyHasSyndrome(unit,syn_id)
for _,syndrome in ipairs(unit.syndromes.active) do
if syndrome.type == syn_id then return true end
end
return false
end
local function assignSyndrome(target,syn_id) --taken straight from here, but edited so I can understand it better: https://gist.github.com/warmist/4061959/. Also implemented expwnent's changes for compatibility with syndromeTrigger.
if target==nil then
return nil
end
if alreadyHasSyndrome(target,syn_id) then
local syndrome
for k,v in ipairs(target.syndromes.active) do
if v.type == syn_id then syndrome = v end
end
if not syndrome then return nil end
syndrome.ticks=1
return true
end
local newSyndrome=df.unit_syndrome:new()
local target_syndrome=df.syndrome.find(syn_id)
newSyndrome.type=target_syndrome.id
newSyndrome.year=df.global.cur_year
newSyndrome.year_time=df.global.cur_year_tick
newSyndrome.ticks=1
newSyndrome.unk1=1
for k,v in ipairs(target_syndrome.ce) do
local sympt=df.unit_syndrome.T_symptoms:new()
sympt.ticks=1
sympt.flags=2
newSyndrome.symptoms:insert("#",sympt)
end
target.syndromes.active:insert("#",newSyndrome)
if debug then
print("Assigned syndrome #" ..syn_id.." to unit.")
end
return true
end
local function syndromeIsIndiscriminate(syndrome)
if #syndrome.syn_affected_class==0 and #syndrome.syn_affected_creature==0 and #syndrome.syn_affected_caste==0 and #syndrome.syn_immune_class==0 and #syndrome.syn_immune_creature==0 and #syndrome.syn_immune_caste==0 then return true end
return false
end
local function creatureIsAffected(unit,syndrome)
if syndromeIsIndiscriminate(syndrome) then return true end
local affected = false
local unitraws = df.creature_raw.find(unit.race)
local casteraws = unitraws.caste[unit.caste]
local unitracename = unitraws.creature_id
local castename = casteraws.caste_id
local unitclasses = casteraws.creature_class
for _,unitclass in ipairs(unitclasses) do
for _,syndromeclass in ipairs(syndrome.syn_affected_class) do
if unitclass.value==syndromeclass.value then affected = true end
end
end
for caste,creature in ipairs(syndrome.syn_affected_creature) do
local affected_creature = creature.value
local affected_caste = syndrome.syn_affected_caste[caste].value --slightly evil, but oh well, hehe.
if affected_creature == unitracename and affected_caste == castename then affected = true end
end
for _,unitclass in ipairs(unitclasses) do
for _,syndromeclass in ipairs(syndrome.syn_immune_class) do
if unitclass.value==syndromeclass.value then affected = false end
end
end
for caste,creature in ipairs(syndrome.syn_immune_creature) do
local immune_creature = creature.value
local immune_caste = syndrome.syn_immune_caste[caste].value
if immune_creature == unitracename and immune_caste == castename then affected = false end
end
if not affected then print ("Creature is not affected.") else print("Creature is affected") end
return affected
end
local function itemAffectsHauler(syndrome)
for k,v in ipairs(syndrome.syn_class) do
if v.value=="DFHACK_AFFECTS_HAULER" then return true end
end
return false
end
local function itemAffectsStuckins(syndrome)
for k,v in ipairs(syndrome.syn_class) do
if v.value=="DFHACK_AFFECTS_STUCKIN" then return true end
end
return false
end
local function itemIsArmorOnly(syndrome)
for k,v in ipairs(syndrome.syn_class) do
if v.value=="DFHACK_ARMOR_ONLY" then return true end
end
return false
end
local function itemIsWieldedOnly(syndrome)
for k,v in ipairs(syndrome.syn_class) do
if v.value=="DFHACK_WIELDED_ONLY" then return true end
end
return false
end
local function itemOnlyAffectsStuckins(syndrome)
for k,v in ipairs(syndrome.syn_class) do
if v.value=="DFHACK_STUCKINS_ONLY" then return true end
end
return false
end
local function itemIsInValidPosition(item_inv, syndrome)
if (item_inv.mode == 0 and not itemAffectsHauler(syndrome)) or (item_inv.mode == 7 and not itemAffectsStuckins(syndrome)) or (item_inv.mode ~= 2 and itemIsArmorOnly(syndrome)) or (item_inv.mode ~=1 and itemIsWieldedOnly(syndrome)) or (item_inv.mode ~=7 and itemOnlyAffectsStuckins(syndrome)) then return false end
return true
end
local function syndromeIsTransformation(syndrome)
for _,effect in ipairs(syndrome.ce) do
local effectType = tostring(effect)
if string.find(effectType,"body_transformation") then return true end
end
return false
end
local function rememberInventory(unit)
local invCopy = {}
for inv_id,item_inv in ipairs(unit.inventory) do
invCopy[inv_id+1] = {}
local itemToWorkOn = invCopy[inv_id+1]
itemToWorkOn.item = item_inv.item
itemToWorkOn.mode = item_inv.mode
itemToWorkOn.body_part_id = item_inv.body_part_id
end
return invCopy
end
local function moveAllToInventory(unit,invTable)
for _,item_inv in ipairs(invTable) do
dfhack.items.moveToInventory(item_inv.item,unit,item_inv.mode,item_inv.body_part_id)
end
end
local function findItems()
for _uid,unit in ipairs(df.global.world.units.all) do
local transformation = false
for itemid,item_inv in ipairs(unit.inventory) do
local item = item_inv.item
print("checking item #" .. itemid .." on unit #" .. _uid)
if getSyndrome(getMaterial(item)) then
print("item has a syndrome, checking if item is valid for application...")
local syndrome = getSyndrome(getMaterial(item))
local syndromeApplied
if syndromeIsTransformation(syndrome) then
unitInventory = rememberInventory(unit)
transformation = true
end
if syndromeIsDfHackSyndrome(syndrome) and creatureIsAffected(unit,syndrome) and itemIsInValidPosition(item_inv, syndrome) then
assignSyndrome(unit,syndrome.id)
syndromeApplied = true
end
end
if itemHasSyndrome(item) then
print("Item itself has a syndrome, checking if item is in correct position and creature is affected")
local syndrome = itemHasSyndrome(item)
if syndromeIsTransformation(syndrome) then
unitInventory = rememberInventory(unit)
transformation = true
end
if item_inv.mode~=0 and item_inv.mode~=7 and creatureIsAffected(unit,syndrome) then assignSyndrome(unit,syndrome.id) end --the mode thing is to avoid stuckins from doing
end
if item.contaminants then
print("Item has contaminants. Checking for syndromes...")
for _,contaminant in ipairs(item.contaminants) do
print("Checking contaminant #" .. _ .. " on item #" .. itemid .. " on unit #" .. _uid ..".")
if getSyndrome(getMaterial(contaminant)) then
local syndrome = getSyndrome(getMaterial(contaminant))
if syndromeIsTransformation(syndrome) then
unitInventory = rememberInventory(unit)
transformation =true
end
if syndromeIsDfHackSyndrome(syndrome) and creatureIsAffected(unit,syndrome) and itemIsInValidPosition(item_inv, syndrome) then assignSyndrome(unit,syndrome.id) end
end
end
end
end
if transformation then dfhack.timeout(2,"ticks",function() moveAllToInventory(unit,unitInventory) end) end
end
end
dfhack.onStateChange.itemsyndrome = function(code) --Many thanks to Warmist for pointing this out to me!
if code==SC_WORLD_LOADED then
itemsyndrome()
end
end
function itemsyndrome()
findItems()
dfhack.timeout(delayTicks,'ticks',itemsyndrome)
end
if enable then
dfhack.onStateChange.itemsyndrome()
print("Enabled itemsyndrome.")
enable = false
end
if force then
findItems()
force = false
end
if disable then
callback = nil
dfhack.onStateChange.itemsyndrome = nil
print("Disabled itemsyndrome.")
disable = false
end
print(delayTicks)