-
Posts
664 -
Joined
-
Last visited
Content Type
Forums
Events
Downloads
Gallery
Mods
News
Store
Posts posted by Grammarsalad
-
-
Book casting is especially cool. I had planned to do a ritual thing where certain spells are able to be cast 'as a ritual' for priests and mages (and prob bards) if known but not currently memorized.
I wanted to do it only with 'certain spells' because, as you point out, this can be abused if broadly applied (even if coding the thing would be easier).
Applying fatigue is a nice touch. I think I'll borrow that idea.
-
Is there is a reason this version isn't pinned or linked in the pinned version? I see a mention of possible crash on exit. Is this version considered 'stable'?
Trying to figure out if I should update from version 7.7.
-
Update, it looks like it works, but I had to make a slight change. I know you said not to read the cols but it freaked out and so I just used some of the original code to make it work again. I'm going to go back and see if I can strip out what isn't necessary, but for now this works:
ACTION_PHP_EACH clabz AS der_clab => der_levs BEGIN ACTION_IF (%der_levs% > 0) BEGIN OUTER_SET patch_row = 0 COPY_EXISTING ~%der_clab%.2da~ ~override~ PATCH_IF (FILE_CONTAINS_EVALUATED(~%der_clab%.2da~ ~SCRLCRFT~)) BEGIN // COUNT_2DA_COLS cols // ** don't bother counting cols READ_2DA_ENTRIES_NOW rows 2 FOR (row = 0; row < rows; ++row) BEGIN FOR (col = 0; col < cols; ++col) BEGIN READ_2DA_ENTRY_FORMER rows row col ~row_title~ PATCH_PRINT "What is %row_title%?" PATCH_IF (~%row_title%~ STRING_EQUAL_CASE ~SCRLCRFT~) BEGIN SET patch_row = row END END END PATCH_IF (patch_row > 0) BEGIN SET_2DA_ENTRY patch_row (%der_levs%) 2 ~GA_B_SCRIB~ // b_scrib END END BUT_ONLY END END
-
7 hours ago, subtledoctor said:
Ah that makes sense - append the row, then check the .ini before setting which level the GA_ should be at. In that case, try this:
ACTION_PHP_EACH clabz AS der_clab => der_levs BEGIN ACTION_IF (%der_levs% > 0) BEGIN OUTER_SET patch_row = 0 COPY_EXISTING ~%der_clab%.2da~ ~override~ PATCH_IF (FILE_CONTAINS_EVALUATED(~%der_clab%.2da~ ~SCRLCRFT~)) BEGIN // COUNT_2DA_COLS cols // ** don't bother counting cols READ_2DA_ENTRIES_NOW rows 2 FOR (row = 0; row < rows; ++row) BEGIN // FOR (col = 0; col < cols; ++col) BEGIN // don't need to check every column READ_2DA_ENTRY row 0 row_title PATCH_IF (~%row_title%~ STRING_EQUAL_CASE ~SCRLCRFT~) BEGIN SET patch_row = row END END PATCH_IF (patch_row > 0) BEGIN PATCH_PRINT "Row is %row% or %rows%. col is %col%. And line is %line%." SET_2DA_ENTRY patch_row (%der_levs%) 2 ~GA_B_SCRIB~ // b_scrib END END BUT_ONLY END END
Rationales:
- CLAB files can have crazy column counts on each row, so don't rely on it
- If for whatever reason the patch_row isn't identified, we don't want to use the variable value from the last iteration, so set it to 0 at the start of every PHP_EACH and set it to > 0 inside each CLAB patch, and only apply the change if it is > 0
- No need for S2ELater/S2ENow if you're only doing one patch
- I think the %der_levs% value should line up with the level number you want it to be, since the CLAB title column is col 0 and the level 1 column is col 1. But you might need to play around with that value in the patch
I haven't tested that at all so YMMV.
Awesome! Thanks! I'll give it a try
-
14 minutes ago, subtledoctor said:
Out of curiosity, why does it need to be in a particular row? Why not APPEND a whole new row? AFAIK the number of rows a CLAB table can process is functionally unlimited, and the column count doesn't even need to be consistent, so you can completely sidestep the "40 cols vs. 50 cols" problem. (I just always append rows with 50 columns.)
Well, I'm specifying the level that the char gets the ability by ini (so that the player can change it).
I actually do append a new row earlier in the code(headed by "SCRLCRFT"). My original solution was to find that newly appended line (i.e. by the text SCRLCRFT) and append at that particular line.
In the php above, "der_levs" is taken from the ini for the level to be applied.
There is probably a better way to do it but I can't think of one atm. Any ideas?
-
Hello. I'm trying to add a special ability to a particular row at a particular level that is specified in an ini.
I have no problem getting the code to add the GA_ ability at the designated level, but it is not consistently adding the ability to the specified row. That is, it seems to add the ability to the correct line where the clab goes up to level 50, but adds the ability to the first line (the "ABILITY1" line) when the clab goes up to level 40. I don't quite have my head wrapped around FOR loops, so I am not quite sure what is the issue. Here is the relevant code:
ACTION_PHP_EACH clabz AS der_clab => der_levs BEGIN ACTION_IF (%der_levs% > 0) BEGIN COPY_EXISTING ~%der_clab%.2da~ ~override~ PATCH_IF (FILE_CONTAINS_EVALUATED(~%der_clab%.2da~ ~SCRLCRFT~)) BEGIN COUNT_2DA_COLS cols READ_2DA_ENTRIES_NOW rows cols FOR (row = 0; row < rows; ++row) BEGIN FOR (col = 0; col < cols; ++col) BEGIN READ_2DA_ENTRY_FORMER rows row col ~line~ PATCH_IF (~%line%~ STRING_EQUAL_CASE ~SCRLCRFT~) BEGIN PATCH_PRINT "Row is %row% or %rows%. col is %col%. And line is %line%." SET_2DA_ENTRY_LATER ~s2el_mng~ (%row% +3) (%der_levs% - 1) GA_B_SCRIB // b_scrib SET_2DA_ENTRIES_NOW s2el_mng 1 END //Scroll line END //for END //for END BUT_ONLY END END
What I am doing is beginning the line with "SCRLCRFT" (i.e. where you would normally see "ABILITYx") and my plan is to add to that particular line. As you can see, I am "adding 3" to the row num because that worked when I first tested it (but, again, just with clabs that go up to level 50).
I'm not sure what I'm doing wrong... -
18 hours ago, Endarire said:
@Grammarsalad
Is that an invitation for everyone who hears about this message?Yup
-
If you are interested in playtesting a component for fnp that adds missing priest scrolls to the game, please send me a pm.
Thanks
-
23 hours ago, Graion Dilach said:
because the random item will not be evaulated inside the shop inventory
Oh, that's too bad.
But,
23 hours ago, Graion Dilach said:You can probably make a Pandora's Priest Scroll out from this
lol, one door closes and another opens.
Thanks -
On 8/11/2022 at 12:47 PM, Graion Dilach said:
On EEs, add a new line to rndtres.2da for your intermediary item and add it to the monsters you want it to carry. This allows that item to be randomized to what you want. Also see https://gibberlings3.github.io/iesdp/files/2da/2da_bgee/rndtres.htm. Note that this doesn't work well in shops/bags of holding though. This debuted with IWD(EE).
There's also the other rnd 2DAs, but those are more hardcoded and I wouldn't suggest messing with those ones.
Sorry, so when you say that this doesn't work well in shops, are you saying that I definitely shouldn't use this to randomize items sold in shops, or that there are things i should be careful about? If the latter, could you share?
-
6 hours ago, morpheus562 said:
Thanks for the update! I'm going to include @Grammarsaladsince he is focusing on those ranger updates along with barbarian skills.
Got it.
Edit: i see the issue
ThanksEdit2: @JohnBob it should install now. (Release 0.9.1) let me know if you have any other issues
-
On 8/11/2022 at 11:54 AM, subtledoctor said:
I agree with you in substance, I just don't see why the same result cannot be achieved by simply designating Stinking Cloud and Earthquake as knockdowns
The main issue here that I can think of is undead. Undead don't breathe and shouldn't be affected by stinking cloud. But, corporeal undead at least should be knocked down by an earthquake.
-
3 hours ago, Graion Dilach said:
On EEs, add a new line to rndtres.2da for your intermediary item and add it to the monsters you want it to carry. This allows that item to be randomized to what you want. Also see https://gibberlings3.github.io/iesdp/files/2da/2da_bgee/rndtres.htm. Note that this doesn't work well in shops/bags of holding though. This debuted with IWD(EE).
There's also the other rnd 2DAs, but those are more hardcoded and I wouldn't suggest messing with those ones.
Awesome! Thanks
-
Ok, that's mostly sorted.
This feels like an obnoxious and loaded question, but I don't really know where to start. Can anybody give me an idea of how loot randomization works?
-
It can be something like,
"if it sells potion of healing, then it should sell at least level 1 scrolls. If it sells (idk) a protection scroll against undead, then it should sell 'good' spells." Something like that. -
On 8/2/2022 at 9:48 PM, Endarire said:
High Hedge and Sorcerous Sundries could still sell divine scrolls. Remember that characters would sell things to vendors they didn't already have. Insect swarm isn't specifically Clerical, but is plausibly stocked by temples.
I'm going to be doing something more general (which allows me to capture mod added stores and has a more general application). You will be happy to know that this will be EET compatible right out of the gate.
What I need is suggestions about what other sort of items would be appropriate for what kind of scrolls. So, right now I have a (very general) thing where I would add level 1 scrolls to stores that also sell the potion of healing (the weakest version).
So, that's the question: what specific item should be sold alongside scrolls of a given type?
-
On 7/26/2022 at 10:34 AM, DavidW said:
Here's a function that should work:
DEFINE_PATCH_FUNCTION item_in_store STR_VAR item="" RET value BEGIN value=0 GET_OFFSET_ARRAY itm_arr STO_V10_ITEMS_SOLD PHP_EACH itm_arr AS itm_ind=>itm_off BEGIN PATCH_IF !value BEGIN READ_ASCII itm_off resref value = ("%resref%" STR_EQ "%item%")? 1: 0 END END END
Originally I coded a two-step one that checked for the string first, but that's overkill given how fast it is just to check stores this way.
Awesome! Thanks, Dave
-
Okay, question: how would I check a store for a particular item. This is what I have right now:
//let's create a list of relevant vendors: COPY ~%folder%/lib/lists/store_list.tpa~ ~override~ COPY_EXISTING_REGEXP GLOB ~^.+\.sto$~ ~override~ // Load all stores BEG CAMCODE: READ_BYTE 0x0008 type //Spell type PATCH_IF type = 3 OR 2 BEGIN //temple or inn type READ_BYTE 0x10 "flags" //ELSE 0 PATCH_IF (("%flags%" BAND 0b00100001) = 0b00100001) BEGIN // if cures available and sells stuff; also filters out invalid files INNER_PATCH_SAVE store_name ~%SOURCE_RES%~ BEGIN END INNER_ACTION BEGIN COPY_EXISTING ~store_list.tpa~ ~override~ REPLACE_TEXTUALLY "BEGIN" "BEGIN %store_name% => ~church~" END END PATCH_IF (("%flags%" BAND 0b00100011) = 0b000000011) BEGIN // if buys and sells READ_LONG 0x18 "buy_mark" PATCH_IF buy_mark > 0 BEGIN READ_LONG 0x34 it_off // items Offset READ_LONG 0x38 it_num // Number of items INNER_PATCH_SAVE store_name ~%SOURCE_RES%~ BEGIN END INNER_ACTION BEGIN COPY_EXISTING ~store_list.tpa~ ~override~ REPLACE_TEXTUALLY "BEGIN" "BEGIN %store_name% => ~inn~" END END END END BUT_ONLY
Basically, I'm creating a list to use later. In the second check, I have these two:
QuoteREAD_LONG 0x34 it_off // items Offset
READ_LONG 0x38 it_num // Number of itemsI just have these there because I know they have something to do with the items actually sold by the store. What I would like to do is check each item, and if it, say, has a filename "SCRLPET"*, then I would add the store to a particular list. Etc.
But, I'm not sure how to actually check for that... It feels 'loopy', but not sure how to do the actual check. Any advice?
* the stone to flesh scroll. Etc.
-
Yeah these are good. I should absolutely distinguish "good" from "evil" scrolls as well.
I'm assuming the actual store item changes by chapter?
-
2 hours ago, subtledoctor said:
I would have whatsername, next to the Friendly Arm Inn, sell druid scrolls with a wink and a nod.
Maybe also the Shadow Druids in Cloakwood Forest?
Thanks. That makes sense (I don't quite remember whatshername, but definitely the shadow druids)
-
I could copy over all enemy priests, but I wouldn't want to just add (e.g.) all 1st level priest scrolls to all priests as droppable loot. Is there a way I could randomize something like that by install?
-
Hello party people. I have a functional mod that creates priest scrolls for the game. I'm kinda proud of it; it adds scrolls for mod-added spells, it creates any scrolls not in the game, adds a generic icon for the scroll if none is found in game (it also copies over all existing icons that are only in...BGEE iirc? Maybe it's bg2ee. It's been a while. Anyway, it copies them over if needed and then references them in the scroll file.)
One thing I'm a bit stuck on is scroll placement. Again, I want to do this in a (more or less) dynamic way.I have (and/or am creating) lists that differentiate universal spell scrolls, druid exclusive spell scrolls, and cleric exclusive spell scrolls. Same with scroll levels.
I also have a list of temples that sell items. I was thinking that if game_is BGEE, then temples can sell scrolls levels 1-3 or so. I might go a little more fine grained, and do it by the actual temple. For example, it seems unlikely that the temple of helm would sell druid scrolls (actually, I'm not sure what to do, exactly, with druid scrolls...)
So, long story short, I'm looking for ideas on how best to distribute the scrolls in game. Any ideas?
-
On 6/26/2022 at 2:15 PM, subtledoctor said:
Honestly I think that you should come up with a more concrete idea of what you want to do. Like, if you could sing a bard song from the stealth button then like all bard songs it would have a delayed effect, which you said you want to avoid. If you want a non-shadowdancer to be able to hide in plain sight… honestly you could just let them go invisible, which amounts to the same thing. (Tying the success to your stealth skill would be a bit tedious but totally doable.)
I generally see more specific questions lead to more helpful answers. To answer your most recent specific question, I have no experience messing with buttons. I have seen a spell, made by @Grammarsalad, that summons an invisible creature which can script the caster to hide like a thief. It would be easy enough to put that in an innate ability; so maybe it would be easier to make a bard who can hide, than a thief who can sing. (Always good to step back and look at other route to your goal.)
Oh yeah. It's actually pretty easy to do iirc. I have at least two spells that do think. Hold on.
Here is the script. It could probably be improved but this could get you started:
https://github.com/UnearthedArcana/B_Spells/blob/master/B_Spells/data/new_spells/ranger_1/B_CAMO.baf
-
On 6/26/2022 at 2:15 PM, subtledoctor said:
Honestly I think that you should come up with a more concrete idea of what you want to do. Like, if you could sing a bard song from the stealth button then like all bard songs it would have a delayed effect, which you said you want to avoid. If you want a non-shadowdancer to be able to hide in plain sight… honestly you could just let them go invisible, which amounts to the same thing. (Tying the success to your stealth skill would be a bit tedious but totally doable.)
I generally see more specific questions lead to more helpful answers. To answer your most recent specific question, I have no experience messing with buttons. I have seen a spell, made by @Grammarsalad, that summons an invisible creature which can script the caster to hide like a thief. It would be easy enough to put that in an innate ability; so maybe it would be easier to make a bard who can hide, than a thief who can sing. (Always good to step back and look at other route to your goal.)
Oh yeah. It's actually pretty easy to do iirc. I have at least two spells that do think. Hold on
Unearthed Arcana presents Faiths & Powers: Gods of the Realms
in Miscellaneous Released Mods
Posted · Edited by Grammarsalad
@subtledoctor
Looks like @sturmvogel has found a possible compatibility issue with the latest release of fnp
(Edit: no, I'm not sure why my text is centered)