Spell Problem: Mountain Strike (Chain Spell)

AceLegend90

New Member
Reaction score
6
Spell Problem: Mountain Strike (Chain Spell) *FIXED*

Hey, I have a slight problem with my chain spell. Its purpose is to damage only the last target of the chain, and damage increases per bounce.

Here's what I have so far:
A00Q - Dummy spell on my hero.
A00T - Same dummy spell on my dummy for the graphics.
A00V - The actual spell that damages my target. There are 32 levels for 8 bounces total and 4 level progression.

Code:
function Mountain_Strike_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00Q'
endfunction

function Mountain_Strike_NearFilter takes nothing returns boolean
    if IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) then
		return false
    elseif IsUnitAlly(GetFilterUnit(), GetTriggerPlayer()) then
        return false
	elseif GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) <= 0 then
		return false
	elseif IsUnitInvisible(GetFilterUnit(), GetTriggerPlayer()) then
		return false
	endif
	return true
endfunction

function Mountain_Strike_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local real targetX = GetUnitX(target)
    local real targetY = GetUnitY(target)
    local group near = CreateGroup()
    local unit nearPick
    local integer nearCount = 0
    local group nearHero = CreateGroup()
    local group nearNon = CreateGroup()
    local group nearTargeted = CreateGroup()
    local integer bounces = 4 + GetUnitAbilityLevel(caster, 'A00Q')
    local unit dummy = CreateUnit(GetTriggerPlayer(), 'h004', GetUnitX(caster), GetUnitY(caster), 0.0)
    
    call UnitAddAbility(dummy, 'A00T')
    call SetUnitAbilityLevel(dummy, 'A00T', 1)
    loop
        call GroupAddUnit(nearTargeted, target)
        loop
            exitwhen GetUnitAbilityLevel(target, 'B006') > 0
            call TriggerSleepAction(RMaxBJ(bj_WAIT_FOR_COND_MIN_INTERVAL, 0.1))
        endloop
        call SetUnitPosition(dummy, targetX, targetY)
        call GroupEnumUnitsInRange(near, targetX, targetY, 250.0, Condition(function Mountain_Strike_NearFilter))
        call GroupRemoveGroup(nearTargeted, near)
        exitwhen bounces == 0 or FirstOfGroup(near) == null
        loop
            set nearPick = FirstOfGroup(near)
            exitwhen nearPick == null
            call GroupRemoveUnit(near, nearPick)
            if IsUnitType(nearPick, UNIT_TYPE_HERO) then
                call GroupAddUnit(nearHero, nearPick)
            else
                call GroupAddUnit(nearNon, nearPick)
            endif
        endloop
        set target = GroupPickRandomUnit(nearNon)
        if target == null or (bounces == 1 and not(FirstOfGroup(nearHero) == null)) then
            set target = GroupPickRandomUnit(nearHero)
        endif
        set targetX = GetUnitX(target)
        set targetY = GetUnitY(target)
        call IssueTargetOrder(dummy, "thunderbolt", target)
        set bounces = bounces - 1
    endloop
    loop
        set nearPick = FirstOfGroup(nearTargeted)
        exitwhen nearPick == null
        call GroupRemoveUnit(nearTargeted, nearPick)
        set nearCount = nearCount + 1
    endloop
    call UnitAddAbility(dummy, 'A00V')
    call BJDebugMsg("Target dmg ability level: " + I2S(nearCount * GetUnitAbilityLevel(caster, 'A00Q')))
    call SetUnitAbilityLevel(dummy, 'A00V', nearCount * GetUnitAbilityLevel(caster, 'A00Q'))
    call IssueTargetOrder(dummy, "shadowstrike", target)
    
    call DestroyGroup(near)
    call DestroyGroup(nearHero)
    call DestroyGroup(nearNon)
    call DestroyGroup(nearTargeted)
    call RemoveUnit(dummy)
    set caster = null
    set target = null
    set near = null
    set nearHero = null
    set nearNon = null
    set nearTargeted = null
    set dummy = null
endfunction

function InitTrig_Mountain_Strike takes nothing returns nothing
    set gg_trg_Mountain_Strike = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Mountain_Strike, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_Mountain_Strike, Condition(function Mountain_Strike_Conditions))
    call TriggerAddAction(gg_trg_Mountain_Strike, function Mountain_Strike_Actions)
endfunction

The problem: Now, the skill works perfectly fine against one or two opponents, however, when there are three or more, it sometimes deals more damage than wanted. Like if there were three, there are times when the skill does 400 or 600 damage when I don't want it to. I really can't find what's wrong with this code.

P.S. Sorry if my coding is shoddy, I'm new to JASS (but not to programming languages).

EDIT1: I changed "IsUnitGroupEmptyBJ(near)" and "IsUnitGroupEmptyBJ(nearHero)" to a more efficient "FirstOfGroup(near) == null" and "FirstOfGroup(nearHero) == null".

EDIT2: I changed "call TriggerSleepAction(RMaxBJ(bj_WAIT_FOR_COND_MIN_INTERVAL, 0.25))" to check every 0.1 seconds instead. I forgot to add in that it prioritizes non-hero units for the bounces except for the last bounce, where it prioritizes a hero unit if available.

EDIT3: I changed "bounces == 1" to "bounces - damage == 1" because Sooda pointed out that "bounces" never equals 1.

EDIT4: Instead of using the unreliable variable "damage", I used "nearCount", which counts how many units are in "nearTargeted". I reverted back to decreasing "bounces" and checking if "bounces" is equal to 0 or 1 in my checks.
 

Sooda

Diversity enchants
Reaction score
318
Add
JASS:
call BJDebugMsg(&quot;Hops done: &quot; + I2S(damage))

into loop where after you have increased damage counter and
JASS:
call BJDebugMsg(&quot;Target dmg ability level: &quot; + I2S(damage * GetUnitAbilityLevel(caster, &#039;A00Q&#039;)))

after you have set ability level acording to hops done, compare numbers and you should find bug.
Everything else looks fine per loop picks unit and if no unit in range deals damage, all units with buffs will be removed from search range to not pick same unit twice or more. Start using vJASS, code can be better too, but for beginner well done :)
 

AceLegend90

New Member
Reaction score
6
Thank you, Sooda!

The problem is that the loop is running through too many times, and I have no clue why. Is my function "Mountain_Strike_NearFilter" not filtering out all the units it needs to? Here's what's happening on my screen. It happens about 25% of the time, but when there are 3 units: it bounces through all the targets once, the integer "damage" suddenly jumps to the maximum amount of bounces, the damage dealt is adjusted to integer "damage".

Any pointers? The buff is only on each unit for 0.50 seconds.
 

Sooda

Diversity enchants
Reaction score
318
Your 'bounce' never equals to 1 because you set it to 5 or more at start:
JASS:
    local integer bounces = 4 + GetUnitAbilityLevel(caster, &#039;A00Q&#039;)

We can now safely look only first 'or' condition because second will never be true:
JASS:
if target == null or (bounces == 1 and not(FirstOfGroup(nearHero) == null)) then


Currently I have no ideas. By suddenly you mean first 'damage' equals 1 and after that it equals 5?

EDIT:

Test only with same units (unit, unit, hero) and another test group (hero, hero, unit) and try to figure out how does your ability acts with one different unit. Don't cast ability randomly instead try to create test environment and spot little ability changes.
 

AceLegend90

New Member
Reaction score
6
Yeah, I forgot that bounces never equals 1 because it used to when I made bounces decrease everytime.

By suddenly, I mean the it shows all the hops in numerical order from 1 to 5, but once it hits the third hop, 3 hops, 4 hops, and 5 hops all show on screen at around the same time.
 

AceLegend90

New Member
Reaction score
6
Thanks Sooda, I've fixed the problem by counting how many units are in nearTargeted instead of using a counter.
 

Sooda

Diversity enchants
Reaction score
318
Glad to hear you got it working as planned, next time please don't delete problem parts like JASS because afterward people can learn from your mistakes in future. I understood now what you meant with 'sudden jump' after second hop things got weird.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top