Jump to content

Skye

Members
  • Posts

    197
  • Joined

  • Last visited

Posts posted by Skye

  1. On 12/2/2023 at 12:50 PM, Sergio - ex SHS member said:

    @SkyeI've been playing your mod another bit. Some more thoughts (note that these are my thoughts and as such they are subjective):
     

      Hide contents

    I've found the scroll in Ragefast's house. I didn't have Ayden, but as soon as I reached the area where Ayden lies, Ayden talked about being able to use the scroll even if he wasn't in my party and was out of my vision. The bug is similar to the one I already reported about dialogues being "fired" out of context.

     


    The imp addition is cool, but it's not interesting. For the player, there is no real reason on giving money to the imp himself; why would charname choose to do so? You are basically risking giving your money to an extraplanar entity in a realm you can't reach if Ayden is not with you/Ayden doesn't want to help you/Ayden died permanently. Too much risk. I will add that the imp should probably offer better services and actually ask Ayden to find something he values around.

    The Refuge starting from 0 and being expanded is really cool.

    I hope you won't give up on this
     

     

    Thanks for the additional playthroughs. I know Ken has been working on making dialogue triggers more natural in cases where Ayden isn't initially in the party, but I'll bring the scroll bit to his attention just to make sure it doesn't slip through.

    I appreciate the feedback on the imp. It was initially just supposed to be a simple money stash because Ken got pissed off that he lost his money in SoD and then again SoA and, since you can't really stash the gold manually from your inventory, we decided to make it an NPC and give it a bit of character. The imp does play a somewhat bigger role in BG2 (including calling in the favor that was promised), but we'd love to hear if you have any ideas on how to improve on it in BG1 so that it's a bit more fun.

    I'm glad you like the Refuge. Making it grow dynamically has been a big challenge for us and we're very proud that we managed to pull it off. 😊

  2. On 10/5/2023 at 8:27 PM, Sergio - ex SHS member said:

    First of all, thanks for the extensive reply.

    1) I didn't realize you are able to skip these components. But I have to add that the reference on these components to the warlock class seems to imply they are supposed to be installed to have the optimal warlock experience (This component will change the configuration so that all thieves and thief kits can gain (at least) 1 point in spear or mace proficiency, like warlock; This simple component will enable the use of wands for all thief kits (including warlocks) if they meet the ability requirements).

    2-3-4-5) Nice, thank you. 

    6) I guess.

    8 ) Yes, I did explore all dialogue options. I'm wondering, what's the specific dialogue option I should be receiving?

    10) I had my notes somewhere (can't find them right now), but basically:
    - if Ayden doesn't join you, he could become an item dealer (you choose when he will make his offer, it could even be when you first meet him)
    - the items he deals are the one you've already made a recipe for, but the recipes are not unlocked when he makes you the proposal; he is still too weak.
    - By providing him cursed items he unlocks more recipes.
    - No searching around for the "common items" you've put in the shops; I don't know if they are respawnable (doubt it), but I would rather pay more and let Ayden find these "items" himself, if these items are added by the mod just for the recipes. 
    - Ayden could become an alternative to Thalantyr Item upgrades; some recipes there make sense, while others don't. 
     

     

    1) Yeah, warlocks actually get spear and mace proficiency by default. We figured if warlocks get to use them, all thieves might as well. They fall in the simple weapon category in 3E anyway. They don't get to use wands by default but, as mentioned, we consider that to be part of the standard rogue package, so that's why the component exists. But yeah, they're both optional. I don't really find myself using the wands much with thief characters but YMMV, obviously.

    8 ) I'll admit, we did hide that more than we probably should have. When selecting where you want to shadow walk, you have to ask Ayden to take you "somewhere special". After that, he'll transport you to the Refuge. It should at least be hinted at how to get there in the readme. The reasoning was that everyone would be curious enough to see where that option leads. Then again, the refuge used to be a very small island with a chest on it and now it's a full-blown stronghold area. He should probably take you there on his own if you don't ask him for a while. I'll open an issue for that.

    10) It's an interesting idea. I'll pass that along.

  3. Hey, Sergio. Thank you so much for trying out the Ayden Project. We've put a lot of work into it over the years and it's always nice to get some feedback. ☺️

    One of the members relayed your review to Ken and he wrote up a reply for you. In the future, if it's not too much trouble, please tag me in the message or post things in the mod thread, so that we get a notification. We would have completely missed this otherwise.

    Spoiler

    I'll address your points here and, if you want, we can talk about it some more.

    1) I've spent a lot of time considering which class to base my Warlock kit on in the beginning. Bard and thief were the prime candidates and they both had their pros and cons. I eventually settled on thief because I felt it made more sense and required less effort at the time. That said, I have been considering making another version of it with the bard class as a base instead.

    As far as the two features are concerned, I felt that all thieves should be able to use wands, so I added that as an option. This stems more from my love of 3E than anything else, where rogues more commonly use wands and scrolls with skills. I also wanted this to be optional for anyone who felt that this would make thief classes too strong.

    As for the spears, I just think it's a very underused weapon group and, as the simplest of weapons, thieves shouldn't have any issues using them. I figured I would try to steer more people to using them by providing this option for all thieves. I added maces because I also added light mace weapons that are useable by thieves.

    I didn't add either of these options to Ayden specifically, because I don't think he needs the ability to use either. He's plenty strong as it is.

    Neither of these components are necessary for the mod to function and are completely skippable. They simply exist because I thought they were cool.

    2) I can add a CHA-based option to threaten the halfling. That sounds pretty good.

    3) Originally, he just ran away, so you could never find him again to extort your money back. Since the end result of the quest is a pretty good reward (either Ayden or just the bag of holding), I didn't expect anyone to care. It's something I can consider adding though.

    4) Ayden can discern Charname's divine nature, hence he will allude to it in conversations, even prior to the the PC finding out what they are. It might be a good idea to make these more subtle though. I will go through the dialogue and see if I can't make the references less overt.

    5) I think that piece of dialogue is in response to you freeing the petrified woman in the basilisk garden. I'll look into that. The triggers might be wrong for that.

    6) Ayden's stats get pretty crazy if you let him consume all the cursed items, but they don't really affect much overall. They enable him to be a front-line character in late game, if you really wanted him to, but they only have very minor effect on him otherwise. It's all the other abilities he gets from curse eating that make him a powerhouse. :D

    7) I've used it everywhere and haven't encountered any issues. That's not to say there's no potential for issues by teleporting around the game, but I've yet to receive a single report of it breaking anything. Make of that what you will.

    8 ) Did you ever initiate dialogue with him directly? It's not something he shares with you on his own. You have to actually talk to him by yourself.

    9) I agree. Standard companions are mostly quiet in BG1, but that would be boring. I'll note in the README that he's chatty and that one should talk to him directly from time to time to get the most out of him.

    10) That sounds like a lot of fun. Feel free to share your ideas with me. I didn't give much thought to using Ayden if the player decides not to recruit him.

    We've already opened up several issues in our project tracker and the changes are due to be included in v2.7. Some of the bigger changes (like having Ayden stick around if you reject him at the beginning) probably won't make it into that one though.

  4. Version 2.6.19 is out. It contains mostly fixes and minor additions for v2.6. The download link remains the same.

    Changelog:

    • Reset weather when shadow walking to prevent it from following.
    • Recovered missing icon for dimensional lure.
    • Added new spell states for several invocations and abilities.
    • Improved Ayden's SoD integration.
    • Fixed random encounter difficulty algorithm.
    • Injected some color into this bleak existence.
    • Added combat delay to warlock AI to further mitigate friendly fire.
    • Fixed some incorrect item recipe strings.
    • Fixed incorrect journal entry for Forged in Fire quest.
    • Added animation-covering polygon to astral mimic.
    • Added new crafting components and craftable items.
    • Added new checks for potentially missing items.
    • Added wand usage for random encounter mages.
    • Added new curse eater abilities.

  5. 3 hours ago, jastey said:

    In any case: if the mod is not explicitely EET compatible probably all area references are wrong (amongst other things). The reason it didn't give an error message is that it patched the BGII ressources, instead.

    That is almost certainly the case and the mod relies quite heavily on existing areas being how they are in the original game, so who knows what exactly happened. There's probably a random cauldron in the middle of Brynnlaw and whatnot. :D

  6. YX1BCWF.png

    Free a powerful warlock from his imprisonment and venture with him on a quest to find the lost Nether Scrolls.

    Discover a new way of unleashing arcane energies with a brand new thief kit: The Warlock.

    Quickly travel vast distances across the Plane of Shadow if you dare to brave its desolate environs.

    Relax and store your equipment in a planar safe haven. Unlock new features and forge alliances in this astral stronghold.

    Brew potions and craft powerful artifacts to enhance your strength and devastate your enemies.

    u64hyyC.png

    Introduction:

    Ayden is a mysterious warlock that's been magically imprisoned on another plane for decades. You will originally encounter him in Ulcaster Ruins, struggling to find his way back to the prime material plane. Should you help him, he will become a loyal companion and friend to you and will open up a world of new opportunities.

    Over time, you will get to know many things about him, his past, and the place he comes from, which will affect your actions and perhaps even the way you perceive the world around you. Where will the road ultimately lead you as you approach godhood on your quest? Who will you put your trust in?


    What to expect:

    • A new thief kit: The Warlock. It comes with its own set of custom abilities and an AI script for convenience.
    • A fully-fleshed out companion NPC that uses the new kit and will interact with you and the world around him.
    • The ability to quickly move to any major area through the Plane of Shadow.
    • Your very own pocket plane that will serve as a stronghold and staging area for your adventures.
    • Several brand new areas and quests (with more on the way).
    • More than 30 new (or familiar) enemies and a handful of new allies.
    • A simple crafting system that will allow you to more easily acquire the gear you need.
    • A number of new items, some for crafting purposes, others for fun.
    • A couple of additional convenience components to make thief classes more fun.

     

    m6YJ5Jj.png

     

    Known Issues in v2.6.19:

    • One of the script actions is missing a parameter, emitting a warning.
    • Ayden may lose his ability to ignore reputation breaking points
    • Invocations may disappear from a warlock's repertoire if they are killed during cooldown.
    • Some of Ayden's comments may pop up instantly upon recruiting him if the preconditions have been met, even if he was not in the party at that time.
  7. This macro will spit out a "2-dimensional" array structure for a given 2DA file. Since there's actually no such thing as a 2-dimensional array in WeiDU (to the best of my knowledge), it can't be a function. It needs to return a variable number of arrays (depending on the size of the 2DA file) for it to work. Also, I'm pretty sure I've seen this before somewhere, but I was bored and Google wasn't being helpful, so here it is.

    Spoiler
    // Consume a 2DA into a 2-dimensional array structure
    DEFINE_PATCH_MACRO CONSUME_2DA BEGIN
      // array name will be the same as the file name
      SPRINT var_name ~%SOURCE_RES%~
    
      // read the table size
      COUNT_2DA_ROWS 1 row_count
      COUNT_2DA_COLS col_count
    
      // read the default cell value
      READ_2DA_ENTRY 1 0 1 default_value
      
      // loop through each data point
      FOR (i = 3; i < row_count; ++i) BEGIN
        READ_2DA_ENTRY i 0 1 row_id // read the row id
    
        FOR (j = 1; j < col_count; ++j) BEGIN
          READ_2DA_ENTRY 2 (j - 1) 1 col_name // read the column name
    
          // try reading the 2da value or use the default if it's missing
          PATCH_TRY READ_2DA_ENTRY i j 1 cell_value
          WITH DEFAULT SPRINT cell_value ~%default_value%~ END
    
          // push the column value into the row array
          SPRINT $EVAL ~%var_name%#%row_id%~(~%col_name%~) ~%cell_value%~
        END
    
        // add a reference to the row array
        SPRINT $EVAL ~%var_name%~(~%row_id%~) ~%var_name%#%row_id%~
      END
    END

    Once a 2DA file is consumed, you can easily reference any value in the table. For example:

    Spoiler
    COPY_EXISTING ~strmod.2da~ ~override~
      LPM CONSUME_2DA
      BUT_ONLY
    
    // Note the double $$: In actuality, $strmod is simply a reference array to each of the row arrays.
    // $strmod(14) will resolve into "strmod#14", which is the secondary array variable for this row.
    // This would be equivalent to calling $strmod#14("WEIGHT_ALLOWANCE"), but that's inconvenient. :)
    OUTER_SPRINT weight_allowance $$strmod(14)("WEIGHT_ALLOWANCE")
    PRINT ~%weight_allowance%~

    As a side note: While this will fill out any empty cells with the default value, just like the engine would, it will crash or malfunction for any 2DAs in a non-standard format (e.g. missing headers, repeating row ids, etc.). I wanted this to be an associative array table, but the macro would probably be more robust if it was numeric. YMMV

  8. Ken created a patch function that adds an arbitrary polygon to an area's WED and updates all the wallgroups:

    Spoiler
    DEFINE_PATCH_FUNCTION WED_ADD_POLYGON
      INT_VAR poly_flags = 0b00000000
    BEGIN
      // read the new vertex vars and convert them to array
      FOR (num = 0; VARIABLE_IS_SET EVAL ~new_vertex_%num%~; ++num) BEGIN
        SET $new_vertex(~%num%~) = EVAL ~new_vertex_%num%~
      END
      
      // calculate the next vertex index from the size of the vertex block
      SET next_idx = ((SOURCE_SIZE - LONG_AT (LONG_AT 0x14 + 0x08)) / 4)
      // set the current position to the end of the file since that's where the vertex block ends
      SET vert_pos = SOURCE_SIZE
      // set the vertex count to 0
      SET vert_cnt = 0
    
      // init the bounding box coords
      SET min_x_coord = 0
      SET min_y_coord = 0
      SET max_x_coord = 0
      SET max_y_coord = 0
    
      PHP_EACH new_vertex AS i => point BEGIN
        INSERT_BYTES vert_pos 0x04 // add 4 bytes for the new vertex
        WRITE_LONG vert_pos point // write the vertex data down
        
        SET x_coord = SHORT_AT (vert_pos + 0x00)
        SET y_coord = SHORT_AT (vert_pos + 0x02)
        
        // update the coords for the bounding box of the polygon
        PATCH_IF (x_coord < min_x_coord) OR (min_x_coord = 0) BEGIN min_x_coord = x_coord END
        PATCH_IF (x_coord > max_x_coord) OR (max_x_coord = 0) BEGIN max_x_coord = x_coord END
        PATCH_IF (y_coord < min_y_coord) OR (min_y_coord = 0) BEGIN min_y_coord = y_coord END
        PATCH_IF (y_coord > max_y_coord) OR (max_y_coord = 0) BEGIN max_y_coord = y_coord END
        
        SET vert_pos += 0x04 // set position pointer to the next vertex
        SET ++vert_cnt // increase vertex count
      END
      
      // calculate the position of next polygon from the current offset and number
      SET poly_idx = LONG_AT (LONG_AT 0x14) // polygon count is also the next polygon index
      SET poly_pos = (LONG_AT (LONG_AT 0x14 + 0x04)) + (poly_idx * 0x12)
      
      // insert a new polygon
      INSERT_BYTES poly_pos 0x12
      WRITE_LONG (poly_pos + 0x00) next_idx // starting vertex index
      WRITE_LONG (poly_pos + 0x04) vert_cnt // number of vertices
      WRITE_BYTE (poly_pos + 0x08) poly_flags // polygon flags
      WRITE_BYTE (poly_pos + 0x09) 0xff // z-index
      WRITE_SHORT (poly_pos + 0x0a) min_x_coord // min x coordinate of bounding box
      WRITE_SHORT (poly_pos + 0x0c) max_x_coord // max x coordinate of bounding box
      WRITE_SHORT (poly_pos + 0x0e) min_y_coord // min y coordinate of bounding box
      WRITE_SHORT (poly_pos + 0x10) max_y_coord // max y coordinate of bounding box
      
      // update polygon count by 1
      WRITE_LONG (LONG_AT 0x14 + 0x00) THIS + 1
    
      // update polygon index lookup table offset by size of polygon
      WRITE_LONG (LONG_AT 0x14 + 0x10) THIS + 0x12
      
      // fetch the map width and height in pixels
      SET map_width = SHORT_AT (LONG_AT 0x10 + 0x00) * 0x40
      SET map_height = SHORT_AT (LONG_AT 0x10 + 0x02) * 0x40
      
      // calculate the number of wallgroups along each axis and total count
      SET x_groups = (map_width / 640) + ((map_width MODULO 640) > 0)
      SET y_groups = (map_height / 480) + ((map_height MODULO 480) > 0)
      SET wg_count = x_groups * y_groups
      
      // determine which wallgroups the polygon falls into
      FOR (y = (min_y_coord / 480); y <= (max_y_coord / 480); ++y) BEGIN
        FOR (x = (min_x_coord / 640); x <= (max_x_coord / 640); ++x) BEGIN
          SET wg_idx = x + (y * x_groups)
          SPRINT $wallgroups(~%wg_idx%~) ~%x%.%y%~
        END
      END
      
      // ready polygon index table and wallgroups offset
      SET poly_idx_tbl = LONG_AT (LONG_AT 0x14 + 0x10)
      SET wallgroup_offset = LONG_AT (LONG_AT 0x14 + 0x0c)
      
      SET idx_tab_inc = 0
      
      // update wallgroup(s)
      PHP_EACH wallgroups AS i => _ BEGIN
        // get offset of current wallgroup
        SET curr_wg_offset = wallgroup_offset + (i * 0x04)
        
        // increase the starting polygon index by amount of previous table inserts
        WRITE_SHORT curr_wg_offset THIS + idx_tab_inc
        
        // read index table offset + count
        SET start_idx = SHORT_AT (curr_wg_offset + 0x00)
        SET poly_cnt = SHORT_AT (curr_wg_offset + 0x02)
        
        // add polygon entry to the index table
        SET new_tbl_offset = poly_idx_tbl + ((start_idx + poly_cnt) * 0x02)
        INSERT_BYTES new_tbl_offset 0x02
        WRITE_SHORT new_tbl_offset poly_idx
        
        // update the polygon count for the current wallgroup
        WRITE_SHORT (curr_wg_offset + 0x02) THIS + 1
        
        FOR (wg = 0; wg < wg_count; ++wg) BEGIN
          // increase the starting index of all the wallgroups with the index >= than the added one
          SET tbl_idx = SHORT_AT (wallgroup_offset + (wg * 0x04))
          
          PATCH_IF (tbl_idx >= (start_idx + poly_cnt)) BEGIN 
            WRITE_SHORT (wallgroup_offset + (wg * 0x04)) THIS + 1
          END
        END
        
        SET ++idx_tab_inc // increase currently-inserted table entries
      END
      
      // update vertices offset by size of polygon and changes to index table
      WRITE_LONG (LONG_AT 0x14 + 0x08) THIS + (0x12 + (idx_tab_inc * 0x02))
    END

    Example usage:

    Spoiler
    COPY_EXISTING ~AR1234.wed~ ~override~
      LPF WED_ADD_POLYGON
        INT_VAR
          poly_flags = 0b00001000
          new_vertex_0 = 100 + (100 << 16)
          new_vertex_1 = 200 + (100 << 16)
          new_vertex_2 = 200 + (200 << 16)
          new_vertex_3 = 100 + (200 << 16)
      END

    Let me know if you find any issues with it so that we can fix it. 🙂

  9. Does anyone have a handy WeiDU macro for adding new polygons to wall groups in pre-existing areas? We are considering writing our own, but I figured we should ask first to save us some frustration. It seems straightforward enough, but working with binary data and offsets and counts generally leads to a lot of gray hair and corrupted files. :D

  10. 11 hours ago, Guest Morgoth said:

    Hey Skye, you planning to release something?

    Ken and I have recently released our Ayden Project mod (we're still waiting for a G3 release, but it's available elsewhere), and we are currently working toward releasing the next version with some major content updates, including some new areas.

  11. I have an area where I would like certain parts to be passable or impassable periodically. Is there a way to dynamically block movement through a region on the map?

    I was thinking maybe an undetectable door that opens and closes via script. It has a blocking region and its own open/closed appearance, so that's convenient.

    Has anyone worked on anything with a similar effect? What was your approach?

  12. 9 hours ago, subtledoctor said:

    Like several other things, this doesn't do what you think it does. It was designed just for multiclasses, to e.g. prevent you choosing a 9th-level spell before you can cast 9th-level spells.

      I see. This is poorly documented in IESDP too, then. Good to know if I ever decide to mess around with the table again.

    9 hours ago, subtledoctor said:

    That’s fascinating! I never thought to try that! If I knew that a few years ago I would have made a feats mod much sooner!

    As long as all of us are a little bit wiser now, it wasn't a waste of time, I guess. 🙂

    9 hours ago, Allbrother said:

    You can kind of achieve a similar effect with a combination of opcodes #171 and #214

    I use that for certain parts of my mod, but it's not good enough for what I'm trying to achieve.

    I guess I'll look into modding the UI. Maybe I can achieve the same result with a custom panel and some Lua.

  13. 3 hours ago, subtledoctor said:

    One option: set the kit to use an existing table (doesn’t matter which, can be Fi0), then use my HLA table-modifying function to give it whatever custom HLAs you want.

    Doesn't do me any good. I also need the kit to start receiving HLAs very early, so it's not just about the ability table.

    1 hour ago, lefreut said:

    The SoD UI is missing the HLA screen (I think the BGEE UI has it).

    You seem to be correct. The old BG:EE UI has the Abilities button. The SoD one does not. I suppose I could mod the button back in with a GUI mod.

    To answer some of my own questions:

    • Despite IESDP saying otherwise, there seems to be no way to add a custom kit to LUNUMAB.2DA. As far as I can tell, the game ignores it.
    • HLAs are theoretically available in BG:EE, but the GUI elements are missing in SoD UI and need to be added back in with a GUI mod.
    • It is possible to define more than 24 HLAs in the LU*.2DA table, since the HLA screen is now scrollable and not just a fixed grid.
    • The MIN_LEV field seems to behave strangely, at least with HLAs past the initial 24. Need to research it further.
    • The rates in LUNUMAB.2DA can be decimals (0.5 seemed to work fine for 1 point/2 levels).

    At this point, unless someone knows something that I've missed, there doesn't seem to be any way for me to make a custom HLA progression for my kit, so this whole idea goes down the drain. My disappointment is immeasurable and my day is ruined...

  14. We are attempting to make use of HLAs for one of our custom kits in BG:EE, with no success. The LUABBR.2DA has the correct suffix for the LU*.2DA file, we added the kit and set the correct values for it in LUNUMAB.2DA, but when a character levels up, nothing seems to happen. I tried to modify a standard thief's HLA gain rate in LUNUMAB.2DA and it just gets stuck at the level up screen, with no way to select an ability, but no way to finish leveling up either.

    In light of all that, I have the following questions:

    1. Are HLAs simply not available in BG:EE due to GUI limitations?
    2. Is there any way to enable them short of porting the entire game to BG2:EE engine?
    3. Can you even specify custom kits in LUNUMAB.2DA? It seems to disregard my entry entirely.
    4. Is it possible to specify more than 24 abilities in the LU*.2DA file or does the engine stop parsing at line 24?
  15. So, I did test my theory and it turned out to be true. I also needed to update the BAM indices manually since argent's functions don't really support image resources that use the same PVRZ page. Doing so does have the added perk of being able to name your PVRZ files whatever you want though, which makes things a bit easier to work with.

    LAF FIND_FREE_PVRZ_INDEX RET large_pvrz_index = free_index END
    COPY ~project/pvrz/icons_large.pvrz~ ~override/MOS%large_pvrz_index%.pvrz~
    
    COPY ~project/bam/mybam01.bam~ ~override~
      READ_LONG 0x001c data_offset
      WRITE_LONG data_offset large_pvrz_index

    Something like that works just fine. Of course, if the BAM file were to have multiple data blocks or PVRZ pages, one would need to do a bit more work.

  16. Yeah, what caught me off guard was that the script kept running after I had already left the area. That was just weird.

    But I do have a better idea of how trigger regions actually work now and I've completed the entire area without too much trouble.

  17. Looking at the source code, from what I can tell, it only makes a difference if your BAMs use multiple PVRZ pages. You can then foreach through all of your PVRZs and update their indices to the new block indices that you got from UPDATE_PVRZ_INDICES. So for small images, like spell icon BAMs, you're probably better off copying them by hand to reduce the amount of unnecessary code.

×
×
  • Create New...