Jump to content

Allbrother

Members
  • Posts

    52
  • Joined

Posts posted by Allbrother

  1. Sorry for butting in, but I got curious and took a look at that spell - it changes the target's script to kick it out of the party (if it's in it) and then to DestroySelf() and give some approximation of its xp value. Not sure if that's recoverable, but if instead it Deactivate()ed (would it still process scripts?) it and left a block to Activate() and assign join dialog when global is flipped and a freedom spell to flip that global, maybe that could work? Just spitballing here...

  2. This is great, thank you. I understand now why my initial attempt didn't work and how I accidentally fixed it.

    Yes, I used FIND_FREE_ANIM (along with TO_HEX_NUMBER) after I found it digging through another mod's cellar, but didn't execute it properly for my use case.

     

    One thing specifically that's still unclear to me - under most animation types, there's animation scheme that defines which suffix covers which sequences. But in it, each sequence code is followed by "=*number range*. For example type 2000 has this:

    Spoiler
    Animation scheme: [resref][wovl]?[seq].BAM, with
    seq:
    - G1: WK=0-4, SC=8-12, SD=16-20, GH=24-28, DE=32-36, TW=40-44
    - G1E: WK=5-7, SC=13-15, SD=21-23, GH=29-31, DE=37-39, TW=45-47
    - G2: A1=0-4, A2/CA=8-12, A3/SP=16-20
    - G2E: A1=5-7, A2/CA=13-15, A3/SP=21-23
    

     

    What are those number ranges? My initial assumption was orientation, but that's noted separately and the numbers for it don't reach as high

  3. Okay, I worked out how to add the new line to animate.ids and name the ini correctly and now my animation is available for selection. However, ingame it's showing a completely different asset than the one I provided.

    The ini I copied had a 4 letter resref that pointed to two 40 frame bams with g1 and g2 suffixes so I set up mine the same way. I didn't change anything else in the INI. I don't get why it isn't working. I also tried just using a single bam with the exact same name as the resref in the ini, but that didn't help either.

  4. Hi.

     

    Long story short, there was no available animation for a creature I need, so I prepared a bam file for the job, I found a default animation to copy the ini from and now I don't know what's the next step? The ini's resref leads to 2 as best as I can tell identical bams (g1 and g2), so I assume I'd have to give my bam the same treatment and I know my new ini has to be named as the first column of the new entry in animate.ids, but how do I do that?

     

    edit:

    Somehow I stumbled my way into getting it to work but... no idea how or why. So if anyone has any documentation or knowledge on the inis and bam setup and naming conventions for the creature animation, I'd appreciate it

  5. And I'm failing. And I don't know why. I've looked all over the script and it all feels like it should be working.

    So what I've done is appended the blob below to the area scripts. It's supposed to run once, roll 1d3 essentially and on 1 spawn level appropriate quest targets and on 2/3 spawn nothing and instead increment a global that when maxed (by running in other target areas) will spawn the targets regardless of the random roll.

    But it's spawning the quest targets in the first area visited 100% of the time for some reason. What am I doing wrong?

     

    Spoiler
    IF
    	LevelLT(Player1,4) //if lvl <4
    	Global("wl_oublek_gnolls","GLOBAL",1) //and quest is active and hasn't spawned yet
    	!Global("wl_oublek_gnolls_rolled","LOCALS",1) //and hasn't rolled in this area
    	OR(2) //and either...
    		RandomNum(3,1) //rolls 1 on 1d3
    		Global("wl_oublek_gnolls_spawned","GLOBAL",3) //or max attempts/spawned
    THEN
    	RESPONSE #100
    		CreateCreature("wl-t1g",[4500.3000],S)
    		CreateCreature("wl-t1g",[4500.3000],S)
    		CreateCreature("wl-t1g",[4500.3000],S)
    		CreateCreature("wl-t1g",[4500.3000],S)
    		CreateCreature("wl-t1g",[4500.3000],S)
    		CreateCreature("wl-t1g",[4500.3000],S)
    		CreateCreature("wl-t1g",[4500.3000],S)
    		CreateCreature("wl-t1g",[4500.3000],S)
    		CreateCreature("wl-t1g",[4500.3000],S)
    		CreateCreature("wl-t2g",[4500.3000],S)
    		SetGlobal("wl_oublek_gnolls","GLOBAL",2) //advance the quest to spawned
    		SetGlobal("wl_oublek_gnolls_spawned","GLOBAL",3) //set to max attempts/spawned
    		SetGlobal("wl_oublek_gnolls_rolled","LOCALS",1) //set to rolled in this area
    END
    
    IF
    	LevelGT(Player1,3) //if lvl >3
    	LevelLT(Player1,7) //and lvl <7
    	Global("wl_oublek_gnolls","GLOBAL",1) //and quest is active and hasn't spawned yet
    	!Global("wl_oublek_gnolls_rolled","LOCALS",1) //and hasn't rolled in this area
    	OR(2) //and either...
    		RandomNum(3,1) //rolls 1 on 1d3
    		Global("wl_oublek_gnolls_spawned","GLOBAL",3) //or max attempts/spawned
    THEN
    	RESPONSE #100
    		CreateCreature("wl-t2g",[4500.3000],S)
    		CreateCreature("wl-t2g",[4500.3000],S)
    		CreateCreature("wl-t2g",[4500.3000],S)
    		CreateCreature("wl-t2g",[4500.3000],S)
    		CreateCreature("wl-t2g",[4500.3000],S)
    		CreateCreature("wl-t2g",[4500.3000],S)
    		CreateCreature("wl-t2g",[4500.3000],S)
    		CreateCreature("wl-t2g",[4500.3000],S)
    		CreateCreature("wl-t2g",[4500.3000],S)
    		CreateCreature("wl-t3g",[4500.3000],S)
    		SetGlobal("wl_oublek_gnolls","GLOBAL",2) //advance the quest to spawned
    		SetGlobal("wl_oublek_gnolls_spawned","GLOBAL",3) //set to max attempts/spawned
    		SetGlobal("wl_oublek_gnolls_rolled","LOCALS",1) //set to rolled in this area
    END
    
    IF
    	LevelGT(Player1,7) //if lvl >7
    	Global("wl_oublek_gnolls","GLOBAL",1) //and quest is active and hasn't spawned yet
    	!Global("wl_oublek_gnolls_rolled","LOCALS",1) //and hasn't rolled in this area
    	OR(2) //and either...
    		RandomNum(3,1) //rolls 1 on 1d3
    		Global("wl_oublek_gnolls_spawned","GLOBAL",3) //or max attempts/spawned
    THEN
    	RESPONSE #100
    		CreateCreature("wl-t3g",[4500.3000],S)
    		CreateCreature("wl-t3g",[4500.3000],S)
    		CreateCreature("wl-t3g",[4500.3000],S)
    		CreateCreature("wl-t3g",[4500.3000],S)
    		CreateCreature("wl-t3g",[4500.3000],S)
    		CreateCreature("wl-t3g",[4500.3000],S)
    		CreateCreature("wl-t3g",[4500.3000],S)
    		CreateCreature("wl-t3g",[4500.3000],S)
    		CreateCreature("wl-t3g",[4500.3000],S)
    		CreateCreature("wl-t4g",[4500.3000],S)
    		SetGlobal("wl_oublek_gnolls","GLOBAL",2) //advance the quest to spawned
    		SetGlobal("wl_oublek_gnolls_spawned","GLOBAL",3) //set to max attempts/spawned
    		SetGlobal("wl_oublek_gnolls_rolled","LOCALS",1) //set to rolled in this area
    END
    
    IF
    	!Global("wl_oublek_gnolls_spawned","GLOBAL",3) //if not at max attempts/spawned
    	!Global("wl_oublek_gnolls_incr","LOCALS",1) //and hasn't incremented attempts in this area
    THEN
    	RESPONSE #100
    		IncrementGlobal("wl_oublek_gnolls_spawned","GLOBAL",1) //increment attemps
    		SetGlobal("wl_oublek_gnolls_rolled","LOCALS",1) //set to rolled in this area
    		SetGlobal("wl_oublek_gnolls_incr","LOCALS",1) //set to incremented attempts in this area
    END
    
    IF
    	Global("wl_oublek_gnolls_count","GLOBAL",10) //if all are dead
    	Global("wl_oublek_gnolls","GLOBAL",2) //and quest hasn't advanced
    THEN
    	RESPONSE #100
    		AddJournalEntry(@3,QUEST) //update journal
    		SetGlobal("wl_oublek_gnolls","GLOBAL",3) //advance quest
    END

     

     

  6. 2 hours ago, subtledoctor said:

    You can use RESOLVE_STR_REF to put the strref of your string into a variable, and then put the variable into the APPEND/I_2_R.

    Thank you. Took some time (and a look at the linked code) to figure out how to properly use it, so to save the effort for anyone dumb like me finding this in the future (or more likely myself in the future once I've forgotten and am referring back to this), this is what worked for me:

     

    ACTION_IF FILE_EXISTS_IN_GAME ~statdesc.2da~ BEGIN
    	OUTER_SPRINT variable1 ~string~
    	OUTER_SET variable2 = RESOLVE_STR_REF (~%variable1%~)
    	COPY_EXISTING ~statdesc.2da~ ~override~
    		COUNT_2DA_ROWS 3 variable3
    			APPEND ~statdesc.2da~ ~%variable3%	%variable2%	bamfile~
    END

     

    2 hours ago, subtledoctor said:

    Then, iterate over rows in the 2da file snd use READ_2DA_ENTRY to compare entries to a value you added, and extract the row number for use in the spell. See here how I do something similar with splprot.2da (that kit_is_row variable I created gets used later in parameter2 of an op318 effect).

    Turns out I had already stored it in variable3, just putting it in parameter2 of the add_spell_effect function did the job

  7. Hi. I got a couple of questions about adding a spell and having it display a custom portrait icon while it's in effect

     

    First, (i think) I know that to add custom portrait icons, I need to add a line in statdesc.2da. The way I found to do it (via insert_2da_row) doesn't allow me to use custom strings (it just adds what I put in verbatim rather than the reference) so my first question is, what's the proper way of doing this?

     

    My second question is, once I have my custom icon with correct string in place, how do I make my spell consistently use it regardless of whether there's been other modifications to statdesc.2da or not? My assumption here is that if I add the line to statdesc and it comes in at row 207, I can have my spell use opcode 142 with value 207 and it'll work for me, but if it's then installed on a game that  already has extra lines in statdesc.2da, then my spell would be pointing to a wrong icon. Is that correct and if so, how do I get around that?

  8. 20 minutes ago, subtledoctor said:

    READ_BYTE reads 8 bits. I don't think there's any facility to read fewer than 8 bits.

    EDIT - Ah I see, you are looking at the "flags" field. If you look at it in Near Infinity (make sure you enable the "Show Hex Offsets" option!) you can see that this field is 4 bytes - it is at byte 0x18 and the next one is at byte 0x1c.

    Sorry, mixed up my words, meant bytes. 

     

    20 minutes ago, subtledoctor said:

    Looking at the bottom of the NI window, it is easy to see what is where: the four columns in this field represent, starting from the left, byte 0x18, byte 0x19, byte 0x1a, and byte 0x1b. (And then the next field begins at 0x1c.)

    I did not realize that at all lol. I switched the field to edit as binary, noted the 4 number strings, switched it back, made a change and checked the binaries again to compare what changed. Knowing how the columns work is much more convenient. Also, I have the offsets, but until just know I didn't understand how exactly they incremented, now I do it'll be very helpful.

     

    Thank you very much for the schooling

  9. 32 minutes ago, subtledoctor said:

    That reads the bit values for that byte, which will be a string of eight 1s and 0s. I know from looking in NI that the two-handed flag is in that seventh bit. I tell it to set each bit to a value of 1 if it was already 1 (as recorded in the %handed% variable) and it is also 1 in my new chosen values (the part after BAND). A crossbow probably already has a value of 1 in that seventh bit - the two handed flag is "checked" - but my new chosen value is 0. Since both are not 1, it gets written as 0 and therefore the two-handed flag becomes "unchecked."

    Thank you. Since the field is 4 bits, if I needed to edit a flag that appears in a later bit, how would that be formatted? For example if I wanted to add silver property (which if I've got this right is the last number in the second bit), what would I put after the BAND? Would it be 1b followed by eight 1s? 

  10. Hi. I'm trying to wrap my head around some of the code used here and I wanted to ask a couple of questions if that's ok.

     

    Specifically about this bit in component 102:

     

    	PATCH_IF (%type% = 27) BEGIN // crossbows
    	  READ_LONG 0x08 gen_name_strref
    	  PATCH_IF (GAME_IS ~bgee bg2ee iwdee eet~) BEGIN
    	    PATCH_IF (gen_name_strref = %light_xbow_strref%) BEGIN
    		  READ_BYTE 0x18 handed
    		  WRITE_BYTE 0x18 (~%handed%~ BAND ~0b11111101~)
    		  FOR (index = 0x54 ; index >= 0x50 ; index -= 4) BEGIN // loop through descriptions
    		    READ_LONG "%index%" "valid"
    		    PATCH_IF ("%valid%" < 2147483646) AND ("%valid%" >= 0) BEGIN // verify description is valid
    			  READ_STRREF "%index%" "description"
    			  INNER_PATCH_SAVE new_desc ~%description%~ BEGIN
    			    REPLACE_TEXTUALLY EXACT_MATCH ~Type: Two-handed~ ~~
    			  END
    			  SAY_EVALUATED "%index%" ~%new_desc%~
    		    END
    		  END
    	    END
    	  END

     

    1.Does the hex code added to handed equal "no tick on two-handed"? And if so, where/how do you get the hex values for the different flags?

     

    2.When verifying description is valid, are the numbers valid is being compared to string references? And if so, what's the significance of 2147483646? Is it just an arbitrary large number or is there a reason to use that specific number?

  11. 35 minutes ago, Dan_P said:

    I just tried this quickly with a copy of barbarian rage, and it seems to work? I added the op232 to recast, and an op321 to remove effects (but not op206 because it wasn't needed). I'm not getting duplicate messages on EE v2.6. You can try this file. If you're getting multiple castings or messages, it might be a pre-v2.6 issue.

    TestRage.zip 756 B · 1 download

     

    Must be a 2.5 thing then, because I got hit with "You cannot cast multiple instances of the same contingency spell on yourself." when I tried that. I even tried straight up plugging your working file in my 2da in case I fucked it up somehow, but same thing. Damn... I guess I'll have to live with the cluttered log.

     

    Thanks for the help

×
×
  • Create New...