Skip to content

[MOD] EEex (v0.10.2-alpha)

1222325272848

Comments

  • OlvynChuruOlvynChuru Member Posts: 3,079
    Bubb wrote: »
    Here's a quick design decision: Should the EEex_MatchObject() trigger fail if it doesn't find an object? This functionality can easily be reproduced by adding an Exists(EEex_MatchObject) after said trigger.

    I guess the real question is, would there be any reason for a script block to continue if an object match fails?

    It should probably fail if it doesn't find an object. Having to include an Exists() line with it every time would at best cause more wordiness and at worst cause bugs if the modder forgets to put in the Exists() line.
  • CrevsDaakCrevsDaak Member Posts: 7,155
    Bubb wrote: »
    I guess the real question is, would there be any reason for a script block to continue if an object match fails?
    I suppose that if you wanted to match several different objects, all at once (say, to make a script for an NPC to use the BG2 Wand of Lighting), it'd be useful if you could, in some way, prevent it from blocking the script block because it did not find one of the six targets it was looking for. Given that this is not the conventional usage, it's likely that what @OlvynChuru suggested is a better idea, and I think you can achieve what I'm saying by doing:
    OR(2)
        EEex_MatchObject()
        True()
    
    Which is good enough for such an uncommon use, and if there are any others, it probably covers them as well (unless you need it in another OR() block, although I think they nest alright. Haven't messed around with scripts in a while).
  • switswit Member, Translator (NDA) Posts: 495
    Awesome progress. Glad to see Volatile fields in. As for the question, failing trigger if object is not found sounds right.
  • OlvynChuruOlvynChuru Member Posts: 3,079
    @Bubb Great work!

    A little request: could you make it so one of the flags in a SPL file changes which name is displayed when the spell is cast? If the flag is set, casting the spell should display the identified name (NAME2) of the spell rather than its general name (NAME1).

    One thing we could do with this is prevent a spell from displaying its name when cast (by setting the flag and having the identified name strref be -1), while still showing its name in the tooltip and the spell description.
  • BubbBubb Member Posts: 1,005
    edited August 2019
    @OlvynChuru: Well, that was tricky!

    BIT31 of a SPL's "Flags" field will now force the engine to display the spell's Identified name in the combat log when cast. Also, the engine didn't skip log output for empty / invalid strings like you wanted, so I patched that in for STRREF_FEEDBACK_CASTING and STRREF_FEEDBACK_CASTS.

    (I don't think BIT31 is being used for anything at the moment, but if it is I can change the check bit)

    By the way, do you know if the "Identified name" (offset 0xC) field is used in the EE engine? I couldn't find any obvious references to it in the assembly.
  • UlbUlb Member Posts: 295
    @Bubb
    Is there a way to assign the 'Shaman Dance' button via opcode404?
    The documentation doesn't list it and none of the not listed numbers I've tried worked out either.
    Am I right to assume that the 'Shaman Dance' is a special case and handled differently than the other buttons?

    On a somewhat related note: I've noticed that button #9 is the (defunct) shapeshift ability. Would it be possible to assign a spell to that ability? That way custom buttons could be created by replacing the bam/stringref. (Would obviously only allow for one custom button, but still, if it could be done with relative easy, that would be useful to have..)
  • BubbBubb Member Posts: 1,005
    edited August 2019
    @Ulb: Shaman Dance is a special-cased Bard Song (2). The engine treats Bard Song as Shaman Dance when the character's class = 21. As such, it cannot be granted to non-shaman characters without additional hackery.

    On the second note, I'd have to look into the exact actionbar mechanisms further. Actionbar functions are extremely complicated, so it's quite hard to decipher the actual functionality in a lot of cases. I'll take a stab at it of course - but with the semester starting back up it'll probably take me a while to get anything done.
  • UlbUlb Member Posts: 295
    Bubb wrote: »
    @Ulb: Shaman Dance is a special-cased Bard Song (2). The engine treats Bard Song as Shaman Dance when the character's class = 21. As such, it cannot be granted to non-shaman characters without additional hackery.

    Thank you, I suspected something like that would be the case.
    I'll take a stab at it of course - but with the semester starting back up it'll probably take me a while to get anything done.
    Don't stress yourself, at least not on my account. While your work is fantastic and very much appreciated, all I'm using it for is stupid kit mods no one needs.. and if I can't do one idea I'll just do something else. :D
  • OlvynChuruOlvynChuru Member Posts: 3,079
    @Bubb For a while, I've been experiencing crashes that happen when I click on a party member's portrait. It seems to happen at random when I load a game: sometimes when I load a game, the first time I click on a character's portrait causes a crash, but if it doesn't, I can play for an hour or two without it crashing from clicking on a portrait.

    This likely isn't a problem with EEex by itself, but rather with some of the things I've added using EEex. In my game, there are two Screen Effects opcodes attached to every creature in every area (in addition to the party members), and the protagonist has a permanent Invoke Lua effect which runs some code whenever the game is loaded but doesn't do anything otherwise.

    Specifically, that permanent Invoke Lua effect calls this function:
    function MEONCREA(effectData, creatureData)
    	local sourceID = EEex_ReadDword(effectData + 0x10C)
    	if (sourceID == 0 or sourceID == -1) then
    		local targetID = EEex_ReadDword(creatureData + 0x34)
    		me_ghost_walk_positions = {}
    		me_ghost_walk_actors = {}
    		EEex_AlterActorEffect(targetID,{{"opcode",402},{"resource","MEONCREA"}}, {{"source_id",targetID}},1)
    	end
    end
    

    I suspect that the crashes are happening because of one of these things. However, I'm not sure why clicking on a party member's portrait would cause a crash. Could you look at the code that's run when a portrait is clicked and see what might be the problem?
  • GrammarsaladGrammarsalad Member Posts: 2,582
    Hey @Bubb and @OlvynChuru

    Okay, I know it hasn't been officially released yet, and so there may be a missing component that is required to finalize the component, but I just had to try custom skills. As you may have guessed, I wasn't quite able to get it to work completely.

    The only thing I did was uncomment the example lore skill before installing EEex in ExtendedSkills.tpa:
    LAF ADD_EXTENDED_SKILL
    INT_VAR
    	stat = 25 //Lore
    	name = RESOLVE_STR_REF(~Lore~)
    	description = RESOLVE_STR_REF(~LORE: The character's lore determines <PRO_HISHER> ability to identify the properties of magic items.~)
    	opcode = 21 //Modify Lore
    	visibility = 4 //Will not appear in character record screen (Lore's already there)
    STR_VAR
    	class_include = ~{4, 9, 10, 13, 15}~ //Usable by thief, fighter/thief, fighter/mage/thief, mage/thief, and cleric/thief
    	kit_include = ~{0x4008}~ //Usable by stalker as well
    	kit_exclude = ~{0x400C, 0x4021}~ //Not usable by swashbuckler or shadowdancer
    	stat_exclude = ~{{38, 16, 2}, {39, 14, 2}}~ //Not usable if your Intelligence is less than 16 or your Wisdom is less than 14
    END
    

    I tested it in my GOG version of BG2EE, version 2.5.16.6 with no other mods installed.

    It partially worked. I created an assassin (with the required attributes) and I was able to put points into 'Lore':
    sko2vtm0ugx2.png

    Now, this might be because 'visibility' is set to 4, but the new value didn't show up in the main character creation screen:
    aybn8p3qxzfa.png

    and the adjusted value did not show up on the character sheet once the game started (it should be 99 or thereabouts):
    dqr3fc7y2q9z.png


  • kjeronkjeron Member Posts: 2,368
    @Grammarsalad Lore might be the worst possible stat to attempt this with.
    It's base value determined from LORE.2da and LOREBON.2da is either recalculated constantly or cannot be overwritten.
  • OlvynChuruOlvynChuru Member Posts: 3,079
    @Grammarsalad I was actually aware of those problems but I haven't gotten around to fixing them yet. I'll see if I can fix them today or tomorrow.

    @kjeron That's actually not the issue (though it might be an issue). The issue is that I designed the custom skills feature in BG1:EE and some of the UI modifications currently don't work in BG2:EE. In BG1:EE I've tested putting points in Lore and it worked.

    236gc5daajyf.png
    axlxe8zre7ga.png
  • BubbBubb Member Posts: 1,005
    @OlvynChuru: Regarding the crashes -

    A ton of things happen when a portrait is clicked; it would be infeasible to guess what exactly is causing the issue. Could you please upload the crash dmp(s)? Also, any way to reproduce on my end would help tremendously.
  • BubbBubb Member Posts: 1,005
    edited August 2019
    @OlvynChuru: Thanks, merged! Indeed - if creatures are deleted, like what DestroySelf() does, they are no longer accessible and EEex_GetActorShare() will return 0x0.

    I noticed that you added additional checks for death states. That's good, and is probably the desired result most of the time, though I just wanted to note that sprites still exist and can be accessed even though they are dead.
  • GrammarsaladGrammarsalad Member Posts: 2,582
    OlvynChuru wrote: »
    ...

    (Yesterday I made custom skills work in BG2EE as well but I didn't mention it here; @Bubb already merged this into EEex).

    Yup. And boy is it cool
  • GrammarsaladGrammarsalad Member Posts: 2,582
    edited August 2019
    Okay, so I'm playing around with the new skill implementation. Oh man, I'm loving it! Okay, so I have a request to make it just a *bit* better: Could we get an opcode or 2da that allowed us to use spls as pseudo-thief skills for our new skills?

    Okay, what do I mean? I see that effect 252 is hard coded to be tied to stat 28, such that, stat 28 determines, in some sense, the chance that a given 252 effect will properly trigger (and/or how likely a 'mishap' is to trigger). Could we get an opcode or 2da that allows us to couple particular spls with newly added stats? So, maybe a 2da that looks something like:
    This file defines added skills

    The first column is filled by the Stat that is associated with the spl, Opcode and/or modal. The value of this stat (of the targeted creature) determine's the % chance (maximum 99%) that the spl or opcode executes when activated.

    The second column is filled by the model that is associated with the skill (ids match what is defined by EEex_ACTIONBAR_TYPE in M__EEex.lua). When the modal is activated, the creature will be targeted by the associated spl (again, with a % chance equal to stat). If the value is ****, then the spl/stat is not associated with any modal.

    The third column is filled by the ResRef of the spl associated with the Stat. This spl will fail if the targeted creature(s) does not have sufficient points in the relevant stat.

    The fourth column is fill by the Opcode that is associated with the stat. Any spl with this opcode will fail if the targeted creature does not have sufficient points in the relevant stat (BE CAREFUL WITH THIS ONE!)

    The fifth column is filled by the ResRef of the spl that fires at the target if the character rolls a 'mishap' (determined with the same probability as the set snares spl). If the value is ****, then there is no mishap associated with this stat.
    2DA V1.0
    ****
    
    STAT 		MODAL 		SPL 		OPCODE 		MISHAP
    TRAP1 		****		spcl412		252		BAM1
    TRAP2		****		spcl414		252		BAM2
    USE_POISON	****		spcl422		252		SPPR411
    U_EVIL!		FIND_TRAPS	spcl212    	****		****
    
    
    The above entries might act as examples. The first two are the normal set trap spl and the special bounty hunter set traps respectively. The third is a hypothetical 'use poison' skill that has a chance of poisoning the character on a mishap, and the fourth uses the Find Traps modal to implement the Paladin's Detect evil ability as a skill using the Find Traps modal.

    Edit: or what if Opcode #401 could be used to associate a stat with a spl in this way at least for a given creature, perhaps with an applied 401 with the relevant spl in the resource.

    Whatever is easiest
  • kjeronkjeron Member Posts: 2,368
    @Grammarsalad
    What about just altering op252 so it's parameters can be used to specify which stat it checks, and whether or not to apply the "Set Trap" restrictions (hostile in sight, trap limit). The critical failure spell is just "%resource%F".
  • GrammarsaladGrammarsalad Member Posts: 2,582
    edited August 2019
    kjeron wrote: »
    @Grammarsalad
    What about just altering op252 so it's parameters can be used to specify which stat it checks, and whether or not to apply the "Set Trap" restrictions (hostile in sight, trap limit). The critical failure spell is just "%resource%F".

    I like that. So, resource would set the spl effect So, for example, if the resource was "spcl422" the the relevant stat would apply to the poison weapon ability to the creature?

    Also, maybe special field could be used associate the stat with a modal?

    Edit: Er, my sense is that that probably wouldn't work (maybe as an AP_ application in the clab? No idea

    Anyway, *merely* an alteration to 252 as described would be Amazeballs
  • BubbBubb Member Posts: 1,005
    Would an externalized Invoke Lua implementation be fine? It's a little awkward to set up spell-wise, (there ends up being 3 levels of indirection :|):
    1. Spell does Opcode #177 (Use EFF File).
    2. EFF calls Invoke Lua with an EEex-provided function, (or your own if you want to supplant the default behavior).
    3. Resource2 would hold the actual spell file to fire - other arguments could be passed via remaining EFF v2.0 params.

    It's possible to make a dedicated opcode that does all of this, but it seems a bit silly to hardcode the probability portion, which I'm just going to write in Lua anyway. Also, if I implement it as the above, the only new additions to EEex would be a few additional internal-function externalizations.

    And, as a side note, Opcode #252 has some funky hardcodedness going on - it's easier to reimplement its functionality than to try to adapt it.
  • GrammarsaladGrammarsalad Member Posts: 2,582
    Bubb wrote: »
    Would an externalized Invoke Lua implementation be fine? It's a little awkward to set up spell-wise, (there ends up being 3 levels of indirection :|):
    1. Spell does Opcode #177 (Use EFF File).
    2. EFF calls Invoke Lua with an EEex-provided function, (or your own if you want to supplant the default behavior).
    3. Resource2 would hold the actual spell file to fire - other arguments could be passed via remaining EFF v2.0 params.

    It's possible to make a dedicated opcode that does all of this, but it seems a bit silly to hardcode the probability portion, which I'm just going to write in Lua anyway. Also, if I implement it as the above, the only new additions to EEex would be a few additional internal-function externalizations.

    And, as a side note, Opcode #252 has some funky hardcodedness going on - it's easier to reimplement its functionality than to try to adapt it.

    You're the expert. If that's is easier for you, I'm happy with it (heh, though an example would be really helpful-- I'm still intimidated by lua, and so I'm not envisioning how exactly this would work. One example would be all I need)
  • OlvynChuruOlvynChuru Member Posts: 3,079
    @Bubb I have another request. I was wondering if it was possible to change the calculation of distance between a creature and that creature's target to take into account differences in z position between them.

    A while ago, you said the pseudocode for spell range was something like this:
    a = (sprite x / 16) - (target x / 16)
    b = (sprite y / 12) - (target y / 12)
    c = spell range + 2
    
    Spell Range Satisfied: a^2 + b^2 <= c^2
    

    Could you turn it into something like this?
    a = (sprite x / 16) - (target x / 16)
    b = (sprite y / 12) - (target y / 12)
    d = (sprite z / 16) - (target z / 16)
    c = spell range + 2
    
    Spell Range Satisfied: a^2 + b^2 + d^2 <= c^2
    

    This would also have to be done for attack range.

    Since creatures don't normally differ in z position, this shouldn't affect the game except when mods include ways of changing a creature's height.
  • CrevsDaakCrevsDaak Member Posts: 7,155
    OlvynChuru wrote: »
    Since creatures don't normally differ in z position, this shouldn't affect the game except when mods include ways of changing a creature's height.
    Isn't the z-position used for visual effects (just a small offset for where the feet circle will be drawn) in-game? I was rather certain the height search map affected creatures' z-position.
  • OlvynChuruOlvynChuru Member Posts: 3,079
    CrevsDaak wrote: »
    OlvynChuru wrote: »
    Since creatures don't normally differ in z position, this shouldn't affect the game except when mods include ways of changing a creature's height.
    Isn't the z-position used for visual effects (just a small offset for where the feet circle will be drawn) in-game? I was rather certain the height search map affected creatures' z-position.

    I just did some testing, and it seems like the height map doesn't actually change the z position value in the actor data. It's always 0 regardless of the height map.

    zpq2fqnbledh.png

    as9v5ts75zjy.png
  • BubbBubb Member Posts: 1,005
    @OlvynChuru: The z-pos and the height map work independently - though they are both taken into consideration when rendering the sprite, as you can see.

    Unfortunately, it appears the compiler has inlined the distance code over hundreds of calls. I can attempt to change just the attack + casting code, but the pathfinding system and other internal targeting mechanisms would probably get confused when they encounter a distance that can't be closed. I.E. if you target a creature flying high in the sky, the engine will just get stuck trying to walk to it, not realizing it can never reach the destination.

    What you are asking most likely can't be done without resulting in some bugs - but if you are OK with these peculiarities, I can still attempt it.
  • OlvynChuruOlvynChuru Member Posts: 3,079
    @Bubb

    Go for it! :)
    Bubb wrote: »
    I.E. if you target a creature flying high in the sky, the engine will just get stuck trying to walk to it, not realizing it can never reach the destination.

    That's fine; that's actually what I wanted to happen.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited September 2019
    @Bubb
    OK, here's another one (if you think it makes sense of course):

    Add the following modified version of 'WeaponCanDamage()' and 'WeaponEffectiveVS()':
    WeaponEffectiveVs(O:Object*,I:WeaponNum*SLOTS)
    // Returns true if the weapon specified in the 2nd parameter of the active creature can hit the target object specified in the 1st parameter.
    
    WeaponCanDamage(O:Object*,I:WeaponNum*SLOTS)
    // Returns true if the weapon specified in the 2nd parameter of the active creature can cause non-zero damage to the target object specified in the 1st parameter.
    
    Post edited by _Luke_ on
Sign In or Register to comment.