df-structures icon indicating copy to clipboard operation
df-structures copied to clipboard

creature.flags unk_6e, unk_6f & unk_49

Open KlonZK opened this issue 8 years ago • 4 comments

only humans have unk_6f.

the set of creatures that have either unk_6e or unk_49 is exactly the set of creatures armor can be made for via the blacksmith. notably this set of creatures does not include several species that can equip and learn/speak/utter, like ogres, trolls, gremlins, gnomes, foul blendecs, troglodytes etc.

only animal men and gorlaks have unk_6e, 187 species in total. 14 species have unk_49, among them dwarves, elves, humans, goblins and kobolds. the rest are animal men as well, some of which have unk_6e too, but not all.

specifically, bat men, olm men, cave fish men, cave swallow men have both flags. amphib men, ant men, reptile men, rodent men and serpent men have unk_49, but not unk_6e.

presumably these species either have entities or are advmode controllable?

KlonZK avatar Mar 26 '16 12:03 KlonZK

only humans have unk_6f.

[OUTSIDER_CONTROLLABLE]?

Putnam3145 avatar Apr 29 '16 01:04 Putnam3145

A thought - It could be "large" clothing? as that is often a modifier of human and above sized clothing. A troll can slip into a polar bear man sized suit of armor made from goblin smiths in dwarf fortress mode in play and as defined by the player quite comfortably, but their own clothes sized for them (goblin civilisation can embark with pre-clothed trolls for reference) will be "Large xobjectx it is sized for trolls" on description.

unk_49 reasonably must correspond to 'small' if you look at it in perspective of a larger animal (dwarf downward in height where it usually starts), while unk_6f must be large. starting roughly at human size (and because of the range of variable intelligent animal men in size compared to unintelligent generic races and only playable with modding trolls this probably plays a factor) even if this isn't precisely correct it should help steer you towards a better answer.

If you give trolls hero production or outsider controllable it wouldn't change their conditions of being excluded from the list (though a careful observation might be to see if their clothes are still listed as 'large') therefore i can't personally see the definite connection between the two.

FantasticFwoosh avatar Oct 23 '16 10:10 FantasticFwoosh

unk_6e seems to correspond to LOCAL_POPS_CONTROLLABLE while 112 (the first one after those included in the struct) corresponds to LOCAL_POPS_PRODUCE_HEROES. I came to these conclusions by looking at TOAD_MAN while modifying the c_variation_default.txt [CREATURE_VARIATION:ANIMAL_PERSON], generating worlds, and looking at the corresponding raw state info. Removing the two tags above toggled both of the flags to False, while removing them one at a time caused one of them to toggle, as per the conclusion above.

Edit: I believe unk_49 is "civilized" as the list contains all the civ building races. Dwarf, Human, Elf, Goblin, Kobold, Cave_Fish_Man, Olm_Man, Bat_Man, Cave_Swallow_Man, Amphibian_Man, Reptile_Man, Serpent_Man, Ant_Man, and Rodent_Man.

creature.flags [116] is set only on CASTE_CAN_LEARN creatures, but I can't figure out what aspect it is tied to: Blind Cave Ogre, Manera, Troll, Ogre, Giant, Blizzard Man, Troglodyte, and some, but not all, Night Creatures. Note that only the regular Giant is included, but not the Ettin, for instance.

Edit 2: Running a script over all creatures printing all creatures that have the raw string "[SLOW_LEARNER]" and printing all creature that have flag 116 set shows a perfect match.

PatrikLundell avatar May 07 '17 14:05 PatrikLundell

The script used to match tags with flags:

function strip (str)
  local i = string.find (str, ":")
  
  if not i then
    return str
  end
  return string.sub (str, 1, i - 1) .. "]"
end

function match_creature_raw_flags ()
  local raw_set = {}
  local flags = {}
  
  for i, flag in ipairs (df.global.world.raws.creatures.all [0].flags) do
    flags [i] = flag
  end
    
  for i, creature in ipairs (df.global.world.raws.creatures.all) do
    for k, flag in ipairs (creature.flags) do
      if flags [k] ~= creature.flags [k] then
        flags [k] = -1
      end
    end
    
    for k, str in ipairs (creature.raws) do
      local token = strip (str [0])
      
      if raw_set [token] then
        raw_set [token] ["count"] = raw_set [token] ["count"] + 1
        
      else
        raw_set [token] = {["count"] = 1, ["flags"] = {}}
        
        for l, flag in ipairs (creature.flags) do
          raw_set [token] ["flags"] [l] = {["present"] = -1, ["absent"] = -1}
        end
      end
    end
  end

  for i, creature in ipairs (df.global.world.raws.creatures.all) do
    dfhack.println (creature.creature_id)
    local matched = {}
    
    for k, str in ipairs (creature.raws) do
      local token = strip (str [0])
      
      matched [token] = true
      
      for l, flag in ipairs (creature.flags) do
        if raw_set [token] ["flags"] [l] ["present"] == -1 then
          raw_set [token] ["flags"] [l] ["present"] = flag
              
        elseif raw_set [token] ["flags"] [l] ["present"] ~= flag then
          raw_set [token] ["flags"] [l] ["present"] = 2  --  Redundant assignment when already mismatch
        end
      end
    end
    
    for k, raw in pairs (raw_set) do
      if not matched [k] then
        for l, flag in ipairs (creature.flags) do
          if raw_set [k] ["flags"] [l] ["absent"] == -1 then
            raw_set [k] ["flags"] [l] ["absent"] = flag
              
          elseif raw_set [k] ["flags"] [l] ["absent"] ~= flag then
            raw_set [k] ["flags"] [l] ["absent"] = 2  --  Redundant assignment when already mismatch
          end
        end
      end
    end
  end
  
  for i, flag in ipairs (df.global.world.raws.creatures.all [0].flags) do
    if flags [i] == -1 then  --  Skip flags that do not change.
      dfhack.println ("Flag:", i, df.creature_raw_flags [i])
      for k, raw in pairs (raw_set) do
        if (raw ["flags"] [i] ["present"] == true or
            raw ["flags"] [i] ["present"] == false) and
           (raw ["flags"] [i] ["absent"] == true or
            raw ["flags"] [i] ["absent"] == false) and
           raw ["flags"] [i] ["present"] ~= raw ["flags"] [i] ["absent"] then
          dfhack.println ("", k, raw ["flags"] [i] ["present"])
        end
      end
    end
  end
end

match_creature_raw_flags ()

PatrikLundell avatar Jan 27 '20 14:01 PatrikLundell