Skip to content

What links the Beastiary pictures?

smeagolheartsmeagolheart Member Posts: 7,963
Anyone know how the beastiary is referenced in game?

I'd like to make a mod that shows the picture of the beast you are talking to while you are talking to said creature. This will take some UI changes but how does the beastiary portrait get referenced by a creature?

I've noticed you just have to spawn in a particular creature and then the appropriate entry is made in the beastiary automatically. How does that happen? I can't find the connection between the beastiary and that entry. Using @argent77 nearinfinity I see no reference in scripts that do it - though I could easily be missing something.

I suspect the link is based on the animation, but is there a table or reference that shows what BMP matches up to what type of animation? If so, my goal is to reference that through dialogue and show the beasitary pic when you talk to a creature of that type.

Anybody know the internals on this aspect?

Comments

  • argent77argent77 Member Posts: 3,478
    There are bestiary-related entries defined in BGEE.LUA (starting around line 1480). I don't know if there is more.
  • smeagolheartsmeagolheart Member Posts: 7,963
    edited April 2017
    argent77 said:

    There are bestiary-related entries defined in BGEE.LUA (starting around line 1480). I don't know if there is more.

    I see there's an index from something, a 2DA file?

    example:

    {
    index=0,
    killvar='Kill_Abishai_Black',
    desc0=3602,
    class=1,
    imageUnknown='image',
    imageKnown='jrabskn',
    name=3279,
    },
    edit:
    I can get it to work - but only if I preselect the journal entry before entering dialogue. :/ It will show the portrait even if I speak to someone else.
    image

    otherwise it shows this:
    image

    so there's no link between speaker and dialogue.
    Post edited by smeagolheart on
  • themazingnessthemazingness Member, Mobile Tester Posts: 702
    I hope you can get this working. It's an awesome idea for a mod.
  • smeagolheartsmeagolheart Member Posts: 7,963
    After messing around with lua for a few hours, I can't get it to work to recognize the speaker to the bestiary portraits.

    I can link them directly, which will be a bit tedious to recreate everything but it can be done and I know how to do it.

    But the portraits show up on the main ui screen without transparency.
    As an example this portrait would show up as this:
    image


    Anyone up to making a transparent frame that fits in with the base UI to get something better than this quick mockup:
    image
  • smeagolheartsmeagolheart Member Posts: 7,963
    edited April 2017
    Pecca said:

    Hi, here is a quick attempt with journal border graphics. It should hide the green if placed exactly.

    @Pecca @AncientCowboy

    Maybe you ui modders can figure this out. In the bestiary the green gets dropped and you get the rounded edges.

    mosaic lua "getBestiaryImage()"

    But in dialogue that doesn't work have to call it as:
    bitmap lua "worldNPCDialogPortrait"
    mosaic lua "worldNPCDialogPortrait" doesn't show anything.

    ... (around line 12849)
    label
    {
    area 752 244 54 44
    mosaic icgoldf
    }
    -- SMEAGOL
    label
    {
    name "worldDialogPortraitArea"
    area 54 24 158 246
    --mosaic lua "getBestiaryImage()"
    --mosaic lua "worldNPCDialogPortrait"
    bitmap lua "worldNPCDialogPortrait"
    align center center
    }
    -- SMEAGOL
    }

    `
    currentChargenAbility = -1
    ...

    So the rounded edges don't work, the frame would have to be square or pseudo-square... I added another layer beneath.. It doesn't look great.
    image

    I'll try placing the frame on top without adding the layer, that might work.

    I don't know LUA well and there might be a way to get the bestiary portrait to link to the speaker that I'm missing. Since I can't figure that out, I'm making the small portrait show up on the UI like in BG, BG2, IWD.



  • PeccaPecca Member Posts: 2,215
    The image I posted should cover over the green edges so another layer should not be necessary. The thing is that the journal images are mos files that allow transparency while portraits are bitmap files which do not allow it. I don't think it is possible to use other files than bitmaps for portraits so you will most likely need to use the cover layer on top of the portrait for this mod.
  • smeagolheartsmeagolheart Member Posts: 7,963
    I've got it, I had to add a pixel or two to the bottom right but I think it is covering all the green..

    image

    Now just need to map all the creatures to their bestiary pics. This seems to be done based on their animation.

    In nearinfinity for one of the creatures, ABISHBH.cre and it is animation 61440. If you click on another animation then click back on Abishai_Black - 61440 you can "view/edit" that it shows F000.ini (not sure the link there?).

    It has a monster_planescape section and an entry on the bestiary there.

    bestiary=0
    In BGEE.lua it seems to enumerate the bestiary around line 1490 has

    {
    index=0,
    killvar='Kill_Abishai_Black',
    desc0=3602,
    class=1,
    imageUnknown='image',
    imageKnown='jrabskn',
    name=3279,
    },
    There's 87 entries on the bestiary. So I think if I go through each animation/ini file I can find out what animations are linked to what bestiary entry. If anyone knows a better way to do that let me know. Once I have that info, I'll patch the appropriate creature to have their bestiary portrait as their small portrait.
  • bob_vengbob_veng Member Posts: 2,308
    this is really good
  • argent77argent77 Member Posts: 3,478
    edited April 2017
    You can probably automate the whole process with WeiDU's text processing functions. Especially INDEX_BUFFER is very useful for processing large text files if you know how to use regular expressions.

    Example code how to read BGEE.LUA entries:
    [spoiler]
    // Reads a numeric value from a LUA variable definition
    DEFINE_PATCH_FUNCTION GET_BESTIARY_NUMBER
    INT_VAR startOfs = 0
    endOfs = 0
    STR_VAR keyName = ~~
    RET number
    BEGIN
    SET number = "-1"
    SET ofs = INDEX_BUFFER(~%keyName%[ %TAB%]*=~ startOfs)
    PATCH_IF (ofs >= startOfs && ofs < endOfs) BEGIN
    SET ofs2 = INDEX_BUFFER(~[%WNL%]~ ofs)
    READ_ASCII ofs string (ofs2 - ofs)
    INNER_PATCH_SAVE string ~%string%~ BEGIN
    REPLACE_TEXTUALLY ~%keyName%[ %TAB%]*=\(-?[0-9]+\).*~ ~\1~
    END
    PATCH_IF (IS_AN_INT "string") BEGIN
    SET number = string
    END
    END
    END

    // Reads a string value from a LUA variable definition
    DEFINE_PATCH_FUNCTION GET_BESTIARY_STRING
    INT_VAR startOfs = 0
    endOfs = 0
    STR_VAR keyName = ~~
    RET value
    BEGIN
    TEXT_SPRINT value ~~
    SET ofs = INDEX_BUFFER(~%keyName%[ %TAB%]*=~ startOfs)
    PATCH_IF (ofs >= startOfs && ofs < endOfs) BEGIN
    SET ofs2 = INDEX_BUFFER(~[%WNL%]~ ofs)
    READ_ASCII ofs string (ofs2 - ofs)
    INNER_PATCH_SAVE value ~%string%~ BEGIN
    REPLACE_TEXTUALLY ~%keyName%[ %TAB%]*=[ %TAB%]*'\([^']*\)'.*~ ~\1~
    END
    END
    END


    // Reading bestiary entries
    COPY_EXISTING - ~bgee.lua~ ~override~
    SET startIndex = INDEX_BUFFER(~bestiary[ %TAB%]*=~)

    // first entry is special - skipping
    SET startIndex = INDEX_BUFFER(~placeholder[ %TAB%]*=~ startIndex)
    SET startIndex = INDEX_BUFFER(~},~ startIndex)

    SET endIndex = INDEX_BUFFER(~},~ (startIndex + 2))
    WHILE (startIndex >= 0) BEGIN
    // processing index
    LPF GET_BESTIARY_NUMBER INT_VAR startOfs = startIndex endOfs = endIndex STR_VAR keyName = "index" RET number END
    PATCH_IF (number >= 0) BEGIN
    SET index = number
    SET $EVAL cre_index("%index%") = number

    // processing killvar
    LPF GET_BESTIARY_STRING INT_VAR startOfs = startIndex endOfs = endIndex STR_VAR keyName = "killvar" RET value END
    TEXT_SPRINT $EVAL cre_killvar("%index%") ~%value%~

    // processing desc0
    LPF GET_BESTIARY_NUMBER INT_VAR startOfs = startIndex endOfs = endIndex STR_VAR keyName = "desc0" RET number END
    SET $EVAL cre_desc_strref("%index%") = number

    // processing class
    LPF GET_BESTIARY_NUMBER INT_VAR startOfs = startIndex endOfs = endIndex STR_VAR keyName = "class" RET number END
    SET $EVAL cre_class("%index%") = number

    // processing imageUnknown
    LPF GET_BESTIARY_STRING INT_VAR startOfs = startIndex endOfs = endIndex STR_VAR keyName = "imageUnknown" RET value END
    TEXT_SPRINT $EVAL cre_imageUnknown("%index%") ~%value%~

    // processing imageKnown
    LPF GET_BESTIARY_STRING INT_VAR startOfs = startIndex endOfs = endIndex STR_VAR keyName = "imageKnown" RET value END
    TEXT_SPRINT $EVAL cre_imageKnown("%index%") ~%value%~

    // processing name
    LPF GET_BESTIARY_NUMBER INT_VAR startOfs = startIndex endOfs = endIndex STR_VAR keyName = "name" RET number END
    SET $EVAL cre_name_strref("%index%") = number

    // jumping to next entry
    SET startIndex = endIndex
    SET endIndex = INDEX_BUFFER(~},~ (startIndex + 2))
    END ELSE BEGIN
    SET startIndex = "-1"
    END
    END
    The data can now be accessed by using indexed variables (e.g. $cre_imageKnown(0) contains the image resource name for the bestiary entry of index = 0).
    [/spoiler]
    Post edited by argent77 on
  • smeagolheartsmeagolheart Member Posts: 7,963
    @argent77

    I'm not yet stuck on the problem of reading the bestiary entries.

    How does it work that "Abishai_Black - 61440" corresponds to F000.INI?

    When I read in the animation data for each creature like this:

    COPY_EXISTING_REGEXP GLOB ~^.+\.cre$~ ~override~
    READ_SHORT 0x28 animationindex ELSE 0
    How do I link variable 'animationindex' which presumably will give me something like 61440 to f000.ini (or am I missing something)?

    I believe I need to read in creaturedata but how to match something from the creature to the ini file where I can grab the bestiary number?
  • argent77argent77 Member Posts: 3,478
    F000 is the hexadecimal representation of 61440. Same is true with all the other animation IDs. Problem in WeiDU is that there is no built-in "decimal -> hexadecimal" converter (or vice versa) available. You have to code a function for this (or look up the functions I coded for my Golem Construction mod).
  • smeagolheartsmeagolheart Member Posts: 7,963
    edited April 2017
    Ok need more coding help guys

    Need a function to read in an ini file (random example F035.INI)

    // Nupperibo

    [general]
    animation_type=F000
    move_scale=4.5
    ellipse=16
    color_blood=47
    color_chunks=255
    sound_freq=9
    personal_space=3
    cast_frame=4

    [monster_planescape]
    attack1=cat1npr
    attack2=cat2npr
    stancefidget1=ccf1npr
    diebackward=cdfbnpr
    gethit=chitnpr
    run=crunnpr
    stance=cstcnpr
    walk=cwlknpr
    walkscale=4.1
    runscale=9
    bestiary=45

    (there's more after this)
    and return the bestiary value (this case 45).

    Then I should be able to match that to the index that argent77 provided earlier that links the portrait.
  • KamigoroshiKamigoroshi Member Posts: 5,870
    This is so going to be a legendary mod! Can't wait to start a new playthrough when it's finished. :3
  • smeagolheartsmeagolheart Member Posts: 7,963
    It should work on existing playthroughs BUT for creatures in areas you've already been, it will only show a blank default placeholder. If you started a new playthough, it will show the correct portrait.

    I'm not sure how it will work on NPCs that are already in your party... At any rate, a new playthrough would give best results.

    The last thing I'm working on is how to weidu in the one small required ui.menu change
  • moody_magemoody_mage Member Posts: 2,054
    Subscribed as this is awesome.
Sign In or Register to comment.