• 🏆 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!

no time for weak

Status
Not open for further replies.
Level 6
Joined
Aug 31, 2014
Messages
137
hello ive been runing into a slight issue with a spell buging im not sure if its piggy backing on other thou..... but here is the code in jass and gui
[jass=spell]//===========================================================================
// Trigger: No time for the weak
//===========================================================================
function Trig_No_time_for_the_weak_Func001C takes nothing returns boolean
if ( not ( GetUnitTypeId(GetAttacker()) == 'Nbst' ) ) then
return false
endif
if ( not ( GetUnitLifePercent(GetAttackedUnitBJ()) < 50.00 ) ) then
return false
endif
return true
endfunction

function Trig_No_time_for_the_weak_Actions takes nothing returns nothing
if ( Trig_No_time_for_the_weak_Func001C() ) then
set udg_Target = GetAttackedUnitBJ()
set udg_hero = GetAttacker()
set udg_Abilitylevel = I2R(GetHeroLevel(udg_hero))
call SetUnitAnimation( udg_hero, "Spell Slam" )
call UnitDamageTargetBJ( udg_hero, udg_Target, ( I2R(GetHeroStatBJ(bj_HEROSTAT_STR, udg_hero, true)) * udg_Abilitylevel ), ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL )
set udg_Abilitylevel = 0.00
set udg_Target = null
set udg_hero = null[/code]
[trigger=gui]No time for the weak
Events
Unit - A unit Is attacked
Conditions
Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Unit-type of (Attacking unit)) Equal to Beastmaster
(Percentage life of (Attacked unit)) Less than 50.00
Then - Actions
Set Target = (Attacked unit)
Set hero = (Attacking unit)
Set Abilitylevel = (Real((Hero level of hero)))
Animation - Play hero's Spell Slam animation
Unit - Cause hero to damage Target, dealing ((Real((Strength of hero (Include bonuses)))) x Abilitylevel) damage of attack type Chaos and damage type Normal
Set Abilitylevel = 0.00
Set Target = No unit
Set hero = No unit
Else - Actions
[/trigger]


heres the other WHICH WORKS
[jass=spell]//===========================================================================
// Trigger: Clumsy Dwaf
//===========================================================================
function Trig_Clumsy_Dwaf_Conditions takes nothing returns boolean
if ( not ( GetUnitTypeId(GetAttacker()) == 'Hmkg' ) ) then
return false
endif
return true
endfunction

function Trig_Clumsy_Dwaf_Actions takes nothing returns nothing
set udg_hero = GetAttacker()
set udg_Target = GetAttackedUnitBJ()
set udg_Abilitylevel = I2R(GetHeroStatBJ(bj_HEROSTAT_STR, udg_hero, true))
set udg_point = GetUnitLoc(udg_Target)
call SetUnitAnimation( udg_hero, "Spell Slam" )
call UnitDamagePointLoc( udg_hero, 0, 100.00, udg_point, ( udg_Abilitylevel * 2.00 ), ATTACK_TYPE_SIEGE, DAMAGE_TYPE_NORMAL )
set udg_Abilitylevel = 0.00
set udg_hero = null
set udg_Target = null[/code]
[trigger=spell]Clumsy Dwaf
Events
Unit - A unit Is attacked
Conditions
(Unit-type of (Attacking unit)) Equal to Mountain King
Actions
Set hero = (Attacking unit)
Set Target = (Attacked unit)
Set Abilitylevel = (Real((Strength of hero (Include bonuses))))
Set point = (Position of Target)
Animation - Play hero's Spell Slam animation
Unit - Cause hero to damage circular area after 0.00 seconds of radius 100.00 at point, dealing (Abilitylevel x 2.00) damage of attack type Siege and damage type Normal
Set Abilitylevel = 0.00
Set hero = No unit
Set Target = No unit
Custom script: call RemoveLocation (udg_point)
[/trigger]


I do remove leaks with all spells just missed the codes for the leaks.
 
Last edited:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
also... noone reads GUI converted JASS better than GUI.
Except people like myself. WC3 GUI is kind of ugly.

heres the other WHICH WORKS
You have not told us what either is meant to be doing. From what I see it looks like both should work in some way or another but that might be completely differently from how you want it to work.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
A few weeks ago, i actually have been using JASS only for so long that I couldnt even use GUI any more :D

But still... this one is not that hard but you have to admit that stuff like this one are getting really annoying to read:
JASS:
function Trig_MiddleSetsDestroyed_Conditions takes nothing returns boolean
    if ( not ( IsUnitType(GetDyingUnit(), UNIT_TYPE_STRUCTURE) == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_MiddleSetsDestroyed_Func001Func001Func001Func001Func001Func001Func002C takes nothing returns boolean
    if ( not ( udg_ItsTimeToDestroyMid[1] == 6 ) ) then
        return false
    endif
    if ( not ( udg_ItsTimeToDestroyMid[2] == 6 ) ) then
        return false
    endif
    if ( not ( udg_ItsTimeToDestroyMid[3] == 6 ) ) then
        return false
    endif
    if ( not ( udg_ItsTimeToDestroyMid[4] == 6 ) ) then
        return false
    endif
    return true
endfunction

function Trig_MiddleSetsDestroyed_Func001Func001Func001Func001Func001Func001C takes nothing returns boolean
    if ( not Trig_MiddleSetsDestroyed_Func001Func001Func001Func001Func001Func001Func002C() ) then
        return false
    endif
    return true
endfunction

function Trig_MiddleSetsDestroyed_Func001Func001Func001Func001Func001Func003C takes nothing returns boolean
    if ( not ( udg_ItsTimeToDestroyMid[4] == 6 ) ) then
        return false
    endif
    return true
endfunction

function Trig_MiddleSetsDestroyed_Func001Func001Func001Func001Func001C takes nothing returns boolean
    if ( not ( udg_TowersTPOrcMid[GetForLoopIndexA()] == GetDyingUnit() ) ) then
        return false
    endif
    return true
endfunction

function Trig_MiddleSetsDestroyed_Func001Func001Func001Func001Func003C takes nothing returns boolean
    if ( not ( udg_ItsTimeToDestroyMid[3] == 6 ) ) then
        return false
    endif
    return true
endfunction

function Trig_MiddleSetsDestroyed_Func001Func001Func001Func001C takes nothing returns boolean
    if ( not ( udg_TowersBTOrcMid[GetForLoopIndexA()] == GetDyingUnit() ) ) then
        return false
    endif
    return true
endfunction

function Trig_MiddleSetsDestroyed_Func001Func001Func001Func003C takes nothing returns boolean
    if ( not ( udg_ItsTimeToDestroyMid[2] == 6 ) ) then
        return false
    endif
    return true
endfunction

function Trig_MiddleSetsDestroyed_Func001Func001Func001C takes nothing returns boolean
    if ( not ( udg_TowersTPHuMid[GetForLoopIndexA()] == GetDyingUnit() ) ) then
        return false
    endif
    return true
endfunction

function Trig_MiddleSetsDestroyed_Func001Func001Func003C takes nothing returns boolean
    if ( not ( udg_ItsTimeToDestroyMid[1] == 6 ) ) then
        return false
    endif
    return true
endfunction

function Trig_MiddleSetsDestroyed_Func001Func001C takes nothing returns boolean
    if ( not ( udg_TowersBTHuMid[GetForLoopIndexA()] == GetDyingUnit() ) ) then
        return false
    endif
    return true
endfunction

function Trig_MiddleSetsDestroyed_Actions takes nothing returns nothing
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 6
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        if ( Trig_MiddleSetsDestroyed_Func001Func001C() ) then
            set udg_ItsTimeToDestroyMid[1] = ( udg_ItsTimeToDestroyMid[1] + 1 )
            if ( Trig_MiddleSetsDestroyed_Func001Func001Func003C() ) then
                call SetUnitInvulnerable( udg_TowersBTHuFrtBrk, false )
            else
            endif
        else
            if ( Trig_MiddleSetsDestroyed_Func001Func001Func001C() ) then
                set udg_ItsTimeToDestroyMid[2] = ( udg_ItsTimeToDestroyMid[2] + 1 )
                if ( Trig_MiddleSetsDestroyed_Func001Func001Func001Func003C() ) then
                    call SetUnitInvulnerable( udg_TowersTPHuFrtBrk, false )
                else
                endif
            else
                if ( Trig_MiddleSetsDestroyed_Func001Func001Func001Func001C() ) then
                    set udg_ItsTimeToDestroyMid[3] = ( udg_ItsTimeToDestroyMid[3] + 1 )
                    if ( Trig_MiddleSetsDestroyed_Func001Func001Func001Func001Func003C() ) then
                        call SetUnitInvulnerable( udg_TowersBTOrcFrtBrk, false )
                    else
                    endif
                else
                    if ( Trig_MiddleSetsDestroyed_Func001Func001Func001Func001Func001C() ) then
                        set udg_ItsTimeToDestroyMid[4] = ( udg_ItsTimeToDestroyMid[4] + 1 )
                        if ( Trig_MiddleSetsDestroyed_Func001Func001Func001Func001Func001Func003C() ) then
                            call SetUnitInvulnerable( udg_TowersTPOrcFrtBrk, false )
                        else
                        endif
                    else
                        if ( Trig_MiddleSetsDestroyed_Func001Func001Func001Func001Func001Func001C() ) then
                            call DestroyTrigger(GetTriggeringTrigger() )
                        else
                        endif
                    endif
                endif
            endif
        endif
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
endfunction

//===========================================================================
function InitTrig_MiddleSetsDestroyed takes nothing returns nothing
    set gg_trg_MiddleSetsDestroyed = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_MiddleSetsDestroyed, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_MiddleSetsDestroyed, Condition( function Trig_MiddleSetsDestroyed_Conditions ) )
    call TriggerAddAction( gg_trg_MiddleSetsDestroyed, function Trig_MiddleSetsDestroyed_Actions )
endfunction
 
Level 6
Joined
Aug 31, 2014
Messages
137
no i am wanting it to single target almost like execute but in passive form. like if he starts attacking a unit with 50% heath or less he will deal streth X his level but it isn't triggering at all. I dont understand why the dwarf one works and the other does not... basicly same triggers but different condition
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Create a new action "Game - Display to all players the text "HP = " + (ConvertRealToString(Current health of target))""
Make one just before the deal damage and one just after.

If that one doesnt make you much wiser, then split the conditions into two parts.
In both "Else" blocks you create another display text action with both different texts.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
If it is not working at all it would be symptomatic of an initialization thread crash. This can be caused by division by 0 or hitting the thread instantaneous operation limit. The operation limit is the most common cause as people often set too large GUI variable arrays and it initializes each index to a value (so an "8000" sized array executes 8,000 times).

Posting the map with the problem might be a good idea. That way people can experience first hand what is not working about the trigger.
 
Level 6
Joined
Aug 31, 2014
Messages
137
ok so i put it in a test map the triggers and it ended up working....
so it might be what you said just not sure how to get it to work now XD can you send me a link or push me in the right direction and would a damage detection system or such fix the issue? ect

edit= i also deleted some unused variables to see if that helps
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
There is something that crashes your initialization.
In GUI it is pretty impossible to reach the limit so there is either a piece of JASS code that you imported that will have massive actions inside a massive loop or you have an event that crashes the initialization.

but as DSG said, posting the map enables us to find that problem and give you a good solution to it as well probably.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
would a damage detection system or such fix the issue?
No, it would either make it worse (if cause is operation limit thread crash) otherwise it would still crash at the same point of the initialization (other thread crashes such as division by 0).

If the cause is an initialization thread crash then the reasons for it could be many. Generally initializing a lot of GUI variables can cause an operation limit thread crash but the numbers needed for that are in the 10,000 range (many arrays of maximum size where each index counts as 1). A lot of triggers can also cause that but that would be in the 1,000s range (few maps have that many). A trigger with too many events (several thousand) is also a cause for such a crash as it is as operation demanding as many triggers.

Any event which uses an arithmetic division operation as an arugment which concludes with division by 0 will crash the thread. Do note that GUI Trigger Event arguments are evaluated by the initialization thread so if the divisor of a division operation was to evaluate to 0 at that time it would cause a thread crash.

All event initialization after the point of the thread crash will not get executed. As such the triggers will appear to be completely broken and never work.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
You are testing with the wrong unit. Rexxar is not a Beastmaster. They look the same, sound the same, even have similar stats but one is the bonus campaign hero (Rexxar) while the other is a normal melee Tavern hero (Beastmaster).

That said do be aware that by pressing stop rapidly you can deal more damage using this than intended since the event fires when an attack starts which is before it deals damage and finishes with cooldown. This affects both triggers.

Additionally the Mountain King suffers from friendly fire (will even hurt itself) due to the nature of the damage you deal. You might want to use a unit group search and deal single target damage to appropriately filtered units instead. Be careful to avoid unit group leaks when doing this.

the trigger actually works and the blademaster deals bonus damage.
Which sounds truly amazing seeing how it is meant to work on the Beastmaster and not the Blademaster.
*cough* typo *cough*
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
You are testing with the wrong unit type. Rexxar is not a Beastmaster. Test it with a Beastmaster and you will see that it does work.

Your "test map" does correctly give the Player 1 (Red) a Beastmaster hero which is why it works. In the actual map ("BOAAH") Player 1 (Red) only has a Rexxar hero which is why it does not work (well it does work, just only on Beastmaster heroes which Player 1 (Red) does not have). Rexxar and Beastmaster are not equivalent to each other and are completely different unit types.

(Unit-type of (Attacking unit)) Equal to Beastmaster
Rexxar -> False
Beastmaster -> True
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
thank you for the help :) i know i will evade the leaks :) also how would i filter the units if i may ask
The below method should work.
  • Clumsy Dwaf
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • (Unit-type of (Attacking unit)) Equal to Mountain King
    • Actions
      • Set hero = (Attacking unit)
      • Set Target = (Attacked unit)
      • Set Abilitylevel = (Real((Strength of hero (Include bonuses))))
      • Set point = (Position of Target)
      • Animation - Play hero's Spell Slam animation
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 100.00 of point matching (((Picked unit) belongs to an enemy of (Owner of hero)) Equal to True)) and do (Actions)
        • Loop - Actions
          • Unit - Cause hero to damage (Picked unit), dealing (Abilitylevel x 2.00) damage of attack type Siege and damage type Normal
      • Custom script: call RemoveLocation (udg_point)
I removed unnecessary variable sets as well.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
  • Unit Group - Pick every unit in (Units within 100.00 of point matching (((Picked unit) belongs to an enemy of (Owner of hero)) Equal to True)) and do (Actions)
    • Loop - Actions
      • Unit - Cause hero to damage (Picked unit), dealing (Abilitylevel x 2.00) damage of attack type Siege and damage type Normal

Inside the "Pick every unit", Picked unit = null, Matching unit = the-unit-that-you-want
Picked unit -> Matching unit.

Inside the "Loop - Actions", Picked unit = the-unit-that-you-want, Matching unit = null
Keep it Picked unit

But I would not suggest to use it.
Instead make an If/Then/Else inside the loop and do the conditions there.
It has several benefits:
1. It is much more readable.
2. This is much more editable.
3. This is more efficient (I am not quite sure but it may reduce the number of new thread runs as well.)
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Inside the "Pick every unit", Picked unit = null, Matching unit = the-unit-that-you-want
Picked unit -> Matching unit.

Inside the "Loop - Actions", Picked unit = the-unit-that-you-want, Matching unit = null
Keep it Picked unit
I forgot how stupid JASS can be at times, my mistake. In StarCraft II group filters are implemented quite differently as internal filter objects which you apply a group to.
 
Level 6
Joined
Aug 31, 2014
Messages
137
how am i surpost to get the aoe from clumsy dwarf to not hurt allys this is what i have so far?

[trigger=trigger]Clumsy Dwaf
Events
Unit - A unit Is attacked
Unit - A unit Is issued an order targeting an object
Conditions
(Unit-type of (Attacking unit)) Equal to Mountain King
Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Issued order) Equal to (Order(stop))
Then - Actions
Skip remaining actions
Else - Actions
Set hero = (Attacking unit)
Set Target = (Attacked unit)
Set Abilitylevel = (Real((Strength of hero (Include bonuses))))
Set point = (Position of Target)
Unit Group - Pick every unit in (Units within 100.00 of point) and do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Target belongs to an enemy of (Owner of hero)) Equal to True
Then - Actions
Animation - Play hero's Spell Slam animation
Unit - Cause hero to damage circular area after 0.00 seconds of radius 100.00 at point, dealing (Abilitylevel x 2.00) damage of attack type Siege and damage type Normal
Else - Actions
[/trigger]


will add leak fixes later... thinking i will have to put them in a unit group
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Inside the loop, you set target to picked unit
The most used (and most basic) condition for splash damage is
Target is enemy of Player
Target is alive
Target is not a structure

You choose to have that last one but the check for alive is really recommended to be a habit.

After that, change the damage to area to damage to target and use the same values.

Also... the issue order thing is pretty weird imo.
Im not familiar with that event in this situation.
 
Level 6
Joined
Aug 31, 2014
Messages
137
Inside the loop, you set target to picked unit
The most used (and most basic) condition for splash damage is
Target is enemy of Player
Target is alive
Target is not a structure

You choose to have that last one but the check for alive is really recommended to be a habit.

After that, change the damage to area to damage to target and use the same values.

Also... the issue order thing is pretty weird imo.
Im not familiar with that event in this situation.

cant seem to find any condtion with splash damage or any damage in genenal

also the event is ment to respond to the stop so they cant abuse the damge by the smash or excute
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Use a DDS if you want to prevent that.
Your solution doesnt work.
About the conditions.
When you want to do splash damage (which you want), the most used targets are enemy non structures.
So you filter out non enemies, structures and ofcourse dead units.

So the conditions are:
Boolean Comparison -> Unit is a structure equal to false
Boolean Comparison -> Unit belongs to an enemy of player equal to false
Boolean Comparison -> Unit is dead equal to false

All should be easy to find.
(the structure is a Unit Classification check.)
 
Status
Not open for further replies.
Top