• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Please help me detect what's the problem with this, I got no clues

Status
Not open for further replies.
Level 10
Joined
May 24, 2016
Messages
339
The thing is, when u kill a neutral and random chance is triggered, the system detect random hero in radius 300 to create and give him a random item from the item pool. If hero is not around, then system detect a nearesnt hero in 800 radius to give him item.
JASS:
globals
integer array indext
integer PaladinsChanceGetItem = 7
group P = CreateGroup()
integer I
integer I2
unit F
integer PalItemCounter = 0
boolean array PalItem[9] // I declared at the start trigger that all 9 booleans are false
integer PalItemsMaxCount = 9
group Paladins = CreateGroup() // I added all heroes into that group and never removing them from it... probably
endglobals




function FDFD takes unit u,unit u2 returns real
local real dx = GetUnitX(u2)-GetUnitX(u)
local real dy = GetUnitY(u2)-GetUnitY(u)
return SquareRoot(dx*dx+dy*dy)
endfunction


function GetClosest takes unit h,group g,real c returns unit
local unit tmp = null
local unit u = null
local real d = 0.
call GroupClear(P2)
set bj_groupAddGroupDest = P2
call ForGroup(g,function GroupAddGroupEnumJ)
loop
set tmp = FirstOfGroup(P2)
if tmp != null then
set d = FDFD(h,tmp)
if d < c then
set c = d
set u = tmp
endif
endif
call GroupRemoveUnit(P2,tmp)
exitwhen tmp == null
endloop
return u
endfunction


function GroupCallback takes nothing returns nothing
    set indext = indext + 1
    set units[indext] = GetEnumUnit()
endfunction

function GroupPickRandomUnitEx takes group g returns unit // this function was used before, I switched to GetRandomSubGroupEnumJ way but didnt help
    set indext = 0
    call ForGroup(g, function GroupCallback)
    return units[GetRandomInt(1, indext)]
endfunction


function GetRandomSubGroupEnumJ takes nothing returns nothing
    if (bj_randomSubGroupWant > 0) then
        if (bj_randomSubGroupWant >= bj_randomSubGroupTotal) or (GetRandomReal(0,1) < bj_randomSubGroupChance) then
            // We either need every remaining unit, or the unit passed its chance check.
            call GroupAddUnit(bj_randomSubGroupGroup, GetEnumUnit())
            set bj_randomSubGroupWant = bj_randomSubGroupWant - 1
        endif
    endif
    set bj_randomSubGroupTotal = bj_randomSubGroupTotal - 1
endfunction



function GetRandomSubGroupJ takes integer count, group sourceGroup returns group
    local group g = CreateGroup()

    set bj_randomSubGroupGroup = g
    set bj_randomSubGroupWant  = count
    set bj_randomSubGroupTotal = CountUnitsInGroupJ(sourceGroup)

    if (bj_randomSubGroupWant <= 0 or bj_randomSubGroupTotal <= 0) then
        return g
    endif

    set bj_randomSubGroupChance = I2R(bj_randomSubGroupWant) / I2R(bj_randomSubGroupTotal)
    call ForGroup(sourceGroup, function GetRandomSubGroupEnumJ)
    return g
endfunction

// function UnitDies with d = Dying unit, boolean boal, group g2
if (GetOwningPlayer(d) == Player(12) or GetOwningPlayer(d) == Player(4))  // player 4 is a neutral units clan
if PaladinsChanceGetItem >= GetRandomInt(0,100) and PalItemCounter < PalItemsMaxCount // we can crash this game if we would not detect if items are all used already

set B = Condition(function Paladins_Filter)
call GroupClear(P)
call GroupEnumUnitsInRange(P,GetUnitX(d),GetUnitY(d),300,B)
//call GroupClear(P2)
set g2 = GetRandomSubGroupJ(1,P)
//set F = //  GroupPickRandomUnitEx(P) // I used this function before GetRandomSubGroupJ. I thought maybe it d help, but it didnt help me since GetRandomSubGroupBJ is blizzard //original way to pcik random unit.
set F = FirstOfGroup(g2)
//call echo(GetUnitName(F))
call DestroyGroup(g2)
if F == null then
call DestroyBoolExpr(B)

set B = Condition(function Paladins_Filter)
call GroupClear(P)
call GroupEnumUnitsInRange(P,GetUnitX(d),GetUnitY(d),800,B)
//call DestroyBoolExpr(B)
set F = GetClosest(d,P,800)
endif
call DestroyBoolExpr(B)
if CountUnitsInGroupJ(P) > 0  and F != null then
set PaladinsChanceGetItem = 0
PalItemCounter++
//set I2 = 0

set Bol = false
loop
set I = GetRandomInt(1,9)
exitwhen Bol == true //or I2 > 40

if I == 1 and not PalItem[1]
set I2 = 'tels'
set PalItem[1] = true
set Bol = true
elseif I == 2 and not PalItem[2]
set I2 = 'rnsp'
set PalItem[2] = true
set Bol = true
elseif I == 3 and not PalItem[3]
set I2 = 'shhn'
set PalItem[3] = true
set Bol = true
elseif I == 4 and not PalItem[4]
set I2 = 'srtl'
set PalItem[4] = true
set Bol = true
elseif I == 5 and not PalItem[5]
set I2 = 'rat3'
set PalItem[5] = true
set Bol = true
elseif I == 6 and not PalItem[6]
set I2 = 'schl'
set PalItem[6] = true
set Bol = true
elseif I == 7 and not PalItem[7]
set I2 = 'anfg'
set PalItem[7] = true
set Bol = true
elseif I == 8 and not PalItem[8]
set I2 = 'lnrn'
set PalItem[8] = true
set Bol = true
elseif I == 9 and not PalItem[9]
set I2 = 'dtsb'
set PalItem[9] = true
set Bol = true
endif
//I2++
endloop

set bj_lastCreatedItem = CreateItem(I2, GetUnitX(F), GetUnitY(F))
call UnitAddItem(F, bj_lastCreatedItem)


endif

else
PaladinsChanceGetItem++
endif

endif
Somehow it triggers a constant lags every second, making the whole game annoying to play
 
Last edited:
Level 45
Joined
Feb 27, 2007
Messages
5,578
Please for everyone's sake learn to indent your code. This is very difficult to read because you've excerpted part of a larger function and didn't bother to indent it properly. For anyone else who comes to look at this, here you go:
JASS:
function FDFD takes unit u,unit u2 returns real
  local real dx = GetUnitX(u2)-GetUnitX(u)
  local real dy = GetUnitY(u2)-GetUnitY(u)
  return SquareRoot(dx*dx+dy*dy)
endfunction

function GetClosest takes unit h,group g,real c returns unit
  local unit tmp = null
  local unit u = null
  local real d = 0.
  call GroupClear(P2)
  set bj_groupAddGroupDest = P2
  call ForGroup(g,function GroupAddGroupEnumJ)
  loop
    set tmp = FirstOfGroup(P2)
    if tmp != null then
      set d = FDFD(h,tmp)
      if d < c then
        set c = d
        set u = tmp
      endif
    endif
    call GroupRemoveUnit(P2,tmp)
    exitwhen tmp == null
  endloop
  return u
endfunction

function GroupCallback takes nothing returns nothing
    set indext = indext + 1
    set units[indext] = GetEnumUnit()
endfunction

function GroupPickRandomUnitEx takes group g returns unit // this function was used before, I switched to GetRandomSubGroupEnumJ way but didnt help
    set indext = 0
    call ForGroup(g, function GroupCallback)
    return units[GetRandomInt(1, indext)]
endfunction


function GetRandomSubGroupEnumJ takes nothing returns nothing
    if (bj_randomSubGroupWant > 0) then
        if (bj_randomSubGroupWant >= bj_randomSubGroupTotal) or (GetRandomReal(0,1) < bj_randomSubGroupChance) then
            // We either need every remaining unit, or the unit passed its chance check.
            call GroupAddUnit(bj_randomSubGroupGroup, GetEnumUnit())
            set bj_randomSubGroupWant = bj_randomSubGroupWant - 1
        endif
    endif
    set bj_randomSubGroupTotal = bj_randomSubGroupTotal - 1
endfunction



function GetRandomSubGroupJ takes integer count, group sourceGroup returns group
    local group g = CreateGroup()

    set bj_randomSubGroupGroup = g
    set bj_randomSubGroupWant  = count
    set bj_randomSubGroupTotal = CountUnitsInGroupJ(sourceGroup)

    if (bj_randomSubGroupWant <= 0 or bj_randomSubGroupTotal <= 0) then
        return g
    endif

    set bj_randomSubGroupChance = I2R(bj_randomSubGroupWant) / I2R(bj_randomSubGroupTotal)
    call ForGroup(sourceGroup, function GetRandomSubGroupEnumJ)
    return g
endfunction


// function UnitDies with d = Dying unit, boolean boal, group g2
if (GetOwningPlayer(d) == Player(12) or GetOwningPlayer(d) == Player(4))  // player 4 is a neutral units clan
  if PaladinsChanceGetItem >= GetRandomInt(0,100) and PalItemCounter < PalItemsMaxCount // we can crash this game if we would not detect if items are all used already

    set B = Condition(function Paladins_Filter)
    call GroupClear(P)
    call GroupEnumUnitsInRange(P,GetUnitX(d),GetUnitY(d),300,B)
    //call GroupClear(P2)
    set g2 = GetRandomSubGroupJ(1,P)
    //set F = //  GroupPickRandomUnitEx(P) // I used this function before GetRandomSubGroupJ. I thought maybe it d help, but it didnt help me since GetRandomSubGroupBJ is blizzard //original way to pcik random unit.
    set F = FirstOfGroup(g2)
    //call echo(GetUnitName(F))
    call DestroyGroup(g2)
    
    if F == null then
      call DestroyBoolExpr(B)

      set B = Condition(function Paladins_Filter)
      call GroupClear(P)
      call GroupEnumUnitsInRange(P,GetUnitX(d),GetUnitY(d),800,B)
      //call DestroyBoolExpr(B)
      set F = GetClosest(d,P,800)
    endif
    
    call DestroyBoolExpr(B)
    
    if CountUnitsInGroupJ(P) > 0  and F != null then
      set PaladinsChanceGetItem = 0
      PalItemCounter++
      //set I2 = 0

      set Bol = false
      loop
        set I = GetRandomInt(1,9)
        exitwhen Bol == true //or I2 > 40

        if I == 1 and not PalItem[1]
          set I2 = 'tels'
          set PalItem[1] = true
          set Bol = true
        elseif I == 2 and not PalItem[2]
          set I2 = 'rnsp'
          set PalItem[2] = true
          set Bol = true
        elseif I == 3 and not PalItem[3]
          set I2 = 'shhn'
          set PalItem[3] = true
          set Bol = true
        elseif I == 4 and not PalItem[4]
          set I2 = 'srtl'
          set PalItem[4] = true
          set Bol = true
        elseif I == 5 and not PalItem[5]
          set I2 = 'rat3'
          set PalItem[5] = true
          set Bol = true
        elseif I == 6 and not PalItem[6]
          set I2 = 'schl'
          set PalItem[6] = true
          set Bol = true
        elseif I == 7 and not PalItem[7]
          set I2 = 'anfg'
          set PalItem[7] = true
          set Bol = true
        elseif I == 8 and not PalItem[8]
          set I2 = 'lnrn'
          set PalItem[8] = true
          set Bol = true
        elseif I == 9 and not PalItem[9]
          set I2 = 'dtsb'
          set PalItem[9] = true
          set Bol = true
        endif
        //I2++
      endloop

      set bj_lastCreatedItem = CreateItem(I2, GetUnitX(F), GetUnitY(F))
      call UnitAddItem(F, bj_lastCreatedItem)
    endif

  else
    PaladinsChanceGetItem++
  endif

endif
I don't see where you're looping infinitely, though in general the way you've done the item-giving loop is not good. As long as all 9 items are not in existence that loop will eventually exit, though as the number of items gets higher so too does the chance that it loops for a very long time until it randomizes one of the remaining acceptable numbers.

Put in some more debug messages and see just how many times the loop is running. Check other parts of the trigger to make sure there isn't something recursive with another trigger/bit of code.
 
Level 10
Joined
May 24, 2016
Messages
339
Please for everyone's sake learn to indent your code. This is very difficult to read because you've excerpted part of a larger function and didn't bother to indent it properly. For anyone else who comes to look at this, here you go:
JASS:
function FDFD takes unit u,unit u2 returns real
  local real dx = GetUnitX(u2)-GetUnitX(u)
  local real dy = GetUnitY(u2)-GetUnitY(u)
  return SquareRoot(dx*dx+dy*dy)
endfunction

function GetClosest takes unit h,group g,real c returns unit
  local unit tmp = null
  local unit u = null
  local real d = 0.
  call GroupClear(P2)
  set bj_groupAddGroupDest = P2
  call ForGroup(g,function GroupAddGroupEnumJ)
  loop
    set tmp = FirstOfGroup(P2)
    if tmp != null then
      set d = FDFD(h,tmp)
      if d < c then
        set c = d
        set u = tmp
      endif
    endif
    call GroupRemoveUnit(P2,tmp)
    exitwhen tmp == null
  endloop
  return u
endfunction

function GroupCallback takes nothing returns nothing
    set indext = indext + 1
    set units[indext] = GetEnumUnit()
endfunction

function GroupPickRandomUnitEx takes group g returns unit // this function was used before, I switched to GetRandomSubGroupEnumJ way but didnt help
    set indext = 0
    call ForGroup(g, function GroupCallback)
    return units[GetRandomInt(1, indext)]
endfunction


function GetRandomSubGroupEnumJ takes nothing returns nothing
    if (bj_randomSubGroupWant > 0) then
        if (bj_randomSubGroupWant >= bj_randomSubGroupTotal) or (GetRandomReal(0,1) < bj_randomSubGroupChance) then
            // We either need every remaining unit, or the unit passed its chance check.
            call GroupAddUnit(bj_randomSubGroupGroup, GetEnumUnit())
            set bj_randomSubGroupWant = bj_randomSubGroupWant - 1
        endif
    endif
    set bj_randomSubGroupTotal = bj_randomSubGroupTotal - 1
endfunction



function GetRandomSubGroupJ takes integer count, group sourceGroup returns group
    local group g = CreateGroup()

    set bj_randomSubGroupGroup = g
    set bj_randomSubGroupWant  = count
    set bj_randomSubGroupTotal = CountUnitsInGroupJ(sourceGroup)

    if (bj_randomSubGroupWant <= 0 or bj_randomSubGroupTotal <= 0) then
        return g
    endif

    set bj_randomSubGroupChance = I2R(bj_randomSubGroupWant) / I2R(bj_randomSubGroupTotal)
    call ForGroup(sourceGroup, function GetRandomSubGroupEnumJ)
    return g
endfunction


// function UnitDies with d = Dying unit, boolean boal, group g2
if (GetOwningPlayer(d) == Player(12) or GetOwningPlayer(d) == Player(4))  // player 4 is a neutral units clan
  if PaladinsChanceGetItem >= GetRandomInt(0,100) and PalItemCounter < PalItemsMaxCount // we can crash this game if we would not detect if items are all used already

    set B = Condition(function Paladins_Filter)
    call GroupClear(P)
    call GroupEnumUnitsInRange(P,GetUnitX(d),GetUnitY(d),300,B)
    //call GroupClear(P2)
    set g2 = GetRandomSubGroupJ(1,P)
    //set F = //  GroupPickRandomUnitEx(P) // I used this function before GetRandomSubGroupJ. I thought maybe it d help, but it didnt help me since GetRandomSubGroupBJ is blizzard //original way to pcik random unit.
    set F = FirstOfGroup(g2)
    //call echo(GetUnitName(F))
    call DestroyGroup(g2)
 
    if F == null then
      call DestroyBoolExpr(B)

      set B = Condition(function Paladins_Filter)
      call GroupClear(P)
      call GroupEnumUnitsInRange(P,GetUnitX(d),GetUnitY(d),800,B)
      //call DestroyBoolExpr(B)
      set F = GetClosest(d,P,800)
    endif
 
    call DestroyBoolExpr(B)
 
    if CountUnitsInGroupJ(P) > 0  and F != null then
      set PaladinsChanceGetItem = 0
      PalItemCounter++
      //set I2 = 0

      set Bol = false
      loop
        set I = GetRandomInt(1,9)
        exitwhen Bol == true //or I2 > 40

        if I == 1 and not PalItem[1]
          set I2 = 'tels'
          set PalItem[1] = true
          set Bol = true
        elseif I == 2 and not PalItem[2]
          set I2 = 'rnsp'
          set PalItem[2] = true
          set Bol = true
        elseif I == 3 and not PalItem[3]
          set I2 = 'shhn'
          set PalItem[3] = true
          set Bol = true
        elseif I == 4 and not PalItem[4]
          set I2 = 'srtl'
          set PalItem[4] = true
          set Bol = true
        elseif I == 5 and not PalItem[5]
          set I2 = 'rat3'
          set PalItem[5] = true
          set Bol = true
        elseif I == 6 and not PalItem[6]
          set I2 = 'schl'
          set PalItem[6] = true
          set Bol = true
        elseif I == 7 and not PalItem[7]
          set I2 = 'anfg'
          set PalItem[7] = true
          set Bol = true
        elseif I == 8 and not PalItem[8]
          set I2 = 'lnrn'
          set PalItem[8] = true
          set Bol = true
        elseif I == 9 and not PalItem[9]
          set I2 = 'dtsb'
          set PalItem[9] = true
          set Bol = true
        endif
        //I2++
      endloop

      set bj_lastCreatedItem = CreateItem(I2, GetUnitX(F), GetUnitY(F))
      call UnitAddItem(F, bj_lastCreatedItem)
    endif

  else
    PaladinsChanceGetItem++
  endif

endif
I don't see where you're looping infinitely, though in general the way you've done the item-giving loop is not good. As long as all 9 items are not in existence that loop will eventually exit, though as the number of items gets higher so too does the chance that it loops for a very long time until it randomizes one of the remaining acceptable numbers.

Put in some more debug messages and see just how many times the loop is running. Check other parts of the trigger to make sure there isn't something recursive with another trigger/bit of code.
UPDATE: I found out why lags are happening. It somehow related with Escort v1.0 escort system I'm using. The topic is closed, thx for helping.
 
Last edited:
Status
Not open for further replies.
Top