Jump to content

[LE] Show script's 'count' number on a message ?


maxarturo

Recommended Posts

Thank you all for your suggestions SurfsideNaturals, Ghaunadaur and last but not least ReDragon.!.


I'll experiment with them all to see which one can work better with what i have in mind. I'm still working on the weapons textures, i should be done with them in a couple of days to start constructing this.


Unfortunately, the scripting and set up approach i have chosen for this, does make the whole thing light and fast to execute, but at the same time it adds some restrictions to it...

Plus, i had the wild idea to not 'count' and show the projectiles fired info, but show the "Soul Gem's Energy Used" on a message and on the Modular, visual retrieval of the info, but i'm still working on the best way that this can be done using just one mesh.


From the player's point of view this is a better approach since it's more direct, i don't think anyone will 'count' how many projectiles he/she has left while they are in an intense hard battle, in my mod they are plenty of those where the player finds himself traped and surrounded by hard tough enemies with no way out.

So, seeing the % of energy is a direct absorption of the info, no need for further thinking !.


Thanks all again !.

Edited by maxarturo
Link to comment
Share on other sites

So i started building this and the 2H Greatsword version works as intended, but during the construction of the 2H version i realise that the 1H version had some major problems that makes it almost impossible to build it like i had originally envisioned.


So, if the 1H swords version can't have their own modulator there is no point to add it to the 2H version, makes no sense...

* There is a way to build what i had first planned but it will result in a five times bigger script than the one i'm posting below and 3 scripts to make it work, making it heavy and easy to produce lag especially if 'Dual Wielding' and doing continuous 'Power Attacks', so i had to change direction.


................................................................................................


Now i'm having a weird issue with the 1H script version.

I have one script for the 3 different types of swords, but of course each one with different assign properties.


The issue that i'm facing is that, "sometimes" if i equip a sword (electro sword) and fire X number of projectiles and then equip the second (insinerator sword) in the other hand, the scripts behaves like they have/share the same "Int Count", so if each sword have 10 projectiles and i fire 5 with one and then i 'dual weild' the second should have 10 projectiles and the first 5, but it starts the count for both at '0' and fires 10 projectiles for each sword.


If i make a separate script for the second sword with different name and different 'Count' name, this never happens !, and it makes NO SENSE !.

And i don't want to have 3 script for each sword that are exactly the same.


If anyone knows why this is happening or has a different approach on the script to avoid this issue happening, i would be most grateful !.




Scriptname aXMDDwarvenXElectrocutionerFx extends activemagiceffect
{Casts the 1H Dwarven X Sword Projectile}

Message Property CoreChargedMSG Auto

Message Property CoreDepletedMSG Auto

GlobalVariable Property EnergyCount Auto

Spell Property SpellHoriz auto

Actor Property PlayerREF Auto

Weapon Property Xsword Auto

Int ECount


Event OnEffectStart(Actor akTarget, Actor akCaster)
akCaster == PlayerREF
registerForAnimationEvent(akCaster, "WeaponSwing")
registerForAnimationEvent(akCaster, "WeaponLeftSwing")
EndEvent

Event OnEffectFinish(Actor akTarget, Actor akCaster)
;;
EndEvent

Event OnAnimationEvent(ObjectReference akSource, string EventName)
akSource == PlayerREF
If ( EnergyCount.GetValue() == 1 )
If EventName == "WeaponSwing"
Bool PowerAttack = akSource.GetAnimationVariableBool("bAllowRotation")
If PowerAttack
If ( PlayerREF.GetEquippedItemType(1) == 1 ) || ( PlayerREF.GetEquippedItemType(0) == 1 )
SpellHoriz.cast(akSource)
ECount = ECount + 1
EndIf
EndIf

ElseIf EventName == "WeaponLeftSwing"
Bool PowerAttack = akSource.GetAnimationVariableBool("bAllowRotation")
If PowerAttack
If ( PlayerREF.GetEquippedItemType(1) == 1 ) || ( PlayerREF.GetEquippedItemType(0) == 1 )
SpellHoriz.cast(akSource)
ECount = ECount + 1
EndIf
EndIf
EndIf
If ( ECount >= 10 )
EnergyCount.setvalue( 0 )
Debug.Notification("DEPLETED")
Utility.Wait(30.0)
If (PlayerREF.GetEquippedWeapon() == Xsword) || (PlayerREF.GetEquippedWeapon(True) == Xsword)
Debug.Notification("CHARGED")
Else
Debug.Notification("CHARGED")
EndIf
ECount = 0
EnergyCount.setvalue( 1 )
EndIf
Else
;
EndIf
EndEvent



Thank you very much for reading all this !.

Edited by maxarturo
Link to comment
Share on other sites

You are using animation events. The magic effect is on the player. If you are dual wielding two one handed weapons, how is the game supposed to know which animation event to fire on which magic effect?

 

Can you tell the exact weapon that is being swung? I do not see this script being able to do that.

 

Please include all of the script associated with this.

 

You might also consider finding the actual power attack events instead of this ( PlayerREF.GetAnimationVariableBool("bAllowRotation") )

Scriptname aXMDDwarvenXElectrocutionerFx extends activemagiceffect  
{Casts the 1H Dwarven X Sword Projectile}
 
Message Property CoreChargedMSG Auto
 
Message Property CoreDepletedMSG Auto
 
GlobalVariable Property EnergyCount Auto
 
Spell Property SpellHoriz auto
 
Actor Property PlayerREF Auto
 
Weapon Property Xsword Auto
 
;Int ECount
 
 
Event OnEffectStart(Actor akTarget, Actor akCaster)
        registerForAnimationEvent(PlayerREF, "WeaponSwing")
        registerForAnimationEvent(PlayerREF, "WeaponLeftSwing")
EndEvent
 
Event OnEffectFinish(Actor akTarget, Actor akCaster)
;;
EndEvent
 
Event OnAnimationEvent(ObjectReference akSource, string EventName)
  ;EventName == "WeaponSwing" || EventName == "WeaponLeftSwing"  You only registered these so you do not need to check for them.
  ;Please test this and see if the script fires on "unregisted events".

         ;  If akSource == PlayerREF As ObjectReference ; only the play was registered, you really do not need this.
          ; Else 
          ;   Return
        ;   EndIf

           If PlayerREF.GetAnimationVariableBool("bAllowRotation")
           Else 
            Return
           EndIf

           If PlayerREF.IsEquipped(Xsword As Form) ; If the player is swinging a weapon any equipped sword will be out. You really do not need this because the effect will be added and removed when the sword is equipeed and unequipped.
           Else
            Return
           EndIf
      
              If EnergyCount.GetValue() < 10
                SpellHoriz.cast(PlayerREF)
                EnergyCount.Mod(1.0)
              Else
                Debug.Notification("DEPLETED")
                Utility.Wait(30.0)
                If PlayerREF.IsEquipped(Xsword As Form)
                    Debug.Notification("CHARGED")
                EndIf
                EnergyCount.setvalue(0)
              EndIf

EndEvent
Link to comment
Share on other sites


"The magic effect is on the player"

The whole thing is handle by perks that are added and removed when the swords are equipped/unequipped, each sword has its own perk that handles it.



"Please include all of the script associated with this. "

I stopped at that point until i resolve the issue presented.


"If akSource == PlayerREF As ObjectReference ; only the play was registered, you really do not need this."

This is there because i intend to make it also be usable by followers, but with a different function.


"IsEquipped()"

It will only fire for the right hand "Weapon" and NOT for the LEFT.


"ECount = 0 ;If the player eqiups the sword, unequips the sword and then equps it again THIS WILL BE SET BACK TO 0."

This is handle by the Global so that it reset only when is suppose to.

The "ECount" is inside the "If ( EnergyCount.GetValue() == 1 )", so it will only fire when this is TRUE ( 1 ) and the "Last Power Attack Left" has been made.

And by using "Wait" instead of "RegisterForGameTime" it stops there and fires when "Wait" finishes, despite the fact that you can unequipped - equipp the sword multiple times ( i'm using "WaitGameTime" ).

* It needs 1h to recharge and each weapon can fire 20 projectiles for each charge.


"Can you tell the exact weapon that is being swung?"

There is only one Event in papyrus that can detect which weapon and from which hand did the swing, but that Event does not register for power attacks, only regular swings and the projectiles from the swords should fire ONLY on power attacks.



As i said there are some issues with 1H Sword "Power Attack", and the issues all lie in the fact that the game was originally made for the Player and Npcs to wield only right handed swords, so to be able to detect a "Power Attack" from the Left Hand it needs to have this lines:

If EventName == "WeaponSwing"

Bool PowerAttack = akSource.GetAnimationVariableBool("bAllowRotation")

If PowerAttack

If ( PlayerREF.GetEquippedItemType(1) == 1 ) || ( PlayerREF.GetEquippedItemType(0) == 1 )


Otherwise it will never fire for the left hand power attacks.



"how is the game supposed to know which animation event to fire on which magic effect? "

This is also resolved by the lines above.



Also those lines are needed because the weapons have also the ability to transfer their projectile function (using the Player's body as a conductor) to another sword equipped in the opposite hand either if it's my projectile swords or a simple sword as long at it's a sword.

If using two of my swords the projectile fire is twice much powerful and you can achieve different combination of powerful damage and visual fxs.

This is absolutely necessary to exist because some of my bosses are literally almost impossible to kill with conventional weapons, and i made this this way so that the player needs to find each boss weakness, and to fight them will require to use my swords alongside with any other things he/she might have in his arsenal.

This mod won't be a walk in the park for anyone that choose to play it, it will literally be a nightmare !.


*** The "ECount" is used to count the projectiles and the Global to determine if the "Sword's Energy Core" is full or empty.


* The issues that you mention can be resolved with an unconventional way, but the whole thing will become too big and heavy.


* Unfortunately, your version of the script will never fire for a LEFT HAND power attack.


* The script works fine, is doing exactly what is supposed to do with no problems, but the only issue is that 1 out of 10 the "Count" will do that weird behavior.

I think i have stumble once again in an unknown bug...


Thank you very much my lady for burning some of your brain cells in this !.

Edited by maxarturo
Link to comment
Share on other sites

This script will work just fine on a weapon in the players left hand.

 

Please try the script before commenting on it. You do not need two variables. Using the global variable to count the uses is a much better idea. You can also use it in your message.

 

Your problem is not a glitch, I told you why your count is off. If you are dual wielding, you will need to determine exactly which sword is being swung. You have stated that certain power events will not fire if a sword is swung from the left hand. So check which hand the sword is in and then use the appropriate events to catch the swing.

 

Meaning, If the sword that is in your effect is not swinging, then the events will not fire on it.

 

https://www.creationkit.com/index.php?title=GetEquippedWeapon_-_Actor

 

If PlayerREF.GetEquippedWeapon(True) == Xsword ; Left

Events that will catch the power animation events in the left hand.

EndIf

 

 

If PlayerREF.GetEquippedWeapon() == Xsword ; Right

Events that will only catch the power animation events in the right hand.

EndIf

 

Now you know exactly which sword was swung and can apply the proper count and spell.

Scriptname aXMDDwarvenXElectrocutionerFx extends activemagiceffect  
{Casts the 1H Dwarven X Sword Projectile}
 
Message Property CoreChargedMSG Auto
 
Message Property CoreDepletedMSG Auto
 
GlobalVariable Property EnergyCount Auto
 
Spell Property SpellHoriz auto
 
Actor Property PlayerREF Auto
 
Weapon Property Xsword Auto
 
;Int ECount
 
 
Event OnEffectStart(Actor akTarget, Actor akCaster)
        registerForAnimationEvent(PlayerREF, "WeaponSwing")
        registerForAnimationEvent(PlayerREF, "WeaponLeftSwing")
EndEvent
 
Event OnEffectFinish(Actor akTarget, Actor akCaster)
;;
EndEvent
 
Event OnAnimationEvent(ObjectReference akSource, string EventName)
  ;EventName == "WeaponSwing" || EventName == "WeaponLeftSwing"  You only registered these so you do not need to check for them.
  ;Please test this and see if the script fires on "unregisted events".

         ;  If akSource == PlayerREF As ObjectReference ; only the play was registered, you really do not need this.
          ; Else 
          ;   Return
        ;   EndIf

           If PlayerREF.GetAnimationVariableBool("bAllowRotation")
           Else 
            Return
           EndIf

           If PlayerREF.GetEquippedWeapon(True) == Xsword || PlayerREF.GetEquippedWeapon() == Xsword
           Else
            Return
           EndIf
      
              If EnergyCount.GetValue() < 11
                SpellHoriz.cast(PlayerREF)
                EnergyCount.Mod(1.0)
              Else
                Debug.Notification("DEPLETED")
                Utility.Wait(30.0)
                If PlayerREF.GetEquippedWeapon(True) == Xsword || PlayerREF.GetEquippedWeapon() == Xsword
                    Debug.Notification("CHARGED")
                EndIf
                EnergyCount.setvalue(0)
              EndIf

EndEvent
Link to comment
Share on other sites

First of all, a million thanks for your willingness to help me !.

And if i offend you in any way with anything that it's written further down, i apologise in advance !.

The last thing that i want is to close doors, tomorrow i might really need the help from someone such as you.


I don't want to be ungrateful or unrespectful, but i'm in a position that i don't need to test a script to see if it works, just by reading it i can see what it does or it doesn't and to identify its flaws.


Describing an idea in a written text is hard for the reader to comprehend the functions and complexity of the idea.


...................................................................................................................


Your script removes completely a fundomentional "Ability" of the weapons, the ability to cast the projectile from a "simple common sword" if in the other hand one of my 'Projectile Weapons' is equipped, removes the "Conductor - Transfer" ability.


Your script removes completely a fundomentional "Ability" of the weapons, the ability to double cast the projectiles in one "Power Attach" from one sword source if 2 of the projectiles sword are equipped, removes the "Overcharge Projectile" ability.


Your idea to use the global to count the projectiles is based on common logic and that's ok, but my idea requires the global to change only from "0" to "1" (this works as the battery meter, Full or Empty and nothing else), the global will be also accessed/use by another script, by the armor's Abilities script.

* but i haven't even started working on the armor's textures...


"Your problem is not a glitch"

I do think that it's in the category of glitches because it will happen only 1 out of 10, and just before i started writing this post i run one more test and i fire in total around 200+ projectiles and the issue did not appear, everything worked flawlessly.

The issue is kind of random and sparse.


I'm already using "GetEquippedWeapon()" in the part of the script that needs to identify the weapon and hand.


* My firsts 1H swords scripts had your logic, but they just wouldn't do the job. i have change around 5 different scripting logics before the final.


* Every time i make a post of an issue i'm facing only 5% of the times someone else can really provide some kind of help, the majority of the times it's some kind of unknown bug or game engine / papyrus flaw.

One simple big example:

Event OnTranslationComplete()

This event is completely F*** U* and it will only fire a few functions (3 to be precise), everything else will be completely ignored and never fire !!.

I can't even start to count how many flaws papyrus has and they are not documented on "creationkit.com" or anywhere else.


* Don't worry, i will find a solution as always...


And again, a million... Million thanks !.

Edited by maxarturo
Link to comment
Share on other sites

maxarturo you should reflect to hints from SurfsideNaturals, because your script is not right.

 

We assume each sword has its own spell(effect) and an own counter to observe: "How many times has been casted the specific spell?".

 

aXMDDwarvenXElectrocutionerFx

 

Scriptname aXMDDwarvenXElectrocutionerFx extends ActiveMagicEffect  
{Casts the 1H Dwarven XSword Projectile}
; https://forums.nexusmods.com/index.php?/topic/8417073-show-scripts-count-number-on-a-message/page-2

 ;Message PROPERTY CoreChargedMSG  auto
 ;Message PROPERTY CoreDepletedMSG auto

  GlobalVariable PROPERTY xCount      auto    ; globalVar weapon specific
  Weapon         PROPERTY Xsword      auto    ; special sword
  Spell          PROPERTY SpellHoriz  auto    ; spell to cast by PowerAttack
 

; -- EVENTs -- 3 + "Waiting"
 
EVENT OnEffectStart(Actor akTarget, Actor akCaster)
; we assume everyone can be the caster, not only the player
    RegisterForAnimationEvent(akCaster as ObjectReference, "WeaponSwing")
    RegisterForAnimationEvent(akCaster as ObjectReference, "WeaponLeftSwing")
ENDEVENT


EVENT OnEffectFinish(Actor akTarget, Actor akCaster)
ENDEVENT


EVENT OnAnimationEvent(ObjectReference akSource, String eventName)
IF (xCount.GetValue() >= 10.0)
    RETURN    ; - STOP -    still in cooldown phase
ENDIF
;---------------------
IF akSource.GetAnimationVariableBool("bAllowRotation")
    IF (eventName == "WeaponSwing")
        myF_TrySpellCast(akSource, TRUE)        ; right hand power attack
    ELSE ;IF (eventName == "WeaponLeftSwing")
        myF_TrySpellCast(akSource, False)       ; left hand power attack
    ENDIF
ENDIF
ENDEVENT


;=============================
state Waiting    ; busy while cooldown time for recharging
;============
    EVENT OnAnimationEvent(ObjectReference akSource, String eventName)
    ENDEVENT
;=======
endState


; -- FUNCTION --

;------------------------------------------------------------
FUNCTION myF_TrySpellCast(ObjectReference akSource, Bool bOK)
;------------------------------------------------------------
; "If you are dual wielding, you will need to determine exactly which sword is being swung." ( SurfsideNaturals )

IF ((akSource as Actor).GetEquippedWeapon(bOK) == Xsword)    
    ; right hand (TRUE), left hand (False)
ELSE
    RETURN    ; - STOP -  no power attack, no spell casting
ENDIF
;--------------------- "Now you know exactly which sword was swung and can apply the proper count and spell."
    SpellHoriz.Cast(akSource)        ; cast the spell
    xCount.Mod(1)                    ; increment sword counter

IF (xCount.GetValue() < 10.0)
    RETURN    ; - STOP -    weapon effect still active
ENDIF
;---------------------
    gotoState("Waiting")            ; ### STATE ###
    bOK = (Game.GetPlayer() == akSource as Actor)

    IF ( bOK )
;;;        CoreDepletedMSG.Show()
        Debug.Notification("DEPLETED")            ; debug info only for player
    ENDIF

int i = 30
    WHILE (i)
        Utility.Wait(1.0)
        i = i - 1
    ENDWHILE

    IF ( bOK )
;;;        CoreChargedMSG.Show()
        Debug.Notification("CHARGED")            ; debug info only for player
    ENDIF

    xCount.setValue(0)               ; reset sword counter
    gotoState("")                    ; ### STATE ###
ENDFUNCTION

 

 

 

Good luck..

Edited by ReDragon2013
Link to comment
Share on other sites

Hi ReDragon.


The last 2 days the only thing that i've been doing is testing heavily my script (final version, but it's the same logic), i've fire thousands of projectiles from all 3 different swords in different combinations and in all possible scenarios, and the "Count" issue occurred only once.

* The "Count" issue is not game or mod breaking.


Other than that, it's working flawlessly !!, it's doing exactly what it's supposed to be doing, so i'm done with this, it's ready...


Thank you both very much for your interest !.

Edited by maxarturo
Link to comment
Share on other sites

 

I can't even start to count how many flaws papyrus has and they are not documented on "creationkit.com" or anywhere else.

 

XD

Well, there are indeed some.

 

But it seems you got it going. Sometimes it's just necessary to be happy with the available solution. :sad:

 

 

Gamebryo isn't that much better either, but just got better in the recent years.

For example, there was no function to activate and deactivate the Pipboy light. oO

I mean that's a simple function, but no command for it to manipulate the light.

 

The only way to turn the light on / off was by pressing the button to go into the inventory for a longer period of time.

 

Which was the way I initially did it. XDDD

Even though I was very unhappy with that solution it worked.

So a combination of HoldKey and ReleaseKey did the trick.

 

Except a few months later JazzIsParis updated his NVSE plugin with this one:

TogglePipBoyLight

Which made me re-writing the whole mod from scratch. ^^

 

 

 

I recently either found some nice issue with

MoveToMyEditorLocation

in Papyrus.

There are 8 corspes the player can drag around and move out of the battle arena, in my recent mod.

I tested that by moving the corpses almost to the other end of the whole dungeon.

As soon as the player starts the boss combat, the corspes should be moved back into their initial position as the boss needs them for specific battle states.

Yet this one didn't work:

 

 

            TimeFadeOut01FXS.Play(_00E_YC_Victim1)
            TimeFadeOut01FXS.Play(_00E_YC_Victim2)
            TimeFadeOut01FXS.Play(_00E_YC_Victim3)
            TimeFadeOut01FXS.Play(_00E_YC_Victim4)
            TimeFadeOut01FXS.Play(_00E_YC_Victim5)
            TimeFadeOut01FXS.Play(_00E_YC_Victim6)
            TimeFadeOut01FXS.Play(_00E_YC_Victim7)
            TimeFadeOut01FXS.Play(_00E_YC_Victim8)
            Utility.Wait(2)
            _00E_YC_Victim1.MoveToMyEditorLocation()
            _00E_YC_Victim2.MoveToMyEditorLocation()
            _00E_YC_Victim3.MoveToMyEditorLocation()
            _00E_YC_Victim4.MoveToMyEditorLocation()
            _00E_YC_Victim5.MoveToMyEditorLocation()
            _00E_YC_Victim6.MoveToMyEditorLocation()
            _00E_YC_Victim7.MoveToMyEditorLocation()
            _00E_YC_Victim8.MoveToMyEditorLocation()
            TimeFadeIn01FXS.Play(_00E_YC_Victim1)
            TimeFadeIn01FXS.Play(_00E_YC_Victim2)
            TimeFadeIn01FXS.Play(_00E_YC_Victim3)
            TimeFadeIn01FXS.Play(_00E_YC_Victim4)
            TimeFadeIn01FXS.Play(_00E_YC_Victim5)
            TimeFadeIn01FXS.Play(_00E_YC_Victim6)
            TimeFadeIn01FXS.Play(_00E_YC_Victim7)
            TimeFadeIn01FXS.Play(_00E_YC_Victim8)

 

 

 

I tried to make their teleportation back to their initial place looks a bit magical by using these visual effects.

Yet "MoveToMyEditorLocation()" didn't fire properly (especially for the corpses which were floating in the water).

 

So I came up with this:

 

 

            TimeFadeOut01FXS.Play(_00E_YC_Victim1)
            TimeFadeOut01FXS.Play(_00E_YC_Victim2)
            TimeFadeOut01FXS.Play(_00E_YC_Victim3)
            TimeFadeOut01FXS.Play(_00E_YC_Victim4)
            TimeFadeOut01FXS.Play(_00E_YC_Victim5)
            TimeFadeOut01FXS.Play(_00E_YC_Victim6)
            TimeFadeOut01FXS.Play(_00E_YC_Victim7)
            TimeFadeOut01FXS.Play(_00E_YC_Victim8)
            Utility.Wait(2)
            _00E_YC_Victim1.Disable()
            _00E_YC_Victim2.Disable()
            _00E_YC_Victim3.Disable()
            _00E_YC_Victim4.Disable()
            _00E_YC_Victim5.Disable()
            _00E_YC_Victim6.Disable()
            _00E_YC_Victim7.Disable()
            _00E_YC_Victim8.Disable()
            _00E_YC_Victim1.MoveToMyEditorLocation()
            _00E_YC_Victim2.MoveToMyEditorLocation()
            _00E_YC_Victim3.MoveToMyEditorLocation()
            _00E_YC_Victim4.MoveToMyEditorLocation()
            _00E_YC_Victim5.MoveToMyEditorLocation()
            _00E_YC_Victim6.MoveToMyEditorLocation()
            _00E_YC_Victim7.MoveToMyEditorLocation()
            _00E_YC_Victim8.MoveToMyEditorLocation()
            _00E_YC_Victim1.Enable()
            _00E_YC_Victim2.Enable()
            _00E_YC_Victim3.Enable()
            _00E_YC_Victim4.Enable()
            _00E_YC_Victim5.Enable()
            _00E_YC_Victim6.Enable()
            _00E_YC_Victim7.Enable()
            _00E_YC_Victim8.Enable()

 

 

Even though there is now no fancy effect when the corpses re-appear on their initial location, at least the movement works properly.

 

Disabling, moving and enabling stuff was something I already got used to in Gamebryo, so it seems a few Gamebryo solutions still work here. :D

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...