• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Solved] Problem with my script

Status
Not open for further replies.
Level 10
Joined
Jun 17, 2014
Messages
236
hello hive, i come here because i need help with my script.
everything just working properly, but the private timer why = CreateTimer( ) is not running
here is the code :
JASS:
library felpower
    globals
        private constant integer SPELL_ID = 'ADEM' //INSERT SPELL ID
        private constant real DURATION = 15.
        private unit caster
        private player array z
        private constant string soundname = "war3mapImported\blablacapskjdiuoqwehsa7fbgt76awetr"
        private constant real IMMDAMAGE = 50.
        private constant real ANIM_DUR = 1.2
        private constant integer AB_ID1 = 'ADPI'
        private constant integer IMM = 'e0IM'
        private constant integer AB_ID2 = 0
        private constant integer AB_ID3 = 0
        private unit dum1
        private timer why = CreateTimer( )
    endglobals
    struct roarfelpower
        static method con takes nothing returns boolean
            local timer casttime = CreateTimer( )
            local real x
            local real y
            local sound cc
            local group kz = CreateGroup( )
            local unit p
            local player enemy
            if GetSpellAbilityId( ) == SPELL_ID then
                set caster = GetTriggerUnit( )
                set x = GetUnitX( caster )
                set y = GetUnitY( caster )
                set enemy = GetOwningPlayer( caster )
            // IF UNIT LESS THAT CRITICAL
                set cc = CreateSound( soundname, false, false, true, 12700, 12700, "" )
                call StartSound( cc )
                call KillSoundWhenDone( cc )
                call PauseUnit( caster, true )
                call SetUnitAnimationByIndex( caster, /* some integer anim */ 17 )
                call PauseUnit( caster, false )
                call PauseUnit( caster, true )
                call DestroyGroup( kz )
                call TimerStart( casttime, ANIM_DUR, false, function thistype.onCast2 )
            endif
            set cc = null
            set kz = null
            set p = null
            set enemy = null
            return false
        endmethod
        static method onCast2 takes nothing returns nothing
            local timer dur = CreateTimer( )
            call PauseUnit( caster, false )
            set dum1 = CreateUnit( Player( 15 ), IMM, GetUnitX( caster ), GetUnitY( caster ), 0. )
            call UnitAddAbility( caster, AB_ID1 )
            call TimerStart( why, 0.2, true, function thistype.Immo )
           
            call TimerStart( dur, DURATION, false, function thistype.onExpire )
            call DestroyTimer( GetExpiredTimer( ) )
        endmethod
        static method Immo takes nothing returns nothing
            local group kz
            local unit p
            local real t
            local real u
            local real k
            call BJDebugMsg( R2S( t ) )
            if GetUnitAbilityLevel( caster, AB_ID1 ) != 0 then
                call BJDebugMsg( R2S( t ) )
                set t = t + 0.2
                call SetUnitX( dum1, GetUnitX( caster ) )
                call SetUnitY( dum1, GetUnitY( caster ) )
                if t == 1. then
                    set kz = CreateGroup( )
                    call GroupEnumUnitsInRange( kz, GetUnitX( caster ), GetUnitY( caster ), 300., null )
                    loop
                        set p = FirstOfGroup( kz )
                        exitwhen p == null
                        call GroupRemoveUnit( kz, p )
                        if IsUnitEnemy( p, GetOwningPlayer( caster ) ) and GetUnitState( p, UNIT_STATE_LIFE ) > 0 then
                            call UnitDamageTarget( caster, p, IMMDAMAGE, false, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS )
                        endif
                    endloop
                    call DestroyGroup( kz )
                endif
            else
                set t = 0
                call KillUnit( dum1 )
                call PauseTimer( GetExpiredTimer( ) )
       
            endif
            set p = null
            set kz = null
        endmethod
        static method onExpire takes nothing returns nothing
            call UnitRemoveAbility( caster, AB_ID1 )
            call DestroyTimer( GetExpiredTimer( ) )
        endmethod
        static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger( )
            local integer i = 0

            loop
                exitwhen i > 15
                call TriggerRegisterPlayerUnitEvent( t, Player( i ), EVENT_PLAYER_UNIT_SPELL_EFFECT, null )

                set i = i + 1
            endloop
            call TriggerAddCondition( t, function thistype.con )
        endmethod
    endstruct
endlibrary
//SPECIAL EVENT GARROSH


//Code indented using The_Witcher's Script Language Aligner
//Download the newest version and report bugs at www.hiveworkshop.com
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
Why you needed to make the why timer to be global?
I think you can just declare it as a local just like what you did on other timers.

Edit: there are so many things needed to fix in your code but Ill let the others to point it out ( cause its hard to explain it on mobile )
 
Last edited:
Level 20
Joined
Aug 13, 2013
Messages
1,696
As Ive said there are many things needed to fix on your code to make it fully MUI as you needed to attach the timer data on a hashtable to allocate it or use a timer utils system, But sorry I cant demontrate them all in my mobile right now ^^

Heres a few:

Using bj event is not bad unless it uses multiple events.

Local timers need to null each time

Use the initializer to onInit
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
What do you mean not running?
Debug the why timer first to see if it is really created onInit.

Do you mean the 't' is not showing debug msg on game?

Do you mean that it does not damage nearby enemy units?

What kz group actually doing inside the con method?

Give more exact details of your problem? ^^
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
^
JASS:
loop
                       set p = FirstOfGroup( kz )
                       exitwhen p == null
                 call GroupRemoveUnit( kz, p )
                       if IsUnitEnemy( p, GetOwningPlayer( caster ) ) and GetUnitState( p, UNIT_STATE_LIFE ) > 0 then
                           call UnitDamageTarget( caster, p, IMMDAMAGE, false, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS )
                       endif
                   endloop

Still no response from the user?
 
Last edited:
Level 10
Joined
Jun 17, 2014
Messages
236
What do you mean not running?
Debug the why timer first to see if it is really created onInit.

Do you mean the 't' is not showing debug msg on game?

Do you mean that it does not damage nearby enemy units?

What kz group actually doing inside the con method?

Give more exact details of your problem? ^^

yes, the "t" debug is not show himself on game, exactly that is.

ow, i forgot to delete kz group on con method, don't notice that, it does nothing.

The only problem i noticed is, the FoG loop doesn't have GroupRemoveUnit() so infinite loop occurs and thread crash. I still couldn't get what you meant by "not running" though.

nope, i've do that.
i mean the "t" debug is not showing on game.
 
Level 11
Joined
Dec 19, 2012
Messages
411
Oh, you misunderstand that timer us not running due to not showing "t" value. Actually it is running, but you're not even init "t" value. That why it is not showing up. And by the way i forgot to mention, don't use == sign to compare real variables, they will never be true, even their values are same.
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
Is the damage works? If it does then its weird not showing the debug msg for t.

I suggest to also debug under the
JASS:
set t = 0
// call BJDebugMsg( R2S( t ) ) //
Cause maybe the if condition returned a false statement.

Is this based on Immolation effect? Where it will damage nearby enemy units per second? If thats the point then you must make the 't' variable declared also as global and its initialized value is 0. And change the "if t == 1. " into " if t >= 1 " then reset the t variable into 0 inside that if - then block. So it will damage enemy units per second.
 
Level 10
Joined
Jun 17, 2014
Messages
236
Oh, you misunderstand that timer us not running due to not showing "t" value. Actually it is running, but you're not even init "t" value. That why it is not showing up. And by the way i forgot to mention, don't use == sign to compare real variables, they will never be true, even their values are same.

JASS:
            call BJDebugMsg( R2S( t ) )
            if GetUnitAbilityLevel( caster, AB_ID1 ) != 0 then
                call BJDebugMsg( R2S( t ) )
even like this?, there is another debug before "if" statement.

Is the damage works? If it does then its weird not showing the debug msg for t.

I suggest to also debug under the

Cause maybe the if condition returned a false statement.

Is this based on Immolation effect? Where it will damage nearby enemy units per second? If thats the point then you must make the 't' variable declared also as global and its initialized value is 0. And change the "if t == 1. " into " if t >= 1 " then reset the t variable into 0 inside that if - then block. So it will damage enemy units per second.

not working.

look at it again, i debugging "t" before if statement.

yes, it is.
 
Level 10
Joined
Jun 17, 2014
Messages
236
Im pointing to debug 't' inside the else block. Can you show the recent changes of the code? Specifically when you applied the t global and initialized the value to 0.
ooh, ok.
i did'nt change any code, because this computer does'nt had WE.

EDIT : now on computer that had WE, and it's work.
i think the problem is "t" variable, after i change it to global variable it's work.
 
Last edited:
Level 11
Joined
Dec 19, 2012
Messages
411
even like this?, there is another debug before "if" statement.
As long as there is no any value init to "t", then it won't print out.


I personally don't think it is solved, even it works. There maybe some possible flaws like real comparison as i mentioned which the condition will never meet. Possibly make sure everything is running as expected (not only the output, and also internal trigger calculation)
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,191
And by the way i forgot to mention, don't use == sign to compare real variables, they will never be true, even their values are same.
Actually there is an error margin to real equality comparison, but not the inequality comparison. This results in the rediclous situation where there exists two reals A and B which can cause the following to happen.
Code:
A == B -> true
A != B -> true
I forget how much the error margin is on equality, however it is very significant for small numbers.

One of the problems looks like it was a thread crash due to using uninitalized variables. Non-array variables cause a thread crash if they are evaluated before being assigned a value. The method Immo is a good example of this since you perform "t = t + 0.2" before local real t is assigned a value. The script would stop execution at that point due to a thread crash.
 
Level 10
Joined
Jun 17, 2014
Messages
236
One of the problems looks like it was a thread crash due to using uninitalized variables. Non-array variables cause a thread crash if they are evaluated before being assigned a value. The method Immo is a good example of this since you perform "t = t + 0.2" before local real t is assigned a value. The script would stop execution at that point due to a thread crash.

got it, thank you for the tip.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
As long as there is no any value init to "t", then it won't print out.
There is more than just that.
As DSG mentioned, as long as a variable has no data (not referring to null, but literally no value), then reading the variable will crash the thread.
So
JASS:
           local real t
           call BJDebugMsg( R2S( t ) )
Will attempt to read "t" to show it in the message, however, because it has no data, it crashes the thread and thus prevents all other actions.
 
Status
Not open for further replies.
Top