Jump to content


  • Posts

  • Joined

  • Last visited

Posts posted by DavidW

  1. 5 hours ago, AL|EN said:

    @DavidW The tp2 'VERSION' keyword still has 2.0.13.


    5 hours ago, AL|EN said:

    Even if you override it via MOD_VERSION variable, the weidu.log still has 2.0.13. I suggest to remove it to avoid confusion and future mistakes.

    This kind of assumes I put it in just to be annoying and make difficulty, rather than because I actually need it for something concrete that I can't work around on the current version of WEIDU.

  2. 3 hours ago, Endarire said:

    In terms of scope, how easily implemented is my solution of changing the map travel times to 0, avoiding all encounters, 'fast traveling' to the location, then returning things to normal post-warp?

    Impossible without engine hacks, I *think*. (If there’s an ingame way to edit travel times, I don’t know it, though it’s not something I’ve looked for extensively.)

    If you’re set on this strategy, I agree with Lynx: do a technical proof-of-concept before worrying about fine details.

  3. At the technical level, the simplest way to do this is by script and dialog. Teleport just summons an invisible creature that initiates dialog. Use the dialog options to select where you teleport to and to control what options are available and whether you're allowed to do it at all. Implement teleportation to an area via an area-specific cutscene called from the dialog, and put the special effects into that cutscene. That's fairly easy to implement. It would obviously be cooler to have a graphical select option but it would be radically harder to do (lots of UI editing at the least, possibly EXE changes.)

    That said, I think the problems of breaking the plot are fairly severe. You have to lock down quite a few areas, with not very much in the way of in-game justification, in order to avoid messing with the whole leave-and-return structure of chapters 4-5. (A party who can teleport doesn't really have any reason to accept the underdark-vs-Saemon dilemma at the end of chapter 4.) And it would be quite difficult to deal with the various forced random encounters that the game (and probably also some mods) triggers from time to time.

  4. Question: AI scripts for the planetar hardcode the spells they expect it to have, so if you add new spells, it won't use them. There's no workaround to that, short of writing your own AI.

    Requests: probably not in both cases, sorry. The complexity is excessive relative to the gain; use EEKeeper. And in addition I'm not aware of all the ramifications of putting kits on multiclass characters like that either, which means I don't want to risk implementing it and finding it leads to trouble down the line. I am *slightly* more tempted by the ability-score swap but it's very much not a priority.

  5. @Luke you can do it with LOOPs though.

    BEGIN LOOP(x||65)
    INCLUDE FILE(test.ssl)
    BEGIN LOOP(x||85)
    INCLUDE FILE(test.ssl)

    I actually think I might have done it that way before and changed it on an erroneous assumption about how variable-substitution works in SSL.

    (Obviously, in this particular case it would be better to do BEGIN LOOP(x||65;85)

  6. 25 minutes ago, subtledoctor said:

    Also weird/unfortunate that the "ignore dead magic" flag in spells does not in fact ignore the "dead magic" flag in areas.  That's real basic "do what it says on the tin" kind of stuff.  Maybe someone should bring that to Beamdog's attention for the 2.6 patch...

    To be fair to Beamdog, it's not as if the flags are called that in any official material. It's what Near Infinity calls them. If NI's description doesn't match what the game engine does, that's for NI to fix.  (The writing on the tin was put there by third parties, not the tin owner.) The proper description of the SPL flag would probably be 'ignore the dead-magic settings of opcode 66'. 

    (And to be fair to Near Infinity, their descriptions are not intended to be full descriptions, just something short enough to fit in the interface.)


  7. To repeat a comment of mine from earlier:

    "Mine is a pretty conservative restoration of the original cut content; Oversight’s has the same idea as the original cut content but a quite different implementation."

    I - obviously - prefer mine but the differences are comparatively minor (I think mine might be a bit more dialog-heavy, and you have to kill Kangaxx in Kish's). Given that mine doesn't have technical incompatibilities with SCS, you're probably better off using mine than trying to coax Kish's into working with SCS.

    There is a fairly detailed readme in my version that explains what it does in some depth, in case that's useful to you.

  8. I'm finding that the alignment comes back wrong even if you just permute rows.

    ... I'm basically concluding that this is more trouble than it's worth. The game is doing some weird lookup stuff that doesn't really track the implied logic of its tables, and the risk of breaking something is probably too high. Thanks for your help with it.

  9. That's matching some of what I've just been finding. I got through character creation ok but was getting alignment anomalies. Will test a bit more, if only for my own curiosity. It offends my mathematical sensibilities to have arbitrary rules like this...

    EDIT: If I understand that correctly, won't it always be satisfied? I'm only permuting table entries, not deleting any. (But then, in that case I shouldn't have got alignment anomalies on my own run.

  10. That's one of the things I was interested in advice about. I think that the actual row number in kitlist.2da turns up in game in very few places. CRE files put the KITIDS entry from kitlist.2da into the kit field, not the row number. Likewise, opcodes 177, 318, 324, 326 check the ids number, So do BCS triggers. And of course rearranging the order of entries in kitlist.2da doesn't change which ids entry is associated with which kit. CLAB files appear directly in kitlist.2da and don't need looking up. LUA entries are from LUABBR, which looks up by rowname, not rownumber. Proficiencies are indexed directly via the proficiency entry in kitlist. And so on.

    The k_x_y 2das that associate kits to race/class combos do a direct lookup via kitlist rownumber. So far as I can tell that's the only place it's used. (And my code above updates them.)

    But: I admit freely that this is not my main area of expertise. If I'm missing something, I'd be glad to be told.


  11. This works, I think.

    DEFINE_ACTION_FUNCTION dw_reorder_kitlist BEGIN
    	// parse kitlist to get number=>multiclas map
    	ACTION_CLEAR_ARRAY is_multiclass
    	COPY_EXISTING "kitlist.2da" override
    		COUNT_2DA_COLS colcount
    		READ_2DA_ENTRIES_NOW dw_kitlist_data colcount
    		FOR (row=0;row<dw_kitlist_data;++row) BEGIN
    			READ_2DA_ENTRY_FORMER dw_kitlist_data row 0 number
    			READ_2DA_ENTRY_FORMER dw_kitlist_data row 8 class_id
    			LPF class_is_multiclass STR_VAR class_id RET multiclass END
    			PATCH_IF multiclass BEGIN
    				SET $is_multiclass("%number%")=1
    	// destructively parse kitlist to get the data
    	ACTION_CLEAR_ARRAY kitlist_contents
    	COPY_EXISTING "kitlist.2da" override
    		REPLACE_EVALUATE "^\([0-9]+\)[ %TAB%]+\([^ %TAB%].*\)" BEGIN
    			SPRINT $kitlist_contents("%MATCH1%") "%MATCH2%"
    	BUT_ONLY // obviously it will change, this is just for neatness
    	ACTION_CLEAR_ARRAY kit_number_map
    	OUTER_SET number_new=0
    	OUTER_SPRINT kitlist_write ""
    	// put the single-class data back
    	ACTION_PHP_EACH kitlist_contents AS number=>data BEGIN
    		ACTION_IF !VARIABLE_IS_SET $is_multiclass("%number%") BEGIN // single-class kit
    			OUTER_SET $kit_number_map("%number%")=number_new
    			OUTER_SPRINT kitlist_write "%kitlist_write%%number_new%%TAB%%data%%WNL%"
    			OUTER_SET number_new=number_new+1
    	// put the multi-class data back
    	ACTION_PHP_EACH kitlist_contents AS number=>data BEGIN
    		ACTION_IF VARIABLE_IS_SET $is_multiclass("%number%") BEGIN //multiclass kit
    			OUTER_SET $kit_number_map("%number%")=number_new
    			OUTER_SPRINT kitlist_write "%kitlist_write%%number_new%%TAB%%data%%WNL%"
    			OUTER_SET number_new=number_new+1
    	// write the data to kitlist
    	APPEND "kitlist.2da" "%kitlist_write%"
    	COPY_EXISTING "kitlist.2da" override PRETTY_PRINT_2DA
    	// update the k_x_y entries
    	COPY_EXISTING "kittable.2da" override
    		COUNT_2DA_COLS colcount
    		READ_2DA_ENTRIES_NOW dw_kittable_data colcount
    		FOR (row=0;row<dw_kittable_data;++row) BEGIN
    			FOR (col=1;col<colcount;++col) BEGIN
    				READ_2DA_ENTRY_FORMER dw_kittable_data row col file
    					LAF remap_k_x_y STR_VAR file END
    DEFINE_PATCH_FUNCTION class_is_multiclass STR_VAR class_id=0 RET multiclass
    	PATCH_MATCH "%class_id%" WITH
    	7 8 9 10 13 14 15 16 17 18 BEGIN
    		SET multiclass=1
    		SET multiclass=0
    		COPY_EXISTING "%file%.2da" override
    			COUNT_2DA_ROWS 2 rowcount
    			FOR (row=0;row<rowcount;++row) BEGIN
    				READ_2DA_ENTRY row 1 2 number
    				PATCH_IF IS_AN_INT number BEGIN
    					SET new_number=$kit_number_map("%number%")
    					SET_2DA_ENTRY row 1 2 new_number


  12. 5 minutes ago, subtledoctor said:

    I've never tried putting a single-class kit into e.g. K_FM_HE.2da, don't know if that works. 

    It does, so far as I can see. It's a very quick lightweight way of making a singleclass kit multiclassed, but it leaves out lots of features - the LUA table for one. I think it's mostly a curiosity.


    6 minutes ago, subtledoctor said:

    Correct.  QDMulti adds a single AP_ spell to the core kitless class tables, and then populates each single spell at each level with opcode 177 effects targeting multiclass kits that have kit effects at that level.  The 177 effects reference .EFFs that use opcode 146 or opcode 171, representing the AP_ and GA_ entries of a multiclass kit table, respectively.

    Do you know if there's any particular advantage of using 177 and EFFs rather than just 326?


    7 minutes ago, subtledoctor said:

    There was discussion about doing this - the idea raised was, fill out kitlist.2da with dummy entries when a multiclass kit is installed, so that all multiclass kits are installed at entry #256+; and then jazz up ADD_KIT to automatically replace the dummy entries when installing single-class kits.  The concerns that kept it in the realm of the hypothetical were 1) the effort involved, and 2) compatibility with legacy mods.

    That does sound messy. I was thinking of something simpler - just run a function that reorders kitlist.2da and relabels the numbers in the k_x_y.2da files. Then you could call it after installing a single-class kit, and (unless I'm missing something) there wouldn't be any legacy-mod problems. I don't think that would be too hard to do - I might see if I can work something up.

  13. Partly for the sake of trying something new, I've been trying to get my head around how the kit system works on EE, especially with respect to multiclassed kits. Here's a quick summary of what I think is correct (and one proposal): if any of the various people who know this part of the engine better than me wanted to confirm (or deny!) that I'm understanding it correctly, I'd appreciate it.

    1) The engine is perfectly happy for you to define a kit with a multiclass parent class.

    2) The engine, and the chargen UI, are perfectly happy for you to assign a multiclass or single-class kit to the kit-selection 2da for a multiclass. 

    3) If you attach a single-class kit to a multiclass character, it overrides the relevant component class. So a Fighter/Mage could become a Berserker/Mage or a Fighter/Invoker, and the character will be listed as Fighter level X... Invoker level Y on the character page. (Indeed, that's how the existing Fighter/Illusionist is defined.) Since the component classes of a multiclass character determine the CLAB table, you end up using the kit's CLAB table for the relevant class. But since the multiclass controls the LUA table, you still use the vanilla multiclass HLAs.

    4) Conversely, if you attach a multiclass kit to a multiclass character, it overrides the multiclass. So a Fighter/Mage could become... well, anything you like... though the character will still be listed as Fighter level X... Mage level Y on the character page. Since the component classes are unchanged, you draw the CLAB entries from the vanilla tables for the component classes, and any kit-defined CLAB is ignored (though of course you can do kit-specific abilities using a 318/326-gated AP_ in the component-class CLAB - I assume that's how QDMULTI works, though I haven't looked at the code). Since the multiclass is changed, you can sub in a kit-specific LUA. 

    5) The engine sulks (i.e. crashes) if you try to use a CLAB file defined in a kitlist.2da entry higher than 255. But it's otherwise happy to use kitlist entries as high as you like: it will cheerfully read names, descriptions, IDS entries etc from high-numbered kitlist rows. That means that the ceiling of 255 kits applies only to single-class kits: you can have as many multiclass kits as you like. BUT the single-class kits need to be first in kitlist.2da, or at least, any spaces after row 255 have to be for multiclass kits. 

    (I appreciate there's also a problem if you use WEIDU's built-in ADD_KIT command, which is hardcoded to complain if you go above 255 kits. SFO's make_kit function doesn't have that problem, and I think argent77 also has a kit-adding function that avoids the problem?)

    If all that's right, presumably it would be sensible to sort kitlist.ids (and make the necessary adjustments to the k_x_y.2da files) after installing a single-class kit, so as to make sure single-class kits precede multiclass kits? (Otherwise you get quite a strong install-order constraint - install single-class kits first - albeit it only matters on quite heavily modded installs.) Am I missing any problem or subtlety that would arise from doing so? Has someone already written code to do it? (If not, I might write some myself.)

  • Create New...