Jump to content

DavidW

Gibberlings
  • Posts

    8,009
  • Joined

  • Last visited

Everything posted by DavidW

  1. I guess GOTO doesn't require you to put the name of a dialog file at all, so case-sensitivity doesn't apply.
  2. Bizarrely, ALTER_TRANS appears to be case-sensitive. If I do <<<<<<<< .../stratagems-inline/test.d ALTER_TRANS bdff1709 BEGIN 2 END BEGIN 1 END BEGIN "EPILOGUE" "EXTERN bdff1709 0" END ALTER_TRANS bdff1709 BEGIN 4 END BEGIN 0 END BEGIN "EPILOGUE" "EXTERN bdff1709 7" END >>>>>>>> COMPILE ".../stratagems-inline/test.d" then I can reproduce Jastey's bug. If I do <<<<<<<< .../stratagems-inline/test.d ALTER_TRANS bdff1709 BEGIN 2 END BEGIN 1 END BEGIN "EPILOGUE" "EXTERN BDFF1709 0" END ALTER_TRANS bdff1709 BEGIN 4 END BEGIN 0 END BEGIN "EPILOGUE" "EXTERN BDFF1709 7" END >>>>>>>> COMPILE ".../stratagems-inline/test.d" it works fine. Probably worth reporting to Wisp - it's undocumented as far as I can see.
  3. You could debate if that's how it ought to work, but it's not really in SCS's scope to adjust it.
  4. If you do PHP_EACH array AS k=>v for a multidimensional or variable-dimensional array, it cycles through all elements of the array. v is set to the value; k_0 is set to the first key, k_1 to the second key (if any), k_2 to the third (if any), and so on. k is a synonym for k_0. (This is documented in the WEIDU readme but quite obscurely - I only understood it myself recently and I've hardly ever seen it used in a mod in the wild, though I've started using it myself quite a lot.) That's often an inefficient way to cycle through a 2da that you've read in, of course; that's indeed why I read in rows and columns. If you want, say, to go through all entries in a particular column, it's easier to do something like PHP_EACH clastext_rows AS row=>discard BEGIN desc_here=$clastext_array("%row%" "descstr") [do something with row and desc_here] END
  5. They’re not automatically immune to Sunray, but it does magical damage (iirc) and they often have Protection from Magic Energy running.
  6. WEIDU is fine with multidimensional (or variable-dimensional) arrays. You can have a function that reads a 2da and spits out a 2D WEIDU array labelled by rows and columns. This is my (probably overcomplicated) version: Basic use: COPY_EXISTING - "clastext.2da" nowhere LPF 2da_read RET_ARRAY clastext_array=array clastext_rows=rows clastext_cols=columns END Code: ////////////////////////////////////////////////////////////////////////////////////// /* document{2da_read} { Read a 2da file (or, in patch context, the current 2da file) into a 2d array. Also return an array of uppercased row headers and column headers, in the format row_label=>row_number. ('case' controls the case of the row and column headers; it's uppercase by default on genuine 2das, mixed by default otherwise) In action context, if the file doesn't exist return 0; otherwise, return 1. Also whine if it doesn't exist, unless silent=1. If the file is a 2da, and 'reflect' is set, reverse rows and columns. If it's a 2da, and 'allow_incomplete_lines' is set, don't require that all lines are complete. If it's a 2da, and "rowname_column" is set, use that column (if it's present) for the row names instead of the usual entries. If 'rowmap' and/or 'colmap' are set, they get applied to the row and column entries before the array is constructed. If 'allow_incomplete_lines' is set, we can handle incomplete lines (filling with the default). } */ ////////////////////////////////////////////////////////////////////////////////////// DEFINE_PATCH_FUNCTION "2da_read" INT_VAR silent=0//boolean reflect=0//boolean allow_incomplete_lines=0//boolean STR_VAR type=""//[2da|ids|table_header|table_no_header] rowmap=""//function colmap=""//function rowname_column="" case=""//[upper|lower|mixed] RET_ARRAY columns rows array BEGIN // initialize CLEAR_ARRAY columns CLEAR_ARRAY rows CLEAR_ARRAY array // try to infer type PATCH_IF "%type%" STR_EQ "" BEGIN PATCH_IF "%rowmap%" STR_CMP "" || "%colmap%" STR_CMP "" BEGIN SPRINT type "2da" END ELSE BEGIN READ_ASCII 0x0 sig (3) PATCH_MATCH "%sig%" WITH "2da" "ids" BEGIN SPRINT type "%sig%" END DEFAULT PATCH_MATCH "%SOURCE_EXT%" WITH "2da" "ids" BEGIN SPRINT type "%SOURCE_EXT%" END DEFAULT SPRINT type "table_header" END END END END // get column width & length COUNT_2DA_COLS colcount COUNT_2DA_ROWS colcount rowcount PATCH_MATCH "%type%" WITH "2da" BEGIN // get the default READ_2DA_ENTRY 1 0 1 default // check if it's empty COUNT_2DA_ROWS 1 empty_check is_empty=(empty_check=3) // get the col headers (& also the lookup column if appropriate) lookup_col_num=0 COUNT_2DA_COLS colcount COUNT_2DA_ROWS colcount rowcount PATCH_MATCH "%colcount%" WITH 2 BEGIN col_row=2 main_row=1 END 3 BEGIN col_row=1 main_row=0 END DEFAULT col_row=0 main_row=0 END READ_2DA_ENTRIES_NOW 2da_coldata (colcount - 1) FOR (col=1;col<colcount;++col) BEGIN READ_2DA_ENTRY_FORMER 2da_coldata col_row (col - 1) value PATCH_MATCH "%value%" WITH "%rowname_column%" BEGIN lookup_col_num=col END DEFAULT END PATCH_MATCH "%case%" WITH lower BEGIN TO_LOWER value END upper BEGIN TO_UPPER value END mixed BEGIN END DEFAULT TO_UPPER value END PATCH_IF !reflect BEGIN SET $columns("%value%")=col END ELSE BEGIN SET $rows("%value%")=col END END PATCH_IF is_empty BEGIN LPF array_map STR_VAR array=columns keymap="%colmap%" RET_ARRAY columns=array END SPRINT $rows("null") discard SPRINT $array("null") discard END ELSE BEGIN // get the rows READ_2DA_ENTRIES_NOW 2da_data colcount FOR (rownum=main_row;rownum<2da_data;++rownum) BEGIN READ_2DA_ENTRY_FORMER 2da_data rownum lookup_col_num value PATCH_MATCH "%case%" WITH lower BEGIN TO_LOWER value END upper BEGIN TO_UPPER value END mixed BEGIN END DEFAULT TO_UPPER value END PATCH_IF !reflect BEGIN SET $rows("%value%")=rownum END ELSE BEGIN SET $columns("%value%")=rownum END END // map rows and columns if needed LPF array_map STR_VAR array=columns keymap="%colmap%" RET_ARRAY columns=array END LPF array_map STR_VAR array=rows keymap="%rowmap%" RET_ARRAY rows=array END PATCH_IF allow_incomplete_lines BEGIN // get the data into a working array READ_ASCII 0x0 data (BUFFER_LENGTH) LPF data_lines STR_VAR data RET_ARRAY lines END PHP_EACH lines AS ind=>line BEGIN PATCH_IF ind>=3 BEGIN LPF array_values_from_string INT_VAR quick=1 STR_VAR string="%line%" RET_ARRAY temparray=array END LPF array_length STR_VAR array=temparray RET length END SPRINT row $temparray(0) row_int=ind - 3 +main_row PATCH_IF !reflect BEGIN SPRINT columns_or_rows columns END ELSE BEGIN SPRINT columns_or_rows rows END PHP_EACH "%columns_or_rows%" AS col=>int BEGIN PATCH_IF int<=length BEGIN SPRINT $working_array("%row_int%" "%int%") $temparray("%int%") END ELSE BEGIN SPRINT $working_array("%row_int%" "%int%") "%default%" END END END END // get it into the final array PHP_EACH rows AS row=>row_int BEGIN PHP_EACH columns AS col=>col_int BEGIN PATCH_IF !reflect BEGIN SPRINT $array("%row%" "%col%") $working_array("%row_int%" "%col_int%") END ELSE BEGIN SPRINT $array("%row%" "%col%") $working_array("%col_int%" "%row_int%") END END END END ELSE BEGIN PHP_EACH rows AS row=>row_int BEGIN PHP_EACH columns AS col=>col_int BEGIN PATCH_IF !reflect BEGIN READ_2DA_ENTRY_FORMER 2da_data row_int col_int entry END ELSE BEGIN READ_2DA_ENTRY_FORMER 2da_data col_int row_int entry END SPRINT $array("%row%" "%col%") "%entry%" END END END END END "ids" BEGIN READ_2DA_ENTRIES_NOW 2da_data 2 // set cols SET $columns("int")=0 SET $columns("sym")=1 // get main data count=0 FOR (row=0;row<2da_data;++row) BEGIN READ_2DA_ENTRY_FORMER 2da_data row 0 int READ_2DA_ENTRY_FORMER 2da_data row 1 sym PATCH_IF IS_AN_INT int BEGIN SET $array("%count%" "int")=int SPRINT $array("%count%" "sym") "%sym%" ++count END END // set rows FOR (row=0;row<count;++row) BEGIN SET $rows("%row%")=row END END "table_header" BEGIN COUNT_2DA_COLS colcount READ_2DA_ENTRIES_NOW 2da_data colcount // get columns FOR (col=0;col<colcount;++col) BEGIN READ_2DA_ENTRY_FORMER 2da_data 0 col value PATCH_MATCH "%case%" WITH lower BEGIN TO_LOWER value END upper BEGIN TO_UPPER value END DEFAULT END SET $columns("%value%")=col END // get data; set rows FOR (ind=1;ind<2da_data;++ind) BEGIN row=ind - 1 SET $rows("%row%")=row PHP_EACH columns AS col=>colnum BEGIN READ_2DA_ENTRY_FORMER 2da_data ind colnum value SPRINT $array("%row%" "%col%") "%value%" END END END "table_noheader" BEGIN COUNT_2DA_COLS colcount READ_2DA_ENTRIES_NOW 2da_data colcount // set columns FOR (col=0;col<colcount;++col) BEGIN SET $columns("%col%")=col END // get data; set rows FOR (ind=1;ind<2da_data;++ind) BEGIN row=ind - 1 SET $rows("%row%")=row PHP_EACH columns AS col=>colnum BEGIN READ_2DA_ENTRY_FORMER 2da_data ind colnum value SPRINT $array("%row%" "%col%") "%value%" END END END DEFAULT PATCH_FAIL "2da_read: unidentified read type %type%" END END
  7. Four in the unmodded game, I think: Fallen Solars, the Ravager, the Aurumach Rilmani, and the Lesser Demon Lord. (And any wizard who casts Improved Mantle, of course!)
  8. I meant Confusion for Chaos - but yes, I was also forgetting you're using mods that make Spell Turning/Deflection affect AoE. I can see that changes the game a lot. If you let Spell Deflection/Turning block AoE you certainly remove the main distinctive benefit of globes.
  9. I think you're all underrating GoI at higher levels. It protects against the contents of Spell Sequencers; even at high levels, 3x Chaos or 3x Skull Trap is non-trivial.
  10. No, SCS has never worked for oBG1. My embryonic, pre-public, pre-tutu version was written for BG1, but I rapidly decided it was too much of a pain. (Pausing the game can interrupt enemy spellcasting.)
  11. The UI is just a button to press to activate the dialog. I think a full-UI version is theoretically possible, but it's a lot of work and I'm not sure it's worth it.
  12. If you check the readme you’ll see that all the existing HLA and toughest-spawn options are still available; you just need to set them using the ‘customize difficulty’ control. (The contents of CC are randomized at install time.)
  13. I don't think either do anything except enable the quest.
  14. I can't reproduce this on an SCS-only install. What else do you have installed?
  15. Again, not in SCS's remit. (Use SI:Abjuration.)
  16. If you're cloning spells, it will lead to other problems: spells that give explicit immunity to a spell won't give immunity to the cloned copy. I imagine you're patching that at the point at which the mod is installed, but that won't help for subsequent mods. I take the point about Cowled Wizards (and thanks: that hadn't occurred to me as an issue) but I suspect it's the lesser of two evils. SR behavior isn't being modified by SCS, but only because SCS explicitly insulates SR. Specifically, SCS does (by design) rewrite fiend-summoning spells, to summon alignment-appropriate fiends, but it excludes the player-controlled version from that rewrite if SR is installed, and it does so by giving it renamed resources. (I can't just skip these changes entirely if SR is installed, because enemy AI relies on them, and coding around that exceeds the amount of effort I'm prepared to go to to support SR's spell system.) That works fine for SR itself, but it creates problems when some third mod uses summoned-fiend resources too. SCS doesn't know that, so there's a mismatch between what the cloned spell does (summon a friendly fiend) and what the resources do (create a fiend with an I'm-not-friendly script). That isn't to say there's anything intrinsically wrong with FnP's clone strategy - it's a tradeoff between one set of problems and another. Ultimately the spell system is not by nature modular.
  17. Casts, or clones? From Alkaid's description it sounds as if the new spell points to an effect file that points to a cre file (which sounds like a clone of SPWI807), not points direct to SPWI807.
  18. In SCS: - the default summoned fiends have an AI script intended for uncontrollable, hostile fiends - if those fiends are summoned by an enemy (mostly this is liches, plus a very few living spellcasters) they swap to a much better-behaved, more controllable script - there is a narrow and hidden route by which players can also summon controllable fiends. In that case, again they get the better behaved script. That script will only have the fiends cast spells if they have no player instructions running (and you can turn off their AI entirely by hotkey). If SR is also installed, the player-summoned fiends are SR's, not SCS's, so the SCS behavior doesn't get seen at all. In this case, it sounds as if FnP has a fiend-summoning spell that is supposed to summon a player-controlled fiend (in which case you'll get a fiend with a script that doesn't fit its allegiance). But without looking at the spell, I can't tell directly.
  19. SCS isn't touching the FnP spell directly, it's touching DEMGLASU. It's adjusting hit points (in 'Improved Fiends') because I want to standardize hp before applying SCS's difficulty-based hp modifications (albeit I think the standardization is slightly funky - it should be setting hp to 80, not 70, and it shouldn't be leaving max hp unchanged).
  20. Yes, I'm not quite sure why SCS is doing that. (It definitely is, I just can't recall the rationale.) There's only so much I can do to catch third-party-added fiend-summoning spells, of course.
  21. There is no SCS 'Shapeshifter Rebalancing (Weimer)' component. SCS's 'Improved Shapeshifting' component has this description in the mod readme: There's nothing about immunity to +1 weapons. (Nor should there be, as it's absurdly overpowered. CHARNAME getting immunity to nonmagical weapons at the end of Shadows of Amn is arguably a bit overpowered; getting it at 1st level would be ridiculous.)
  22. OK, so 'DWDVGLAB.cre' and 'DWDVPITF.cre' are clones of, respectively, DEMGLASU.cre and DEMPITSU.cre. I make them so that I can isolate SR's versions of the spell from SCS's versions (which inter alia might summon demons or devils depending on caster alignment). SCS mages carry on using the SCS versions but players keep the SR versions. I don't otherwise modify those files - they should be identical to the SR versions - although they might be being swept up in some of SCS's general hp/thac0/save algorithms. What's actually wrong with them?
  23. There were some specific conversations between me and Demivrgvs, ages ago, about how to make SCS's and SR's death knights and fiend summons play nicely with each other; DWDVGLAB is one of the consequences of that, I think. It wouldn't surprise me if subsequent changes in how either SR or SCS is implemented has messed it up (to say nothing of SR-vs-SRR issues).
  24. To comment on this from a design perspective: SCS's design philosophy is to adjust the AI to play as effectively as possible within the existing rule system, and only to modify that rule system if it creates hard blocks, hard counters, or otherwise breaks gameplay. (This isn't SR(R)'s design philosophy, because SR(R) is a spell-revisions mod, not an enemy-AI mod.) So, from that perspective: in the vanilla game liches are immune to all level 1-5 spells, period. (You can't breach a lich's PMW in unmodded BG2, iirc - in fact I don't think there's any alternative to waiting it out.) So I'm not asking 'does it make sense for this to extend to antimagic attacks' but 'does this extending to antimagic attacks create insuperable problems?' From that POV, it's not a problem that Spell Thrust and Secret Word don't affect liches - there are other, higher level, anti-spell-defense spells, like Ruby Ray, that do affect them. But it is a problem that Breach doesn't affect them, because Breach is singular: no other spell does what it does. Short of adding new higher-level spells (which is again rather outside SCS's scope), letting Breach penetrate liches' defenses (and of course documenting that in the in-game description and mod readme) is the most minimal solution. Now, SCS has over the years got a bit more relaxed about spell system tweaks, both as it's got more popular (so that I don't need to worry so much about losing audience) and as WEIDU, and my ability to code in WEIDU, has got more sophisticated. These days I might consider just having a blanket rule that antimagic spells ignore level-based immunities - it would certainly be more legible to players, without seriously affecting game balance. There are implementation issues but they're not so serious for anti-spell-defense spells. (For Breach, I have to remove liches' immunity to level 5 spells and then manually grant immunity to all other level-5 spells - I can't just mess with the internal spell level because it's referenced in other game effects, e.g. spell turning. But I *think* that would be less of an issue with Spell Thrust and the like.)
  25. The tasloi spear is part of their core animation, i.e. can't be changed. And there aren't really multiple spear types they could carry (halberds are implausible and it's hard to think where they'd get high-quality weapons from).
×
×
  • Create New...