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

[JASS] I can't save my game and I think it's because of These Codes memory leak but I don't know how to fix it.

Level 2
Joined
Feb 12, 2024
Messages
16
Edited1: I tried disable all 3 code listed below but the crash when save the game (not the map) still occur.

1708834528932.png



I just learnd Jass for about a week. I have edited other's code to my liking for my custom map.

this map game saving was fine before.

but after I added and edited 3 of these code in to my map. When I actually play the map and try to save it. It got fatal error and can't not be saved.

So this is why I think the fatal error caused by these 3 code but I don't know how to fix it.


JASS:
function Omnislash_Ulti_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A08Z' //New SpellId needed for your new Spell
endfunction

function Unit_Group_Ulti takes nothing returns boolean
    return GetBooleanAnd( IsUnitAliveBJ(GetFilterUnit()) == true, IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true  ) and UnitHasBuffBJ(GetFilterUnit(), 'Bcyc') == false and UnitHasBuffBJ(GetFilterUnit(), 'BUsl') == false and GetUnitTypeId(GetFilterUnit()) != 'uplg' and GetUnitTypeId(GetFilterUnit()) != 'uloc' and UnitHasBuffBJ(GetFilterUnit(), 'Bcy2') == false
endfunction

function Omnislash_Ulti_Actions takes nothing returns nothing
    local unit Caster = GetTriggerUnit()
    local integer i = 0
    local group UnitGroup
    local unit TargetRandom
    local unit Target = GetSpellTargetUnit()
    local effect Phoenix
    local location R
    local integer AGI = GetHeroStatBJ(bj_HEROSTAT_AGI, Caster, true)
    local real Damage = ( 1000.00 * GetUnitAbilityLevelSwapped('A08Z', Caster) ) + ( AGI * 25 )
    local integer Amount = 2 + ( GetUnitAbilityLevelSwapped('A08Z', Caster) * 5 )
// 2 + ( GetUnitAbilityLevelSwapped('A08Z', Caster) * 5 ) >> set how many hits
// 3000 * ( GetUnitAbilityLevelSwapped('A08Z', Caster) ) >> how much damage deal
    call SetUnitAbilityLevelSwapped( 'A0EC', GetTriggerUnit(), ( GetUnitAbilityLevelSwapped('A08Z', GetTriggerUnit()) + 1 ) )
//
    call TriggerSleepAction( 0.20 )
    call SelectUnitRemove( Caster )
    call SetUnitVertexColor( Caster, 150, 150, 150, 150 )
    call SetUnitInvulnerable( Caster, true )
    set Phoenix = AddSpecialEffectTarget("Abilities\\Weapons\\ChimaeraAcidMissile\\ChimaeraAcidMissile.mdl",Caster,"weapon" )
    call DestroyEffect(AddSpecialEffectTarget( "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl", Caster, "chest" ))
    call SetUnitPositionLocFacingBJ( Caster, PolarProjectionBJ(GetUnitLoc(Target), 50.00, GetRandomDirectionDeg()), AngleBetweenPoints(GetUnitLoc(Caster), GetUnitLoc(Target)) )
    call UnitDamageTarget( Caster, Target, Damage, false, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_AXE_MEDIUM_CHOP )
    call SetUnitAnimation( Caster, "attack" )
    call TriggerSleepAction( 0.25 )
    call SelectUnitRemove( Caster )
//    set UnitGroup = GetUnitsInRangeOfLocMatching(600.00, GetUnitLoc(Caster), Condition(function Unit_Group_Ulti))
    set TargetRandom = Target
    loop
        set i = i + 1
        exitwhen i > Amount
//            call DestroyGroup(UnitGroup)   
            set UnitGroup = GetUnitsInRangeOfLocMatching(600.00, GetUnitLoc(Caster), Condition(function Unit_Group_Ulti))
            if ( IsUnitGroupEmptyBJ(UnitGroup) == false ) then
                if ( not( IsUnitDeadBJ(TargetRandom) == true ) ) then
                    set R = GetUnitLoc(TargetRandom)
                    call DestroyEffect(AddSpecialEffectTarget( "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl", Caster, "chest" ))
                    call SetUnitPositionLocFacingBJ( Caster, PolarProjectionBJ(R, 50.00, GetRandomDirectionDeg()), AngleBetweenPoints(GetUnitLoc(Caster), GetUnitLoc(TargetRandom)) )
                    call UnitDamageTarget( Caster, TargetRandom, Damage, false, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_AXE_MEDIUM_CHOP )
                    call SetUnitAnimation( Caster, "attack" )
                    call RemoveLocation ( R )
                    call TriggerSleepAction( 0.17 )
                    call SelectUnitRemove( Caster )
                else              
                    set TargetRandom = GroupPickRandomUnit(UnitGroup)
                    set R = GetUnitLoc(TargetRandom)
                    call DestroyEffect(AddSpecialEffectTarget( "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl", Caster, "chest" ))
                    call SetUnitPositionLocFacingBJ( Caster, PolarProjectionBJ(R, 50.00, GetRandomDirectionDeg()), AngleBetweenPoints(GetUnitLoc(Caster), GetUnitLoc(TargetRandom)) )
                    call UnitDamageTarget( Caster, TargetRandom, Damage, false, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_AXE_MEDIUM_CHOP )
                    call SetUnitAnimation( Caster, "attack" )
                    call RemoveLocation ( R )
                    call TriggerSleepAction( 0.17 )
                    call SelectUnitRemove( Caster )
                endif
            else
            endif
            call DestroyGroup(UnitGroup)
        endloop
    call SelectUnitForPlayerSingle( Caster, GetTriggerPlayer() )
//
    call SetUnitAbilityLevelSwapped( 'A0EC', GetTriggerUnit(), 1 )
//
    call SetUnitInvulnerable( Caster, false )
    call SetUnitVertexColor( Caster, 255, 255, 255, 255 )
    call DestroyEffect( Phoenix )
    set Phoenix = null
    set Caster = null
    set UnitGroup = null
    set TargetRandom = null
    set Target = null
    set Amount = 0
    set R = null
    set AGI = 0
    set Damage = 0
endfunction

//===========================================================================
function InitTrig_Omnislash_Ulti_Sentry_Ultimate takes nothing returns nothing
    local trigger trig = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( trig, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( trig, Condition( function Omnislash_Ulti_Conditions ) )
    call TriggerAddAction( trig, function Omnislash_Ulti_Actions )
  set trig = null
endfunction

JASS:
scope GreaterBashNew initializer Init
globals
    private constant integer MAX_HANDLE_NO = 8190
    private constant integer MIN_HANDLE_ID = 0x100000
  
    private boolean array Flag[MAX_HANDLE_NO]
endglobals

private function H2I takes handle h returns integer
    return GetHandleId(h)
endfunction

private function Conditions takes nothing returns boolean
    return GetTriggerDamageType() == DAMAGE_TYPE_ATTACK and Flag[H2I(GetTriggerDamageSource())-MIN_HANDLE_ID] and GetUnitAbilityLevel(GetTriggerDamageSource(), 'A0MV') > 0 and not IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE)
endfunction

private function Actions takes nothing returns nothing
    local unit u = GetTriggerDamageSource()
    local unit t = GetTriggerDamageTarget()
    local integer lvl = GetUnitAbilityLevel(u, 'A0MV')
    local integer pr = GetTriggerPriority(GetTriggeringTrigger())
    local texttag te = CreateTextTag()
    local real d = GetTriggerDamage()
    local location HeroPoint = GetUnitLoc(u)
    local location TargetPoint = GetUnitLoc(t)
  
 //   if GetRandomInt(1, 100) <=  ( GetUnitAbilityLevelSwapped(('A0MV', u) * 5 ) + 0 ) then
//    if  GetRandomInt(1, 100) <= ( ( GetUnitAbilityLevelSwapped('A0MV', u) * 5 ) + 0 ) ) then
//    if ( GetRandomInt(1, 100) <= ( ( GetUnitAbilityLevelSwapped('A0MV', u) * 5 ) + 0 ) ) then
//        call KnockbackTarget(u, t, AngleBetweenPoints(HeroPoint, TargetPoint), 400.00, 100, true, true, false)
    if ( IsUnitEnemy(t, GetOwningPlayer(u)) == true ) then
        call KnockbackTarget(u, t, GetUnitFacing(u), 225.00, 300.00, true, true, false)
    endif
        //    call KnockbackTarget(u, t, a, 1200., 1600, true, true, false)
    //call KnockbackTarget(TargetUnit, AngleInDegrees, InitialSpeed, SpeedLossPerInterval, KillDestructables, KnockbackAdjacent, ChainAdjacent)
        call AddSpecialEffectLocBJ( HeroPoint, "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl" )
        call DestroyEffectBJ( GetLastCreatedEffectBJ() )
  
    //Deals +100%/200%/300%/etc damage
    call RemoveLocation(HeroPoint)
    call RemoveLocation(TargetPoint)
    set Flag[H2I(u)-MIN_HANDLE_ID] = false
    set te = null
    set u = null
    set t = null
    set HeroPoint = null
    set TargetPoint = null
endfunction

private function Atk_Conditions takes nothing returns boolean
    return GetUnitAbilityLevel(GetAttacker(), 'A0MV') > 0 and not IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE)
endfunction

private function Atk_Actions takes nothing returns nothing
    local unit u = GetAttacker()
    local unit t = GetAttackedUnitBJ()
    local location HeroPoint = GetUnitLoc(u)
    local location TargetPoint = GetUnitLoc(t)
  
 //   if GetRandomInt(1, 100) <= 100 then
 //   if GetRandomInt(1, 100) <=  ( GetUnitAbilityLevelSwapped(('A0MV', u) * 5 ) + 0 ) then
//    if  GetRandomInt(1, 100) <= ( ( GetUnitAbilityLevelSwapped('A0MV', u) * 5 ) + 0 ) ) then
    if ( GetRandomInt(1, 100) <= ( ( GetUnitAbilityLevelSwapped('A0MV', u) * 2 ) + 23 ) ) then
//        call KnockbackTarget(u, t, AngleBetweenPoints(HeroPoint, TargetPoint), 400.00, 100, true, true, false)
 //       call KnockbackTarget(u, t, GetUnitFacing(u), 700.00, 100, true, true, false)
//    call KnockbackTarget(u, t, a, 1200., 1600, true, true, false)
    //call KnockbackTarget(TargetUnit, AngleInDegrees, InitialSpeed, SpeedLossPerInterval, KillDestructables, KnockbackAdjacent, ChainAdjacent)
        if ( IsUnitEnemy(t, GetOwningPlayer(u)) == true ) then
            call KnockbackTarget(u, t, GetUnitFacing(u), 225.00, 300.00, true, true, false)
            call TriggerExecute( gg_trg_Knock_Back_AOE_Damage )
        endif
      
        call SetUnitAnimation(u, "attack slam")
        call QueueUnitAnimation(u, "stand ready")
    //    call AddSpecialEffectLocBJ( TargetPoint, "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl" )
     //   call DestroyEffectBJ( GetLastCreatedEffectBJ() )
        set Flag[H2I(u)-MIN_HANDLE_ID] = true
    else
        set Flag[H2I(u)-MIN_HANDLE_ID] = false
    endif
    call TriggerSleepAction( 0.01 )
    set u = null
    set t = null
    call RemoveLocation(HeroPoint)
    call RemoveLocation(TargetPoint)
    set HeroPoint = null
    set TargetPoint = null
endfunction

private function Init takes nothing returns nothing
    local trigger trg = CreateTrigger()
  
    call TriggerAddAction(trg, function Actions)
    call TriggerAddCondition(trg, Condition(function Conditions))
    call TriggerRegisterDamageEvent(trg, 1)
  
    set trg = CreateTrigger()
    call TriggerAddAction(trg, function Atk_Actions)
    call TriggerAddCondition(trg, Condition(function Atk_Conditions))
    call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_ATTACKED)
  
    set trg = null
endfunction
endscope

JASS:
scope WateryShieldEffectNew initializer Init
//globals
//    private constant integer MAX_HANDLE_NO = 8190
//   private constant integer MIN_HANDLE_ID = 0x100000
  
 //   private boolean array Flag[MAX_HANDLE_NO]
//endglobals

//private function H2I takes handle h returns integer
//    return GetHandleId(h)
//endfunction

private function Conditions takes nothing returns boolean
//    return GetTriggerDamageType() == DAMAGE_TYPE_ATTACK and Flag[H2I(GetTriggerDamageSource())-MIN_HANDLE_ID])// and if ( UnitHasBuffBJ(GetTriggerUnit(), 'B02G') == true ) and if ( I2R(GetUnitUserData(GetTriggerUnit())) > 0.00 ) == true ) )
    local real d = GetTriggerDamage()
    if ( not ( UnitHasBuffBJ(GetTriggerUnit(), 'B05C') == true ) ) then
        return false
    endif

    if ( not ( d > 0.00 ) ) then
        return false
    endif
    return true
    //    return GetTriggerDamageType() == DAMAGE_TYPE_ATTACK and Flag[H2I(GetTriggerDamageSource())-MIN_HANDLE_ID] and GetUnitAbilityLevel(GetTriggerDamageSource(), 'AOcr') > 0)
endfunction

private function Actions takes nothing returns nothing
    local unit u = GetTriggerDamageSource()
    local unit t = GetTriggerDamageTarget()
//    local integer lvl = GetUnitAbilityLevel(u, 'AOcr')
    local integer pr = GetTriggerPriority(GetTriggeringTrigger())
    local texttag te = CreateTextTag()
    local real d = GetTriggerDamage()
    local real Heal = GetHeroStatBJ(bj_HEROSTAT_INT, udg_Naga_WaterShield_Caster, true) * GetUnitAbilityLevelSwapped('A0N8', udg_Naga_WaterShield_Caster)
    local location WaterShieldPoint
    local location WaterShieldPoint2
    local location WaterShieldPoint3
    local integer HealText = R2I(Heal)
    //damage prevent locals
  //  local real    dmg = GetTriggerDamage()
 //   local integer in  = WateryShieldEffectNew_I //SampleFlame_I
//    local integer i   = 0
    //damage prevent locals
    if ( d >= 1.00 ) then
        set WaterShieldPoint = GetUnitLoc(t)
        set WaterShieldPoint2 = GetUnitLoc(u)
        set WaterShieldPoint3 = PolarProjectionBJ(WaterShieldPoint, 30.00, AngleBetweenPoints(WaterShieldPoint, WaterShieldPoint2))
        call CreateNUnitsAtLocFacingLocBJ( 1, 'h01Y', GetOwningPlayer(t), WaterShieldPoint3, WaterShieldPoint2 )
        call UnitApplyTimedLifeBJ( 1.00, 'BTLF', GetLastCreatedUnit() )
        call CreateNUnitsAtLocFacingLocBJ( 1, 'h01Y', GetOwningPlayer(t), WaterShieldPoint3, WaterShieldPoint2 )
        call UnitApplyTimedLifeBJ( 1.00, 'BTLF', GetLastCreatedUnit() )
      
        call SetUnitLifeBJ( t, ( GetUnitStateSwap(UNIT_STATE_LIFE, t) + ( Heal ) ) )

        set WaterShieldPoint = GetUnitLoc(t)
        call CreateTextTagLocBJ( ( I2S(HealText) ), WaterShieldPoint, 0, 10, 20.00, 20.00, 100, 0 )
        set udg_NagaSorc_Heal_Text = GetLastCreatedTextTag()
        call SetTextTagPermanentBJ( udg_NagaSorc_Heal_Text, false )
        call SetTextTagLifespanBJ( udg_NagaSorc_Heal_Text, 1.00 )
        call SetTextTagFadepointBJ( udg_NagaSorc_Heal_Text, 1.50 )
        call SetTextTagVelocityBJ( udg_NagaSorc_Heal_Text, 80.00, 90 )
      
        call RemoveLocation(WaterShieldPoint)
        call RemoveLocation(WaterShieldPoint2)
        call RemoveLocation(WaterShieldPoint3)
    else
    endif

    set te = null
    set u = null
    set t = null
    set WaterShieldPoint = null
    set WaterShieldPoint2 = null
    set WaterShieldPoint3 = null
    set Heal = 0
    set HealText = 0
    set udg_NagaSorc_Heal_Text = null
endfunction

private function Init takes nothing returns nothing
    local trigger trg = CreateTrigger()
  
    call TriggerAddAction(trg, function Actions)
    call TriggerAddCondition(trg, Condition(function Conditions))
    call TriggerRegisterDamageEvent(trg, 3) // Priority set to 3, so it activates later
  
    set trg = CreateTrigger()
    set trg = null
endfunction
endscope
 
Last edited:

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,546
That's not a memory leak, you aren't even running the code yet at the time of saving. Memory leaks would happen in-game and pile up over time causing slow down but really should never cause a crash.

I'm no expert but this looks like the issue:
vJASS:
scope GreaterBashNew initializer Init
globals
    private constant integer MAX_HANDLE_NO = 8190
    private constant integer MIN_HANDLE_ID = 0x100000
 
    private boolean array Flag[MAX_HANDLE_NO]
endglobals
You could try deleting those two HANDLE variables and change the code to use the unit's custom value instead:
vJASS:
set Flag[GetUnitUserData(u)] = true
vJASS:
set Flag[GetUnitUserData(u)] = false
vJASS:
return GetTriggerDamageType() == DAMAGE_TYPE_ATTACK and Flag[GetUnitUserData(GetTriggerDamageSource())] and GetUnitAbilityLevel(GetTriggerDamageSource(), 'A0MV') > 0 and not IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE)
This would require a Unit Indexer which you probably already have.
 
Top