Skip to content

General mod Questions thread

1606163656670

Comments

  • AquadrizztAquadrizzt Member Posts: 1,065
    edited August 2019
    @argent77, I've been patterning some of the code off of your Afaaq mod. Did you use a spell for fog of war on Afaaq? I could have sworn I got the item idea from your mod, but it might have just been me overthinking in a late night caffeine-fueled haze.

    Also, while I'm here, how would I go about deleting a specific creature from an area? I've forgotten how to work with fj_area_structure and I'm unsure where to look for example usage.
  • argent77argent77 Member Posts: 3,434
    I'm not using the most efficient features for Afaaq, since the mod has to be compatible with the original engine as well. However, I'm using similar techniques for my Golem Construction mod, which is exclusively coded for EE 2.0.

    Recently I faced the same problem for a feature coming up in the next release. I solved it as described in my previous comment. You can look it up in the devel branch of the mod: a7!cmd2.d (see line 35 and 42). The spells to turn sight on and off.

    For removing actors via fj_are_structure function you'll need the actor index within the ARE file. I guess you'd have to write the code for this yourself, unless you know the index beforehand.

    The removal code looks like this:
    LPF fj_are_structure
    INT_VAR
      fj_delete_mode    = 3   // the actor index
    STR_VAR
      fj_structure_type = ~actor~
    END
    
  • CryosaurCryosaur Member Posts: 15
    edited August 2019
    1) Why do mods still use marker files? Do they allow some flexibility or functionality beyond what REQUIRE_COMPONENT and MOD_IS_INSTALLED provide?


    2) For opcode 179 (Damage vs. type bonus), I am curious about the most correct / best way of adding this to a weapon item. I am aware that just the bare opcode has undesirable side effects, so you must wrap it with a 177 (Use EFF File). However, there are two ways to do the wrap and two places to put the effect.

    The base games prefer 177 [type filter] + 12 (Damage), placed as an Ability Effect. Though not actually using the 179 opcode, this style does have the added flexibility of a different damage type than the weapon and the placement seems more intuitive to me.

    Item Revisions seems to prefer 177 [ANYONE] + 179 [type filter], placed as a Global Effect. This style does use the 179 opcode which inherits the weapon's damage type (correct?) and the placement is correct for the 177 + 179 style (the base game does use it once). However, the global placement seems weird for a weapon, like it might have similar side-effects as the bare 179 opcode. Oddly, Item Revisions also does not change all weapons that use the 177 + 20 style over to this different 177 + 179 style that it prefers.

    So. Apart from the damage type flexibility/inheritance and the associated variable EFF file reuse, are either of these opcode 179 implementations "correct" or "better" for weapon items?
  • The user and all related content has been deleted.
  • kjeronkjeron Member Posts: 2,367
    Cryosaur wrote: »
    So. Apart from the damage type flexibility/inheritance and the associated variable EFF file reuse, are either of these opcode 179 implementations "correct" or "better" for weapon items?
    "Better" would depend on the situation, neither is perfect though.
    op179:
    • will affect all attacks, not just the weapon it's on, which would be incorrect when dual-wielding.
    • for two-handed/ranged weapons, it can be ideal if a base weapon damage bonus is desired
    • damage is multiplied by critical hits (and maybe backstabs)
    • multiple op179 effects only allow additional targeting, they do not stack their damage bonus
    op177+12:
    • will only affect attacks made with that weapon ability, so it will not affect dual-wielding
    • allows for different damage bonuses for different weapon abilities of the same item (such as the melee and ranged abilities of a throwing axe)
    • allows for non-physical damage types, as well as physical damage types different from the weapon's base damage
    • not subject to critical hit or backstab multipliers (though can be duplicated as a Critical Hit effect, and to some degree as a Backstab effect)

    Using op177+179 is only necessary in the original games, as they required fields in the EFF file to specify the damage value. The EE's do this with the special field, which is available in spell/item file effects.
  • CryosaurCryosaur Member Posts: 15
    edited August 2019
    kjeron wrote: »
    "Better" would depend on the situation, neither is perfect though.
    So, bare 179 has no unintended side-effects on weapons flagged Two-handed? Hmm.. Now that I search NI again, I do see one (1) item (an SoD bow) in BG:EE+BG2:EE with it's bonus that way, though I do wonder why it is that not more... Anyway, thank you for that list of trade-offs.
    kjeron wrote: »
    Using op177+179 is only necessary in the [non-EE] games...
    Huh. Guess it goes to show that even IR + IRR is... not using the latest tech. Suddenly I feel a great desire to start the IRRR project : Item Revisions Revised Revitalized? :p

    A related question: is there a similar reduced trade-off comparison for opcode 178 (THAC0 vs. type bonus), albeit with only two (178 and 177+178) options? Like, bare 178 works fine for Two-handed and non-weapon items, but 177+178 is recommended for One-handed weapons? Though I did search a bit, I never found any original discussion on why the bare 178 and 179 opcode are not used.
  • switswit Member, Translator (NDA) Posts: 495
    edited August 2019
    regarding "THAC0 vs. type bonus" opcode working globally regardless if it's set via EFF file or directly using Special field. Don't you think we should report descriptions of all one-handed weapons with this opcode as bugs to Beamdog? for example "Flame Tongue +1: The Burning Earth" description:
    STATISTICS:

    THAC0: +1, +2 vs. regenerating creatures, +3 vs. cold-using creatures, +4 vs. undead
    Damage: 1d8+1, +1 fire damage, +2 vs. regenerating creatures, +3 vs. cold-using creatures, +4 vs. undead
    Damage type: Slashing
    Speed Factor: 3
    Proficiency Type: Long Sword
    Type: One-handed
    Requires:
    6 Strength

    Weight: 4

    should be imo changed into this to match what the item actually does (in this case gives global bonuses for both damage and THAC0)
    STATISTICS:

    Equipped abilities:
    – THAC0: +1 vs. regenerating creatures, +2 vs. cold-using creatures, +3 vs. undead
    – Damage: +1 vs. regenerating creatures, +2 vs. cold-using creatures, +3 vs. undead

    THAC0: +1
    Damage: 1d8+1, +1 fire damage
    Damage type: Slashing
    Speed Factor: 3
    Proficiency Type: Long Sword
    Type: One-handed
    Requires:
    6 Strength

    Weight: 4

    When it comes to Damage vs. type bonus opcode the only instance where it makes sense to add it alongside damage line is for 2-handed weapons or if it's applied via melee extended header.

    edit: instead of using "Special" field as a "Value" (what's the point if there is already parameter3 for the same purpose and none of the existing items have been updated to use it like this anyway) it would be better to dedicate it for opcode 301 parameter2 condition ("By this weapon only" / "Always")
    Post edited by swit on
  • kjeronkjeron Member Posts: 2,367
    edited August 2019
    swit wrote: »
    regarding "THAC0 vs. type bonus" opcode working globally regardless if it's set via EFF file or directly using Special field. Don't you think we should report descriptions of all one-handed weapons with this opcode as bugs to Beamdog? for example "Flame Tongue +1: The Burning Earth" description:
    The damage is dealt correctly (through 177/12) in the EE, it's just the THAC0 that is incorrect. At least that is the case for that specific sword (I think most of the IWDEE weapons are not setup correctly for damage though.)
    swit wrote: »
    edit: instead of using "Special" field as a "Value" (what's the point if there is already parameter3 for the same purpose and none of the existing items have been updated to use it like this anyway) it would be better to dedicate it for opcode 301 parameter2 condition ("By this weapon only" / "Always")
    It wouldn't work with it's current functionality: the ("By this weapon only" / "Always") mechanic only functions if the effect is directly on the item, not when it's filtered through op177 in an EFF, which it would have to be to access param3 for the value. Either that would need to be changed, or an alternative would be to have the special field split into two 2-byte sections, two bytes for damage, two bytes for "only/always".
  • Minsc2017Minsc2017 Member Posts: 34
    kjeron wrote: »
    1) What's the flag Keen edge for? - IWD2 only, doubles critical threat range
    2) How can I set/unset the bit related to EE: damage strength bonus using ALTER_ITEM_HEADER? - you can't AFAIK, you'll have to manually loop through them.
    READ_LONG 0x64 ab_off ELSE ~-4~
    READ_SHORT 0x68 ab_num ELSE 0
    FOR (i = 0; i < ab_num; ++i) BEGIN
    READ_BYTE (ab_off + 0x38 * i + 2) location ELSE 0
    PATCH_IF location = 1 BEGIN // is weapon ability
    // sort by item parameters as desired
    READ_BYTE (ab_off + 0x38 * i) header_type
    PATCH_IF header_type = 1 BEGIN // 1=melee, 2=ranged, 3=magical, 4=launcher
    READ_BYTE (ab_off + 0x38 * i + 0x10) launcher
    PATCH_IF launcher = 0 BEGIN // 0=melee/thrown, 1=bow, 2=xbox, 3=sling
    // Either:
    WRITE_BYTE (ab_off + 0x38 * i + 0x26) (THIS BOR BIT2) // set flag
    WRITE_BYTE (ab_off + 0x38 * i + 0x26) (THIS BAND (255 - BIT2)) // unset flag
    END
    END
    END
    END

    Thanks for this snippet.

    Me: "Sh*t, this question is hard to even search for. How about "ALTER_ITEM_HEADER incomplete damage"... well I'll be damned."
  • BubbBubb Member Posts: 1,001
    The IESDP says:
    IESDP wrote:
    Nearest() identifiers cascade outwards, i.e. if there are only three valid creatures, FourthNearest() and above will return the third nearest creature (rather than false).

    From my testing this is not the case - objects that specify a certain position always return an invalid object if there aren't as many valid creatures as what is being searched for.

    Just wanted to verify that this snippet is wrong, or that my understanding of it is wrong.
  • AlonsoAlonso Member Posts: 806
    Can you tell me a bit about opcodes? What are they and how are they used?
  • OlvynChuruOlvynChuru Member Posts: 3,075
    Alonso wrote: »
    Can you tell me a bit about opcodes? What are they and how are they used?

    Items and spells apply opcodes (aka effects) to a creature. These opcodes change the creature in various ways depending on the opcode type (e.g. fire resistance bonus, Strength bonus) and depending on the other numbers in the effect (which could determine how much to change a stat or in what way it should be changed).
  • wukewuke Member Posts: 113
    edited August 2019
    Is it impossible to call PlaySong() in .d files? I wanted to change the music in the middle of a dialogue, so I tried to call DO ~PlaySong(XX)~ in .d file instead of in a script file (tested with original game music number) and it didn't work, although with NearInfinity I can see the PlaySong() in "Action" section of that dialogue entry, does that mean I must call PlaySong() in .baf file?

    edit: alright after testing several more times it seems playsong() can work, but only triggers after dialogue ends...
    Post edited by wuke on
  • RatatoskrRatatoskr Member Posts: 711
    I think I know the answer to this, but just to be sure...

    Is there any easy way to add an interjection to dialogue added to an existing NPC by another mod? Normally that would call for Interject_copy_trans, but the dialogue states vary with different installs, right? So there's no way to be sure what it will be?
  • polymorphedsquirrelpolymorphedsquirrel Member Posts: 114
    Would someone be able to tell me how EET uses NPC portraits? That is, are all NPCs the same, separate for each game, creature files as in stand alone? Or does it somehow unify them to use the same portraits through the whole series, or change the portrait names?
  • sufflaminandussufflaminandus Member Posts: 8
    edited August 2019
    Hey, can anyone please explain how banters between NPCs work.
    1. Is there some internal timer that periodically checks for valid banters between companions or something?
    2. By looking at existent scripts I understood that to make banter between NPCs you need to create regular .d states, like this:
    CHAIN IF ~IsValidForPartyDialog("Jaheira") See("Jaheira") CombatCounter(0) Global("S4RayJaheira","GLOBAL", 0)~ THEN BS4RAY RayJaheira1
    
    but what is the logic behind it? Why such state, for example, does not trigger when I try to talk with NPC?
    3. How to manually trigger banters? Or to debug them, speaking in general. Advancing game time or real time via console does not have an effect.
    Post edited by sufflaminandus on
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    @Bubb , @kjeron

    I have a question about the engine. Let's consider the following script:
    IF
    	Range(NearestEnemyOf(Myself),4)
    	IsWeaponRanged(Myself)
    THEN
    	RESPONSE #100
    		EquipMostDamagingMelee()
    		Continue()
    END
    
    IF
    	!Range(NearestEnemyOf(Myself),4)
    	!IsWeaponRanged(Myself)
    	CanEquipRanged()
    THEN
    	RESPONSE #100
    		EquipRanged()
    		Continue()
    END
    
    IF
    	See(NearestEnemyOf(Myself))
    	False()
    THEN
    	RESPONSE #100
    		NoAction()
    END
    
    IF
    	!StateCheck(LastSeenBy(Myself),STATE_REALLY_DEAD)
    	See(LastSeenBy(Myself))
    THEN
    	RESPONSE #100
    		AttackOneRound(LastSeenBy(Myself))
    END
    

    Assign this script to an NPC that has both a melee and a ranged weapon (e.g., a kobold), and whose allegiance is ENEMY. Spawn that creature using the CLUA console.

    If it doesn't spawn within 4', then it will attack me with its ranged weapon (intended). But as soon as I get within 4', it doesn't switch to its melee weapon and keeps attacking with its ranged weapon. Why!? I don't know how to reliably reproduce this issue but it sometimes happens.

    Moreover, I noticed the following things:
    1. this issue that does not occur with party members (see BDDEFAI.bcs, line 141–163)
    2. this issue does not occur if I remove the action Continue().

    Could you provide additional details about my issue? Thanks in advance!
  • BubbBubb Member Posts: 1,001
    @Luke93: I can't reproduce - the Kobold always catches on after the current one-round attack period is up. How often does this not-switching behavior occur? Game + game version & details about your test creature might help.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited August 2019
    Bubb wrote: »
    @Luke93: I can't reproduce - the Kobold always catches on after the current one-round attack period is up. How often does this not-switching behavior occur? Game + game version & details about your test creature might help.

    Testing environment: BG2EE v2.5.16.6.

    It often occurs for me and I cannot understand why.... Moreover, I also noticed the opposite behavior: if the creature spawns within 4' and I run away, then it will chase me with its melee weapon after the current one-attack round period is up (instead of picking up its ranged weapon and shoot arrows at me).
    Will attach my CRE as soon as possible.....
  • jasteyjastey Member Posts: 2,673
    edited August 2019
    Ratatoskr wrote: »
    I think I know the answer to this, but just to be sure...

    Is there any easy way to add an interjection to dialogue added to an existing NPC by another mod? Normally that would call for Interject_copy_trans, but the dialogue states vary with different installs, right? So there's no way to be sure what it will be?

    @Ratatoskr There is a way to catch a dialogue state number using STATE_WHICH_SAYS.
    This will fail if the referenced line is multiple times inside the dlg.

    Here is an example how I use it to identify a dialogue state in case one of my own mods is already installed and add another transaction:
    You give STATE_WHICH_SAYS the tra line of the mod you want to refer to. In my case it is "BRAGES_SWORD.d" from bgqe. The text line is in ~bgqe/tra/%s/BRAGES_SWORD.tra~. "44" is the text line (@44) inside the tra I am looking for. Inside the game, the line is now in BRAGE.dlg.
    In my example, "brage_state" is the variable name of the state number and can be used as %brage_state% (plus EVALUATE_BUFFER) later just as any OUTER_SET variable.
    If there is no reference or multiple times, the variable will be at -1 or -2 which will fail the install. So you either know that this line is installed and only once inside the dlg (independent on other NPC interjections etc.), or you need to nestle the STATE_WHICH_SAYS so it won't fail the whole install.
    The inlined is just to show you how I use it later.
    /* quest is installed via bgqe */
    
    /* identify the correct dialogue state of "Brage's Sword" */
    OUTER_SET brage_state = STATE_WHICH_SAYS 44 IN ~bgqe/tra/%s/BRAGES_SWORD.tra~ FROM ~BRAGE.dlg~
    
    END
    
    <<<<<<<< ...inlined/brage_bg1_add.d
    
    ADD_TRANS_ACTION BRAGE BEGIN %brage_state% END BEGIN END ~SetGlobal("C#BE_SpawnBrage","GLOBAL",1)~
    
    >>>>>>>>
    COMPILE EVALUATE_BUFFER ~...inlined/brage_bg1_add.d~
    
  • jasteyjastey Member Posts: 2,673
    Would someone be able to tell me how EET uses NPC portraits? That is, are all NPCs the same, separate for each game, creature files as in stand alone? Or does it somehow unify them to use the same portraits through the whole series, or change the portrait names?

    @polymorphedsquirrel EET uses the same, firstly spawned NPCs for the whole saga. I would assume that the portraits will be the same for the whole game and the one the NPC has in BG1 (or at their first appearance). (Calling @swit for assurance.)
  • RatatoskrRatatoskr Member Posts: 711
    @jastey Interesting. It's good to know there is a way to do it. Though I've never used OUTER_SET for anything so I'd have to learn how to code that first. Does that have to go in the setup file or could I code with STATE_WHICH_SAYS in the dialogue file in combination with INTERJECT_COPY_TRANS?
  • jasteyjastey Member Posts: 2,673
    STATE_WHICH_SAYS (and OUTER_SET) go into the tp2.
    After that, the OUTER_SET variables can be used inside .d and baf files if compiled using EVALUATE_BUFFER.
  • switswit Member, Translator (NDA) Posts: 495
    Would someone be able to tell me how EET uses NPC portraits? That is, are all NPCs the same, separate for each game, creature files as in stand alone? Or does it somehow unify them to use the same portraits through the whole series, or change the portrait names?

    portraits are swapped as the game progresses by default (via spell effects, just like it's done for Viconia in vanilla SoD). You can unify them via optional tweak available in EET_Tweaks package.
  • jasteyjastey Member Posts: 2,673
    edited August 2019
    @swit Does this mean the portrait names are different to the EE vanilla games (or are the portrait names between games different anyhow)?
  • switswit Member, Translator (NDA) Posts: 495
    edited August 2019
    jastey wrote: »
    @swit Does this mean the portrait names are different to the EE vanilla games (or are the portrait names between games different anyhow)?

    the portrait names are exactly the same as in vanilla games. There is no name conflict between those BMP file names.
  • DrazharDrazhar Member Posts: 7
    Hey all I’ve been messing around with EE keeper and effects.. and I’m wanting to add a vorpal effect like what’s on the silver sword. Would this be possible? Also not sure if this is the correct place to ask!
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited August 2019
    WeiDU noob question (sigh :( )

    How can I assign the result of a function to a unique variable if my function runs on different elements of an array?
    ACTION_DEFINE_ASSOCIATIVE_ARRAY	identifier	BEGIN
    	elem1	=> 1
    	elem2	=> 1
    	// and so forth....
    END
    
    ACTION_PHP_EACH	identifier AS something => ind	BEGIN
    	ACTION_IF	(ind == 1)	BEGIN
    		LAF	MY_FUNCTION
    		STR_VAR
    			resource = EVAL ~%something%~
    		RET
    			result	// This is supposed to be a string....
    		END
    	END
    END
    
    OUTER_TEXT_SPRINT	myvar	"%result%"
    
    // Fact is that "%myvar%" contains the last element. What about the other elements? How can I retrieve them?
    // To sum up: I'd like myvar1 = result (input: something(1)) after the first iteration, myvar2 = result (input: something(2)) after the second iteration and so forth.....
    
    Post edited by _Luke_ on
  • kjeronkjeron Member Posts: 2,367
    // To sum up: I'd like myvar1 = result (input: something(1)) after the first iteration, myvar2 = result (input: something(2)) after the second iteration and so forth.....
    	OUTER_SET	idx = 1
    	ACTION_PHP_EACH	identifier AS something => ind	BEGIN
    		ACTION_IF	(ind = 1)	BEGIN
    			LAF	MY_FUNCTION
    			STR_VAR
    				resource = EVAL EVAL ~%%something%%~
    			RET
    				$myvar(~%idx%~) = result
    			END
    		END
    		OUTER_SET	idx += 1
    	END
    
    This won't set myvar_# if that iteration wasn't (ind = 1), resulting in skipped myvar_# indexes, such that this:
    ACTION_DEFINE_ASSOCIATIVE_ARRAY	identifier	BEGIN
    	elem1	=> 1
    	elem2	=> 1
    	elem3	=> 0
    	elem4	=> 1
    END
    
    Would produce:
    myvar_1 = EVAL ~%elem1%~
    myvar_2 = EVAL ~%elem2%~
    myvar_4 = EVAL ~%elem4%~
    
    You can move "OUTER_SET idx += 1" up one line, and it will not skip indexes when assigning myvar#, which would instead produce:
    myvar_1 = EVAL ~%elem1%~
    myvar_2 = EVAL ~%elem2%~
    myvar_3 = EVAL ~%elem4%~
    
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited August 2019
    @kjeron

    Thanks.

    Let's complicate things: suppose elem1, elem2, elem3 are strings from SPELL.ids (e.g., CLERIC_BLESS, etc...)
    ACTION_DEFINE_ASSOCIATIVE_ARRAY	identifier	BEGIN
    	CLERIC_BLESS	=> 1
    	CLERIC_COMMAND	=> 1
    	// and so forth....
    END
    
    ACTION_PHP_EACH	identifier AS name => ind	BEGIN
    	ACTION_IF	(ind == 1)	BEGIN
    		LAF	RES_NUM_OF_SPELL_NAME
    		STR_VAR
    			spell_name = EVAL ~%name%~
    		RET
    			spell_res
    		END
    	END
    END
    
    // I'd like to have variable cleric_bless = spell_res (input: CLERIC_BLESS), cleric_command = spell_res (input: CLERIC_COMMAND) and so forth.... How can I do that?
    

    Well, I could access them as I need them, but it does sound quite time consuming:
    OUTER_TEXT_SPRINT	cleric_bless	"%myvar_1%"
    OUTER_TEXT_SPRINT	cleric_command	"%myvar_2%"
    // and so forth...
    
    Post edited by _Luke_ on
Sign In or Register to comment.