Portal-Zone Gothic-Zone Gothic II-Zone Gothic 3-Zone Gothic 4-Zone Modifikationen-Zone Download-Zone Foren-Zone RPG-Zone Almanach-Zone Spirit of Gothic

 

Ergebnis 1 bis 8 von 8
  1. Beiträge anzeigen #1
    Apprentice
    Registriert seit
    May 2017
    Beiträge
    38
     
    LootaBox ist offline

    How to create VFX with separated origin and instigator?

    Hey,

    First of all thanks to all the modders around here, I would not have gotten nearly as far with my little mod without the massive amount of ready-made script bits and discussion on these forums.

    So I'm looking at the function Wld_PlayEffect, which takes a parameter often called originVob.
    This parameter determines where the VFX originates and who instigated it. I don't know if the engine differentiates these two roles.
    The first role is obvious and the second is important for the AI to notice that "ok, THAT guys VFX hit me".

    I want to separate these two, to have the instigator still be the same originVob, but the origin of the effect something else.
    Think of Circle 4 "Lightning" spell. You shoot a bolt out of your hand that brings down a lightning when it hits something. I want to remove that intermediary bolt and just bring down the lightning from the sky instantly.

    I will try to explain it using some examples:
    Code:
    Wld_PlayEffect("someFX", target, target, 0, 100, DAM_MAGIC, FALSE);
    • GOOD: Creates VFX around target.
    • BAD: Hits the caster and AI doesn't know caster is responsible.

    Code:
    Wld_PlayEffect("someFX", caster, target, 0, 100, DAM_MAGIC, FALSE);
    • GOOD: Does not hit the caster and AI responds correctly.
    • BAD: Creates VFX around caster.

    How can I combine the good bits from both of these examples? I thought of having some kind of invisible super fast projectile that creates the actual colliding VFX on a delay, but to be honest working with the visual effects of Gothic II is pretty much trial and error for me, even if I'm starting to understand it a little. I can't figure this one out...

    Thanks in advance for any help.

  2. #2
    Falugify
    Gast
     
    Wld_PlayEffect("spellFX", oth, slf, 2, 100, DAM_MAGIC, FALSE);

  3. Beiträge anzeigen #3
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    One line answers are never really helpful. In fact, the only thing you seem to have changed is a parameter going from 0 to 2 and I'm not sure that even helps. If it does: Please explain the answer.

  4. Beiträge anzeigen #4
    Knight
    Registriert seit
    Aug 2009
    Ort
    Hessen
    Beiträge
    1.487
     
    Cryp18Struct ist offline
    In GFA mud-freak does more or less the opposite of what you want:
    https://github.com/szapp/GothicFreeA...n/spell.d#L286
    (changes the target of the vfx, you want to change the origin)
    There might be a suitable engine function you could call in an analogous way.

    edit:
    Or you send a damage perception when the spell triggers:
    Code:
    Wld_PlayEffect("someFX", target, target, 0, 100, DAM_MAGIC, FALSE); // vfx created at target
    Npc_SendSinglePerc(caster, target, PERC_ASSESSDAMAGE); // make target react to damage from caster
    NPC_SendPassivePerc(caster, PERC_ASSESSFIGHTSOUND, target, caster); // make onlookers react to fight caster <-> target
    Geändert von Cryp18Struct (26.09.2019 um 00:55 Uhr)

  5. Beiträge anzeigen #5
    Apprentice
    Registriert seit
    May 2017
    Beiträge
    38
     
    LootaBox ist offline
    One explanation for that parameter i found is the following:

    effectLevel: If you specify effectLevel, it searches for a VisualFX instance called _L and uses it if it is
    was found. (it still needs to have a VisualFX instance defined by name!)

    Im not sure how that would help..?

    The idea to send additional passive percs is great, ill have to look into that. It wont be quite that simple, since the vfx can hit multiple creatures, but i think i can maybe do it using the 'ondmg' hooks..

  6. Beiträge anzeigen #6
    Apprentice
    Registriert seit
    May 2017
    Beiträge
    38
     
    LootaBox ist offline
    Well, for single target this works fine:

    Code:
    func void Spell_Cast_Focus(var C_NPC slf, var C_NPC oth, var int manaCost, var int spellDamage, var string spellFX)
    {
        Wld_PlayEffect(spellFX, oth, oth, 0, 0, 0, FALSE);
        B_MagicHurtNpc(slf, oth, spellDamage);
    
        if (oth.attribute[ATR_HITPOINTS] > 0)
        {
            Npc_SendSinglePerc(slf, oth, PERC_ASSESSDAMAGE);
            NPC_SendPassivePerc(slf, PERC_ASSESSFIGHTSOUND, oth, slf);
        }
        else
        {
            Npc_SendPassivePerc (slf, PERC_ASSESSMURDER, oth, slf);
        };
    
        slf.attribute[ATR_MANA] -= manaCost;
        slf.aivar[AIV_SelectSpell] += 1;
    };
    You can then just call this function from Spell_Cast_LightningFlash (or any other spell), while making sure the _KEY_CAST of that spells VFX doesn't additionally fire the regular projectile from the casters hand.

    I couldn't figure out how to get similar functionality for spells that should hit multiple targets, but for now I can live with this. Thanks for the help!

  7. Beiträge anzeigen #7
    Knight
    Registriert seit
    Aug 2009
    Ort
    Hessen
    Beiträge
    1.487
     
    Cryp18Struct ist offline
    Maybe give broadcasts a try:
    https://forum.worldofplayers.de/foru...1#post17232705
    You could check for all NPCs (in the active AI-Area[30m around hero]) if they are close enough to the primary target and then treat them.

  8. Beiträge anzeigen #8
    Apprentice
    Registriert seit
    May 2017
    Beiträge
    38
     
    LootaBox ist offline
    So, this function has evolved quite a bit since the last post here. I have a bit of an interesting mystery for those interested, but first...

    Here is the current version that I am quite happy with.
    Damage is calculated and delivered OK and AI responds as expected.
    (note: all spells in my mod deal magic type damage, but the function should be easy to adjust for other scenarios)

    Code:
    func  void Spell_Cast_Focus(var C_NPC slf, var C_NPC oth, var int spellID,  var int spellCat, var int spellDamage, var string spellFX)
    {
        // Backup self/other and reverse slf/oth in their place
        var C_NPC selfTemp; selfTemp = Hlp_GetNpc (self);
        var C_NPC otherTemp; otherTemp = Hlp_GetNpc (other);
        self = Hlp_GetNpc(oth); other = Hlp_GetNpc(slf);
    
        // Handle collision, if no collision restore backup self/other and return
        var int coll; coll = C_CanNpcCollideWithSpell(spellID);
        if (coll == COLL_DONOTHING)
        {
            self = Hlp_GetNpc(selfTemp); other = Hlp_GetNpc(otherTemp);
            return;
        };
    
        // Collided, set last hit spell and assess magic
        var oCNpc selfOC; selfOC = Hlp_GetNpc(self);
        //Print(IntToString(selfOC.lastHitSpellID));
        selfOC.lastHitSpellID = spellID;
        selfOC.lastHitSpellCat = spellCat;
        B_AssessMagic();
    
        // Restore backup self/other, use slf/oth from now on
        self = Hlp_GetNpc(selfTemp); other = Hlp_GetNpc(otherTemp);
    
        // Calculate and apply damage
        if (coll & COLL_APPLYDOUBLEDAMAGE)    { spellDamage *= 2; };
        if (coll & COLL_APPLYHALVEDAMAGE)    { spellDamage /= 2; };
        spellDamage -= oth.protection[PROT_MAGIC];
        if (spellDamage > 0) { B_MagicHurtNpc(slf, oth, spellDamage); };
    
        // Play vfx
        Wld_PlayEffect(spellFX, oth, oth, 0, 0, 0, FALSE);
    };
    Now if you look closely there is a commented line in there:
    Code:
    Print(IntToString(selfOC.lastHitSpellID));
    This prints the "last hit spell id" before I set it for the spell being "focus cast", which is necessary for B_AssessMagic. There is a strange behavior that I don't quite understand, and I'm just a bit concerned that it might have some side effects.

    I use this method for SPL_LightningFlash, for instance (spell id 29).
    I was testing with SPL_Firebolt (spell id 19), which is using the normal engine/vfx method of spell delivery (I haven't touched it).
    In all tests I target an NPC that has not been hit by any spell.

    If I cast spell 29 twice, I get printed -1 and 29. This seems OK, no spell hit the NPC before the first one and then its 29, as can be expected.

    If I cast 19 followed with 29, I get printed -1. This could also be OK, makes me think that the engine clears the last hit spell ID at some point before the second spell hit the NPC. I could easily just clear the id that I set after calling B_AssessMagic in my function.

    But before I did that I did additional test, and now comes the weird part.
    If I cast 29 -> 19 -> 29, I get printed -1 and 29. No I'm lost!

    If the engine clears the last hit spell ID after handling the spell 19... Why is the hit id 29 still there when I get to casting 29 again? If the engine clears the last hit spell id the expected prints would be -1 and -1.

    Maybe I am missing something obvious, and maybe I am worrying over nothing... But if anyone can offer some insight into this that would be much appreciated!

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
Impressum | Link Us | intern
World of Gothic © by World of Gothic Team
Gothic, Gothic 2 & Gothic 3 are © by Piranha Bytes & Egmont Interactive & JoWooD Productions AG, all rights reserved worldwide