• 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.

[JASS] disease system

Status
Not open for further replies.

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
Hi,

this is a system to check if a unit on the map area is diseased,
if so it check if there are unit near the diseased unit (300 range)
then it check if those unit are allready diseased or not.
if not there is 4% chance that the disease will be infecting the nearby unit.

it use 2 group unit without filter, i don't know if using filter is better or not,
i think the code can be improved a lot.
[Jass=]
function Disease_malaria takes nothing returns nothing
local group g
local group g1
local unit u
local unit u1
local unit dummy
local real x
local real y
set g = CreateGroup()
call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, null)
loop
set u = FirstOfGroup(g)
set x = GetUnitX(u)
set y = GetUnitY(u)
exitwhen u == null
if GetUnitAbilityLevel(u, 'B00I') > 0 then
call SetUnitState( u, UNIT_STATE_MANA, ( GetUnitState( u, UNIT_STATE_MANA ) - 10.00 ))
call SetUnitState( u, UNIT_STATE_LIFE, ( GetUnitState( u, UNIT_STATE_LIFE ) - 10.00 ))
set g1 = CreateGroup()
call GroupEnumUnitsInRange(g1, x, y, 300.00, null)
loop
set u1 = FirstOfGroup(g1)
exitwhen u1 == null
if not GetUnitAbilityLevel(u, 'B00I') > 0 then
if GetRandomInt(1, 50) <= 2 then
set x = GetUnitX(u1)
set y = GetUnitY(u1)
set dummy = CreateUnit( Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x, y, bj_UNIT_FACING )
call UnitAddAbility( dummy, 'ANdh' )
call IssueTargetOrder( dummy, "drunkenhaze", u1 )
endif
endif
call GroupRemoveUnit(g1, u1)
endloop
call DestroyGroup(g1)
set g1 = null
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set g = null
endfunction

//===========================================================================
function InitTrig_Disease_malaria takes nothing returns nothing
set gg_trg_Disease_malaria = CreateTrigger( )
call TriggerAddAction( gg_trg_Disease_malaria, function Disease_malaria )
endfunction
[/code]

the function is linked to a periodic event trigger wich run this function every 3 sec.
 
Take a look at this - http://www.hiveworkshop.com/forums/...on-using-first-group-loop-enumeration-223140/

Use a global static group and you never have to create/destroy.

Also:

set dummy = CreateUnit( Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x, y,bj_UNIT_FACING )
call UnitAddAbility( dummy, 'ANdh' )
call IssueTargetOrder( dummy, "drunkenhaze", u1 )

leaks a unit unless you've killed it with object data. There's a way to use a static dummy but that can wait.
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
hum are you suggesting something like this?
[Jass=]
scope Malaria initializer i
globals
private group grp=CreateGroup()
endglobals

private function i takes real x, real y returns nothing
local unit u1=null
local real x1
local real y1
call GroupEnumUnitsInRange(grp,x,y,300.,null)
loop
set u1=FirstOfGroup(grp)
exitwhen u1==null
if not GetUnitAbilityLevel(u1, 'B00I') > 0 then
if GetRandomInt(1, 50) <= 2 then
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
set dummy = CreateUnit( Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x1, y1, bj_UNIT_FACING )
call UnitAddAbility( dummy, 'ANdh' )
call IssueTargetOrder( dummy, "drunkenhaze", u1 )
endif
endif
call GroupRemoveUnit(grp,u1)
endloop
endfunction
endscope
[/code]


[Jass=]
function Disease_malaria takes nothing returns nothing
local group g
local group g1
local unit u
local unit u1
local unit dummy
local real x
local real y
set g = CreateGroup()
call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, null)
loop
set u = FirstOfGroup(g)
set x = GetUnitX(u)
set y = GetUnitY(u)
exitwhen u == null
if GetUnitAbilityLevel(u, 'B00I') > 0 then
if not IsUnitType(u, UNIT_TYPE_HERO) then
call SetUnitState( u, UNIT_STATE_MANA, ( GetUnitState( u, UNIT_STATE_MANA ) - 3.00 ))
call SetUnitState( u, UNIT_STATE_LIFE, ( GetUnitState( u, UNIT_STATE_LIFE ) - 3.00 ))
endif
call Malaria_i(x,y)
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set g = null
endfunction

//===========================================================================
function InitTrig_Disease_malaria takes nothing returns nothing
set gg_trg_Disease_malaria = CreateTrigger( )
call TriggerAddAction( gg_trg_Disease_malaria, function Disease_malaria )
endfunction
[/code]

About the dummy unit. it has a 2 sec life span (2 hp with -1 hp regen), it does not decay and does not revive, and it is removed upon death from game by a unit die event trigger.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
Malaria_i will not compile I think because its private, give it public modifier and it should work just normally
and why is Malaria_i initializer actually? it has nothing that should be run while map is loading or am I wrong?

because you are using vJass, you dont need InitTrig_Disease_malaria anymore as it serves no purpose

and when it comes to it, you could just past the Malaria_i part from the if block to the Disease_malaria and you dont need to even have that function anymore(calling function is always slower than using Natives)
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
i don't really follow...

how does calling a scope function make my function Disease malaria a vjass function?
and how would the function exist without the create trigger and init trigger?

about the malaria scope...i don't really understand how to use it.
Cokemonkey11 showed a link to a tutorial.
so i tried to use the tutorial scope to put into pratice on my disease malaria function....

was the function better the first time at the beginning of this thread.?
or is it better to use scope and globals?


EDIT
is it something like this ?
[Jass=]
scope Disease
globals
private group g1=CreateGroup()
private group g2=CreateGroup()
endglobals

public function malaria takes nothing returns nothing
local unit u1=null
local unit u2=null
local unit dummy
local real x1
local real x2
local real y1
local real y2
call GroupEnumUnitsInRect(g1, bj_mapInitialPlayableArea, null)
loop
set u1 = FirstOfGroup(g1)
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
exitwhen u1 == null
if GetUnitAbilityLevel(u1, 'B00I') > 0 then
if not IsUnitType(u1, UNIT_TYPE_HERO) then
call SetUnitState( u1, UNIT_STATE_MANA, ( GetUnitState( u1, UNIT_STATE_MANA ) - 3.00 ))
call SetUnitState( u1, UNIT_STATE_LIFE, ( GetUnitState( u1, UNIT_STATE_LIFE ) - 3.00 ))
endif
call GroupEnumUnitsInRange(g2,x1,y1,300.,null)
loop
set u2=FirstOfGroup(g2)
exitwhen u2==null
if not GetUnitAbilityLevel(u2, 'B00I') > 0 then
if GetRandomInt(1, 50) <= 2 then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
set dummy = CreateUnit( Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x2, y2, bj_UNIT_FACING )
call UnitAddAbility( dummy, 'ANdh' )
call IssueTargetOrder( dummy, "drunkenhaze", u2 )
endif
endif
call GroupRemoveUnit(g2,u2)
endloop
endif
call GroupRemoveUnit(g1, u1)
endloop
endfunction
endscope
[/code]

is it ok without initializer?
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
if a function is private, if you try to call it from outside of the scope(either struct, library or scope itself) should pop error that either the function doesnt exists or it is private

I mean, the trigger you have it there right now only runs the function once when map loads which is useless I would say, just use scope and initializer
by the way why dont you put it to the same scope?
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
so is this good?

[Jass=]
scope Disease
globals
private group g1=CreateGroup()
private group g2=CreateGroup()
endglobals

public function malaria takes nothing returns nothing
local unit u1=null
local unit u2=null
local unit dummy
local real x1
local real x2
local real y1
local real y2
call GroupEnumUnitsInRect(g1, bj_mapInitialPlayableArea, null)
loop
set u1 = FirstOfGroup(g1)
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
exitwhen u1 == null
if GetUnitAbilityLevel(u1, 'B00I') > 0 then
if not IsUnitType(u1, UNIT_TYPE_HERO) then
call SetUnitState( u1, UNIT_STATE_MANA, ( GetUnitState( u1, UNIT_STATE_MANA ) - 3.00 ))
call SetUnitState( u1, UNIT_STATE_LIFE, ( GetUnitState( u1, UNIT_STATE_LIFE ) - 3.00 ))
endif
call GroupEnumUnitsInRange(g2,x1,y1,300.,null)
loop
set u2=FirstOfGroup(g2)
exitwhen u2==null
if not GetUnitAbilityLevel(u2, 'B00I') > 0 then
if GetRandomInt(1, 50) <= 2 then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
set dummy = CreateUnit( Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x2, y2, bj_UNIT_FACING )
call UnitAddAbility( dummy, 'ANdh' )
call IssueTargetOrder( dummy, "drunkenhaze", u2 )
endif
endif
call GroupRemoveUnit(g2,u2)
endloop
endif
call GroupRemoveUnit(g1, u1)
endloop
endfunction

public function plague takes nothing returns nothing
local unit u1=null
local unit u2=null
local unit dummy
local real x1
local real x2
local real y1
local real y2
call GroupEnumUnitsInRect(g1, bj_mapInitialPlayableArea, null)
loop
set u1 = FirstOfGroup(g1)
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
exitwhen u1 == null
if GetUnitAbilityLevel(u1, 'B00H') > 0 then
if not IsUnitType(u1, UNIT_TYPE_HERO) then
call SetUnitState( u1, UNIT_STATE_MANA, ( GetUnitState( u1, UNIT_STATE_MANA ) - 3.00 ))
call SetUnitState( u1, UNIT_STATE_LIFE, ( GetUnitState( u1, UNIT_STATE_LIFE ) - 4.50 ))
endif
call GroupEnumUnitsInRange(g2,x1,y1,300.,null)
loop
set u2=FirstOfGroup(g2)
exitwhen u2==null
if not GetUnitAbilityLevel(u2, 'B00H') > 0 then
if GetRandomInt(1, 50) <= 2 then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
set dummy = CreateUnit( Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x2, y2, bj_UNIT_FACING )
call UnitAddAbility( dummy, 'ACif' )
call IssueTargetOrder( dummy, "innerfire", u2 )
endif
endif
call GroupRemoveUnit(g2,u2)
endloop
endif
call GroupRemoveUnit(g1, u1)
endloop
endfunction

public function fever takes nothing returns nothing
local unit u1=null
local unit u2=null
local unit dummy
local real x1
local real x2
local real y1
local real y2
call GroupEnumUnitsInRect(g1, bj_mapInitialPlayableArea, null)
loop
set u1 = FirstOfGroup(g1)
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
exitwhen u1 == null
if GetUnitAbilityLevel(u1, 'Brej') > 0 then
if not IsUnitType(u1, UNIT_TYPE_HERO) then
call SetUnitState( u1, UNIT_STATE_MANA, ( GetUnitState( u1, UNIT_STATE_MANA ) - 1.50 ))
call SetUnitState( u1, UNIT_STATE_LIFE, ( GetUnitState( u1, UNIT_STATE_LIFE ) - 6.00 ))
endif
call GroupEnumUnitsInRange(g2,x1,y1,300.,null)
loop
set u2=FirstOfGroup(g2)
exitwhen u2==null
if not GetUnitAbilityLevel(u2, 'Brej') > 0 then
if GetRandomInt(1, 50) <= 2 then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
set dummy = CreateUnit( Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x2, y2, bj_UNIT_FACING )
call UnitAddAbility( dummy, 'ACff' )
call IssueTargetOrder( dummy, "faeriefire", u2 )
endif
endif
call GroupRemoveUnit(g2,u2)
endloop
endif
call GroupRemoveUnit(g1, u1)
endloop
endfunction
endscope
[/code]

would use call Disease_malaria to do the malaria check and effect?
and call Disease_plague for plague
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
i don't need to specify the scope?
i intend to call from outside the scope.

trigger player timer-------------------
periodic event every 3 sec
call malaria()
call plague()
call fever()
do other action
call other triggers
--------------------------------------------------

is this correct? where ever the scope is placed, i can access it from any trigger just by using call 'name of function' inside scope...
what happen if i have more than 1 scope ? is it impossible for 2 scope to share same name function (if public that would bug right?)
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
[Jass=]
library Disease
globals
private group g1=CreateGroup()
private group g2=CreateGroup()
private group g3=CreateGroup()
endglobals

public function Malaria takes nothing returns nothing
local unit u1=null
local unit u2=null
local unit dummy
local real x1
local real x2
local real y1
local real y2
local integer res
local integer p
call GroupEnumUnitsInRect(g1, bj_mapInitialPlayableArea, null)
loop
set u1 = FirstOfGroup(g1)
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
exitwhen u1 == null
if GetUnitAbilityLevel(u1, 'B00I') > 0 then
if IsUnitType(u1, UNIT_TYPE_HERO) then
set p = GetPlayerId(GetOwningPlayer(u1)) + 1
set udg_MB_Malaria= "Yes"
if GetUnitState( udg_Hero_Troll, UNIT_STATE_LIFE) > 3.00 then
call SetUnitState( udg_Hero_Troll, UNIT_STATE_LIFE, ( GetUnitState( udg_Hero_Troll, UNIT_STATE_LIFE) - 3.00 ) )
else
call KillUnit( udg_Hero_Troll )
set udg_Die_Diseases = ( udg_Die_Diseases + 1 )
endif
if GetUnitAbilityLevel(udg_Hero_Troll, 'B00G') == 0 and GetUnitAbilityLevel(udg_Hero_Troll, 'BUst') == 0 then
call SetUnitState( udg_Hero_Troll, UNIT_STATE_MANA, ( GetUnitState( udg_Hero_Troll, UNIT_STATE_MANA) - 3.00 ) )
endif
call SetPlayerState( Player(p-1), PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState( Player(p-1), PLAYER_STATE_RESOURCE_LUMBER) + 1)
else
call SetUnitState( u1, UNIT_STATE_MANA, ( GetUnitState( u1, UNIT_STATE_MANA ) - 3.00 ))
call SetUnitState( u1, UNIT_STATE_LIFE, ( GetUnitState( u1, UNIT_STATE_LIFE ) - 3.00 ))
endif
call GroupEnumUnitsInRange(g2, x1, y1, 300.00, null)
loop
set u2 = FirstOfGroup(g2)
exitwhen u2 == null
if GetUnitAbilityLevel(u2, 'B00I') == 0 then
if IsUnitType(u2, UNIT_TYPE_HERO) then
set res = udg_DiseaseResist[GetPlayerId(GetOwningPlayer(u2)) + 1]
else
set res = 50
endif
if GetRandomInt(1, res) <= 2 then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
set dummy = CreateUnit( Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x2, y2, bj_UNIT_FACING )
call UnitAddAbility( dummy, 'ANdh' )
call IssueTargetOrder( dummy, "drunkenhaze", u2 )
endif
endif
call GroupRemoveUnit(g2, u2)
endloop
else
if IsUnitType(u1, UNIT_TYPE_HERO) then
set p = GetPlayerId(GetOwningPlayer(u1)) + 1
set udg_MB_Malaria= "No"
endif
endif
call GroupRemoveUnit(g1, u1)
endloop
endfunction

public function Plague takes nothing returns nothing
local unit u1=null
local unit u2=null
local unit dummy
local real x1
local real x2
local real y1
local real y2
local integer res
local integer p
call GroupEnumUnitsInRect(g1, bj_mapInitialPlayableArea, null)
loop
set u1 = FirstOfGroup(g1)
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
exitwhen u1 == null
if GetUnitAbilityLevel(u1, 'B00H') > 0 then
if IsUnitType(u1, UNIT_TYPE_HERO) then
set p = GetPlayerId(GetOwningPlayer(u1)) + 1
set udg_MB_Plague= "Yes"
if GetUnitState( udg_Hero_Troll, UNIT_STATE_LIFE) > 3.00 then
call SetUnitState( udg_Hero_Troll, UNIT_STATE_LIFE, ( GetUnitState( udg_Hero_Troll, UNIT_STATE_LIFE) - 3.00 ) )
else
call KillUnit( udg_Hero_Troll )
set udg_Die_Diseases = ( udg_Die_Diseases + 1 )
endif
if GetUnitAbilityLevel(udg_Hero_Troll, 'B00G') == 0 and GetUnitAbilityLevel(udg_Hero_Troll, 'BUst') == 0 then
call SetUnitState( udg_Hero_Troll, UNIT_STATE_MANA, ( GetUnitState( udg_Hero_Troll, UNIT_STATE_MANA) - 4.50 ) )
endif
else
call SetUnitState( u1, UNIT_STATE_MANA, ( GetUnitState( u1, UNIT_STATE_MANA ) - 3.00 ))
call SetUnitState( u1, UNIT_STATE_LIFE, ( GetUnitState( u1, UNIT_STATE_LIFE ) - 4.50 ))
endif
call GroupEnumUnitsInRange(g2, x1, y1, 300.00, null)
loop
set u1 = FirstOfGroup(g2)
exitwhen u2 == null
if GetUnitAbilityLevel(u2, 'B00H') == 0 then
if IsUnitType(u2, UNIT_TYPE_HERO) then
set res = udg_DiseaseResist[GetPlayerId(GetOwningPlayer(u2)) + 1]
else
set res = 50
endif
if GetRandomInt(1, res) <= 2 then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
set dummy = CreateUnit( Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x2, y2, bj_UNIT_FACING )
call UnitAddAbility( dummy, 'ACif' )
call IssueTargetOrder( dummy, "innerfire", u2 )
endif
endif
call GroupRemoveUnit(g2, u2)
endloop
else
if IsUnitType(u1, UNIT_TYPE_HERO) then
set p = GetPlayerId(GetOwningPlayer(u1)) + 1
set udg_MB_Plague= "No"
endif
endif
call GroupRemoveUnit(g1, u1)
endloop
endfunction

public function Fever takes nothing returns nothing
local unit u1=null
local unit u2=null
local unit u3=null
local unit dummy
local real x1
local real x2
local real y1
local real y2
local integer res
local integer p
call GroupEnumUnitsInRect(g1, bj_mapInitialPlayableArea, null)
loop
set u1 = FirstOfGroup(g1)
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
exitwhen u1 == null
if GetUnitAbilityLevel(u1, 'Brej') > 0 then
if IsUnitType(u1, UNIT_TYPE_HERO) then
set p = GetPlayerId( GetOwningPlayer(u1))
set udg_MB_Fever= "Yes"
call SetPlayerState( Player(p-1), PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState( Player(p-1), PLAYER_STATE_RESOURCE_LUMBER) + GetRandomInt(0, 2))
if GetUnitState( udg_Hero_Troll, UNIT_STATE_LIFE) > 1.50 then
call SetUnitState( udg_Hero_Troll, UNIT_STATE_LIFE, ( GetUnitState( udg_Hero_Troll, UNIT_STATE_LIFE) - 1.50 ) )
else
call KillUnit( udg_Hero_Troll )
set udg_Die_Diseases = ( udg_Die_Diseases + 1 )
endif
if GetUnitAbilityLevel(udg_Hero_Troll, 'B00G') == 0 and GetUnitAbilityLevel(udg_Hero_Troll, 'BUst') == 0 then
call SetUnitState( udg_Hero_Troll, UNIT_STATE_MANA, ( GetUnitState( udg_Hero_Troll, UNIT_STATE_MANA) - 6.00 ) )
if GetRandomInt(1, 10) == 1 then
call GroupEnumUnitsInRange(g3, x1, y1, 2000.00, null)
loop
set u3 = FirstOfGroup(g3)
exitwhen u3 == null
if IsUnitType(u3, UNIT_TYPE_HERO) then
call DisplayTimedTextToPlayer( GetOwningPlayer(u3), 0., 0., 6.00, ( "|c0000c400Troll " + ( GetPlayerName(GetOwningPlayer(u1)) + ":|r |c00ffff64AAaatcchhoo!|r" ) ) )
call PingMinimapForPlayer( GetOwningPlayer(u3), x1, y1, 3.00 )
endif
call GroupRemoveUnit(g3, u3)
endloop
endif
endif
else
call SetUnitState( u1, UNIT_STATE_MANA, ( GetUnitState( u1, UNIT_STATE_MANA ) - 1.50 ))
call SetUnitState( u1, UNIT_STATE_LIFE, ( GetUnitState( u1, UNIT_STATE_LIFE ) - 6.00 ))
endif
call GroupEnumUnitsInRange(g2, x1, y1, 300.00, null)
loop
set u2 = FirstOfGroup(g2)
exitwhen u2 == null
if GetUnitAbilityLevel(u2, 'Brej') == 0 then
if IsUnitType(u2, UNIT_TYPE_HERO) then
set res = udg_DiseaseResist[GetPlayerId(GetOwningPlayer(u2)) + 1]
else
set res = 50
endif
if GetRandomInt(1, res) <= 2 then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
set dummy = CreateUnit( Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x2, y2, bj_UNIT_FACING )
call UnitAddAbility( dummy, 'ACff' )
call IssueTargetOrder( dummy, "faeriefire", u2 )
endif
endif
call GroupRemoveUnit(g2, u2)
endloop
else
if IsUnitType(u1, UNIT_TYPE_HERO) then
set p = GetPlayerId(GetOwningPlayer(u1)) + 1
set udg_MB_Fever= "No"
endif
endif
call GroupRemoveUnit(g1, u1)
endloop
endfunction
endlibrary
[/code]
this doesn't want to compile...
it detect many error even line 1 is syntax error
and all public function show syntax error...???
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
i found out it was a udg_variable wich was bugging the library...
the only thing syntax check didn't notice...
all the other error were actually fake because it work fine.

Is there a way to improve the library?
[Jass=]
library Disease
globals
private group g1=CreateGroup()
private group g2=CreateGroup()
private group g3=CreateGroup()
endglobals

public function Malaria takes nothing returns nothing
local unit u1=null
local unit u2=null
local unit dummy=null
local real x1
local real x2
local real y1
local real y2
local integer res
local integer p
call GroupEnumUnitsInRect(g1, bj_mapInitialPlayableArea, null)
loop
set u1 = FirstOfGroup(g1)
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
exitwhen u1 == null
if GetUnitAbilityLevel(u1, 'B00I') > 0 then
if IsUnitType(u1, UNIT_TYPE_HERO) then
set p = GetPlayerId(GetOwningPlayer(u1)) + 1
set udg_MB_Malaria= "Yes"
call SetPlayerState(Player(p-1), PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState(Player(p-1), PLAYER_STATE_RESOURCE_LUMBER) + 1)
if GetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE) > 3.00 then
call SetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE, (GetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE) - 3.00 ) )
else
call KillUnit(udg_Hero_Troll)
set udg_Die_Diseases = udg_Die_Diseases + 1
endif
if GetUnitAbilityLevel(udg_Hero_Troll, 'B00G') == 0 and GetUnitAbilityLevel(udg_Hero_Troll, 'BUst') == 0 then
call SetUnitState(udg_Hero_Troll, UNIT_STATE_MANA, (GetUnitState(udg_Hero_Troll, UNIT_STATE_MANA) - 3.00 ) )
endif
else
call SetUnitState(u1, UNIT_STATE_LIFE, (GetUnitState(u1, UNIT_STATE_LIFE ) - 3.00 ))
call SetUnitState(u1, UNIT_STATE_MANA, (GetUnitState(u1, UNIT_STATE_MANA ) - 3.00 ))
endif
call GroupEnumUnitsInRange(g2, x1, y1, 300.00, null)
loop
set u2 = FirstOfGroup(g2)
exitwhen u2 == null
if GetUnitAbilityLevel(u2, 'B00I') == 0 then
if IsUnitType(u2, UNIT_TYPE_HERO) then
set res = udg_DiseaseResist[GetPlayerId(GetOwningPlayer(u2)) + 1]
else
set res = 50
endif
if GetRandomInt(1, res) <= 2 then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
set dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x2, y2, bj_UNIT_FACING)
call UnitAddAbility(dummy, 'ANdh')
call IssueTargetOrder(dummy, "drunkenhaze", u2)
endif
endif
call GroupRemoveUnit(g2, u2)
endloop
else
if IsUnitType(u1, UNIT_TYPE_HERO) then
set p = GetPlayerId(GetOwningPlayer(u1)) + 1
set udg_MB_Malaria= "No"
endif
endif
call GroupRemoveUnit(g1, u1)
endloop
endfunction

public function Plague takes nothing returns nothing
local unit u1=null
local unit u2=null
local unit dummy=null
local real x1
local real x2
local real y1
local real y2
local integer res
local integer p
call GroupEnumUnitsInRect(g1, bj_mapInitialPlayableArea, null)
loop
set u1 = FirstOfGroup(g1)
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
exitwhen u1 == null
if GetUnitAbilityLevel(u1, 'B00H') > 0 then
if IsUnitType(u1, UNIT_TYPE_HERO) then
set p = GetPlayerId(GetOwningPlayer(u1)) + 1
set udg_MB_Plague= "Yes"
if GetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE) > 3.00 then
call SetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE, (GetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE) - 3.00 ) )
else
call KillUnit(udg_Hero_Troll)
set udg_Die_Diseases = udg_Die_Diseases + 1
endif
if GetUnitAbilityLevel(udg_Hero_Troll, 'B00G') == 0 and GetUnitAbilityLevel(udg_Hero_Troll, 'BUst') == 0 then
call SetUnitState(udg_Hero_Troll, UNIT_STATE_MANA, (GetUnitState(udg_Hero_Troll, UNIT_STATE_MANA) - 4.50 ) )
endif
else
call SetUnitState(u1, UNIT_STATE_LIFE, (GetUnitState(u1, UNIT_STATE_LIFE) - 3.00 ))
call SetUnitState(u1, UNIT_STATE_MANA, (GetUnitState(u1, UNIT_STATE_MANA) - 4.50 ))
endif
call GroupEnumUnitsInRange(g2, x1, y1, 300.00, null)
loop
set u2 = FirstOfGroup(g2)
exitwhen u2 == null
if GetUnitAbilityLevel(u2, 'B00H') == 0 then
if IsUnitType(u2, UNIT_TYPE_HERO) then
set res = udg_DiseaseResist[GetPlayerId(GetOwningPlayer(u2)) + 1]
else
set res = 50
endif
if GetRandomInt(1, res) <= 2 then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
set dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x2, y2, bj_UNIT_FACING)
call UnitAddAbility(dummy, 'ACif')
call IssueTargetOrder(dummy, "innerfire", u2)
endif
endif
call GroupRemoveUnit(g2, u2)
endloop
else
if IsUnitType(u1, UNIT_TYPE_HERO) then
set p = GetPlayerId(GetOwningPlayer(u1)) + 1
set udg_MB_Plague= "No"
endif
endif
call GroupRemoveUnit(g1, u1)
endloop
endfunction

public function Fever takes nothing returns nothing
local unit u1=null
local unit u2=null
local unit u3=null
local unit dummy=null
local real x1
local real x2
local real y1
local real y2
local integer res
local integer p
call GroupEnumUnitsInRect(g1, bj_mapInitialPlayableArea, null)
loop
set u1 = FirstOfGroup(g1)
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
exitwhen u1 == null
if GetUnitAbilityLevel(u1, 'Brej') > 0 then
if IsUnitType(u1, UNIT_TYPE_HERO) then
set p = GetPlayerId( GetOwningPlayer(u1))
set udg_MB_Fever= "Yes"
call SetPlayerState(Player(p-1), PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState(Player(p-1), PLAYER_STATE_RESOURCE_LUMBER) + GetRandomInt(0, 2))
if GetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE) > 1.50 then
call SetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE, (GetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE) - 1.50 ) )
else
call KillUnit(udg_Hero_Troll)
set udg_Die_Diseases = udg_Die_Diseases + 1
endif
if GetUnitAbilityLevel(udg_Hero_Troll, 'B00G') == 0 and GetUnitAbilityLevel(udg_Hero_Troll, 'BUst') == 0 then
call SetUnitState(udg_Hero_Troll, UNIT_STATE_MANA, (GetUnitState(udg_Hero_Troll, UNIT_STATE_MANA) - 6.00 ) )
if GetRandomInt(1, 10) == 1 then
call GroupEnumUnitsInRange(g3, x1, y1, 2000.00, null)
loop
set u3 = FirstOfGroup(g3)
exitwhen u3 == null
if IsUnitType(u3, UNIT_TYPE_HERO) then
call DisplayTimedTextToPlayer(GetOwningPlayer(u3), 0., 0., 6.00, ( "|c0000c400Troll " + (GetPlayerName(GetOwningPlayer(u1)) + ":|r |c00ffff64AAaatcchhoo!|r" ) ) )
call PingMinimapForPlayer(GetOwningPlayer(u3), x1, y1, 3.00 )
endif
call GroupRemoveUnit(g3, u3)
endloop
endif
endif
else
call SetUnitState(u1, UNIT_STATE_LIFE, (GetUnitState(u1, UNIT_STATE_LIFE) - 1.50 ))
call SetUnitState(u1, UNIT_STATE_MANA, (GetUnitState(u1, UNIT_STATE_MANA) - 6.00 ))
endif
call GroupEnumUnitsInRange(g2, x1, y1, 300.00, null)
loop
set u2 = FirstOfGroup(g2)
exitwhen u2 == null
if GetUnitAbilityLevel(u2, 'Brej') == 0 then
if IsUnitType(u2, UNIT_TYPE_HERO) then
set res = udg_DiseaseResist[GetPlayerId(GetOwningPlayer(u2)) + 1]
else
set res = 50
endif
if GetRandomInt(1, res) <= 2 then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
set dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x2, y2, bj_UNIT_FACING)
call UnitAddAbility(dummy, 'ACff')
call IssueTargetOrder(dummy, "faeriefire", u2)
endif
endif
call GroupRemoveUnit(g2, u2)
endloop
else
if IsUnitType(u1, UNIT_TYPE_HERO) then
set p = GetPlayerId(GetOwningPlayer(u1)) + 1
set udg_MB_Fever= "No"
endif
endif
call GroupRemoveUnit(g1, u1)
endloop
endfunction
endlibrary
[/code]

because as now every 3 sec i do:
call Disease_Malaria()
call Disease_Plague()
call Disease_Fever()

so i each 3 sec take all unit in map (3 times) to check the buff and do the disease damage and spread infection...
i though about doing like this:
pick all unit in map group1
if buff1 then
do group2 (malaria)
if buff2 then
do group2 (plague)
if buff3 then
do group2 (fever)

since the first group do the same thing in all disease (pick all unit in map) i can merge them...
but the problem is if a unit has many buff disease what would happen?
because they are removed from group1 but is it after they are checked in every if then else....

the best would be to pick every unit in 300 of diseased unit only once and then do an infection check for all disease on the unit

EDIT
done, i finally called only 1 time group1 and 1 time group2 for all diseases
thanks for everyone help [Solved]
 
Last edited:
Is there a way to improve the library?

It's pretty solid now, but you could always improve it.

  • Declare arbitrary values like 300. and 'B00I' as constants to improve readability.
  • Comment your code - especially before the library and functions as explanation of what they do.
  • Didn't look in too much detail, but since g3 is not nested in g2, you can re-use g2. What I'm trying to say is you only need 2 static groups here.
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
i don't really understand the concept of global and constant in Jass...
but since i have in this library
g1 and g2 and g3 as globals
it means that i am not allowed to use g1,g2,g3 as group in other triggers?
constant mean that it is a private global so it doesn't change right?

about g3, i didn't use it like this at first...
but since the modification it is true i could remove it and use g2
here is the lastest configuration:

[Jass=]
library Disease
globals
private group g1=CreateGroup()
private group g2=CreateGroup()
private group g3=CreateGroup()
private integer malaria='B00I'
private integer plague='B00H'
private integer fever='Brej'
endglobals

public function Infection takes nothing returns nothing
local unit u1=null
local unit u2=null
local unit u3=null
local unit dummy=null
local real x1
local real x2
local real y1
local real y2
local integer res
local integer p
call GroupEnumUnitsInRect(g1, bj_mapInitialPlayableArea, null)
loop
set u1 = FirstOfGroup(g1)
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
exitwhen u1 == null
//Special action for diseased Heroes
if IsUnitType(u1, UNIT_TYPE_HERO) then
set p = GetPlayerId(GetOwningPlayer(u1)) + 1
//Malaria Disease
if GetUnitAbilityLevel(u1, malaria) > 0 then
set udg_MB_Malaria= "Yes"
call SetPlayerState(Player(p-1), PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState(Player(p-1), PLAYER_STATE_RESOURCE_LUMBER) + 1)
if GetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE) > 3.00 then
call SetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE, (GetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE) - 3.00 ))
else
call KillUnit(udg_Hero_Troll)
set udg_Die_Diseases = udg_Die_Diseases + 1
endif
if GetUnitAbilityLevel(udg_Hero_Troll, 'B00G') == 0 and GetUnitAbilityLevel(udg_Hero_Troll, 'BUst') == 0 then
call SetUnitState(udg_Hero_Troll, UNIT_STATE_MANA, (GetUnitState(udg_Hero_Troll, UNIT_STATE_MANA) - 3.00 ))
endif
else
set udg_MB_Malaria= "No"
endif
//Plague Disease
if GetUnitAbilityLevel(u1, plague) > 0 then
set udg_MB_Plague= "Yes"
if GetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE) > 3.00 then
call SetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE, (GetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE) - 3.00 ))
else
call KillUnit(udg_Hero_Troll)
set udg_Die_Diseases = udg_Die_Diseases + 1
endif
if GetUnitAbilityLevel(udg_Hero_Troll, 'B00G') == 0 and GetUnitAbilityLevel(udg_Hero_Troll, 'BUst') == 0 then
call SetUnitState(udg_Hero_Troll, UNIT_STATE_MANA, (GetUnitState(udg_Hero_Troll, UNIT_STATE_MANA) - 4.50 ))
endif
else
set udg_MB_Plague= "No"
endif
//Fever Disease
if GetUnitAbilityLevel(u1, fever) > 0 then
set udg_MB_Fever= "Yes"
call SetPlayerState(Player(p-1), PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState(Player(p-1), PLAYER_STATE_RESOURCE_LUMBER) + GetRandomInt(0, 2))
if GetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE) > 1.50 then
call SetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE, (GetUnitState(udg_Hero_Troll, UNIT_STATE_LIFE) - 1.50 ))
else
call KillUnit(udg_Hero_Troll)
set udg_Die_Diseases = udg_Die_Diseases + 1
endif
if GetUnitAbilityLevel(udg_Hero_Troll, 'B00G') == 0 and GetUnitAbilityLevel(udg_Hero_Troll, 'BUst') == 0 then
call SetUnitState(udg_Hero_Troll, UNIT_STATE_MANA, (GetUnitState(udg_Hero_Troll, UNIT_STATE_MANA) - 6.00 ))
if GetRandomInt(1, 10) == 1 then
call GroupEnumUnitsInRange(g3, x1, y1, 2000., null)
loop
set u3 = FirstOfGroup(g3)
exitwhen u3 == null
if IsUnitType(u3, UNIT_TYPE_HERO) then
call DisplayTimedTextToPlayer(GetOwningPlayer(u3), 0., 0., 6.00, ( "|c0000c400Troll " + (GetPlayerName(GetOwningPlayer(u1)) + ":|r |c00ffff64AAaatcchhoo!|r" ) ) )
call PingMinimapForPlayer(GetOwningPlayer(u3), x1, y1, 3.00 )
endif
call GroupRemoveUnit(g3, u3)
endloop
endif
endif
else
set udg_MB_Fever= "No"
endif
//Action for diseased Units
else
if GetUnitAbilityLevel(u1, malaria) > 0 then
call SetUnitState(u1, UNIT_STATE_LIFE, (GetUnitState(u1, UNIT_STATE_LIFE ) - 3.00 ))
call SetUnitState(u1, UNIT_STATE_MANA, (GetUnitState(u1, UNIT_STATE_MANA ) - 3.00 ))
endif
if GetUnitAbilityLevel(u1, plague) > 0 then
call SetUnitState(u1, UNIT_STATE_LIFE, (GetUnitState(u1, UNIT_STATE_LIFE) - 3.00 ))
call SetUnitState(u1, UNIT_STATE_MANA, (GetUnitState(u1, UNIT_STATE_MANA) - 4.50 ))
endif
if GetUnitAbilityLevel(u1, fever) > 0 then
call SetUnitState(u1, UNIT_STATE_LIFE, (GetUnitState(u1, UNIT_STATE_LIFE) - 1.50 ))
call SetUnitState(u1, UNIT_STATE_MANA, (GetUnitState(u1, UNIT_STATE_MANA) - 6.00 ))
endif
endif
//Check if Unit from group1 is infected with any disease
if GetUnitAbilityLevel(u1, malaria) > 0 or GetUnitAbilityLevel(u1, plague) > 0 or GetUnitAbilityLevel(u1, fever) > 0 then
call GroupEnumUnitsInRange(g2, x1, y1, 300., null)
loop
set u2 = FirstOfGroup(g2)
exitwhen u2 == null
//check to prevent auto infection
if u2 != u1 then
if IsUnitType(u2, UNIT_TYPE_HERO) then
set res = udg_DiseaseResist[GetPlayerId(GetOwningPlayer(u2)) + 1]
else
set res = 50
endif
//if unit from group1 has malaria and the unit2 in range has not malaria yet
if GetUnitAbilityLevel(u1, malaria) > 0 and GetUnitAbilityLevel(u2, malaria) == 0 then
if GetRandomInt(1, res) <= 3 then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
set dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x2, y2, bj_UNIT_FACING)
call UnitAddAbility(dummy, 'ANdh')
call IssueTargetOrder(dummy, "drunkenhaze", u2)
endif
endif
//if unit from group1 has plague and the unit2 in range has not plague yet
if GetUnitAbilityLevel(u1, plague) > 0 and GetUnitAbilityLevel(u2, plague) == 0 then
if GetRandomInt(1, res) <= 3 then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
set dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x2, y2, bj_UNIT_FACING)
call UnitAddAbility(dummy, 'ACif')
call IssueTargetOrder(dummy, "innerfire", u2)
endif
endif
//if unit from group1 has fever and the unit2 in range has not fever yet
if GetUnitAbilityLevel(u1, fever) > 0 and GetUnitAbilityLevel(u2, fever) == 0 then
if GetRandomInt(1, res) <= 3 then
set x2 = GetUnitX(u2)
set y2 = GetUnitY(u2)
set dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'ndwm', x2, y2, bj_UNIT_FACING)
call UnitAddAbility(dummy, 'ACff')
call IssueTargetOrder(dummy, "faeriefire", u2)
endif
endif
endif
call GroupRemoveUnit(g2, u2)
endloop
endif
call GroupRemoveUnit(g1, u1)
endloop
endfunction
endlibrary
[/code]
 

Wrda

Spell Reviewer
Level 28
Joined
Nov 18, 2012
Messages
1,994
Global variables: variables that can be used in any trigger.
constant variables : variables that don't change, if you try to change, you get an error.
JASS:
        local unit u1=null
        local unit u2=null
        local unit u3=null
        local unit dummy=null
You don't need to declare these variables as null, because they are already null.
 
private means its unique to tht library so yes u can use g12 g2 and g3 in other triggers because u have them as private in this one. constant means tht it will not allow u to use set variable = value. for these u have an option
JASS:
        private integer malaria='B00I'
        private integer plague='B00H'
        private integer fever='Brej'

if they dont change and u only want to use them in this trigger change it to this
JASS:
        private constant integer malaria='B00I'
        private constant integer plague='B00H'
        private constant integer fever='Brej'
if u want to use them in other triggers but u dont want them to change there value change it to this
JASS:
        constant integer malaria='B00I'
        constant integer plague='B00H'
        constant integer fever='Brej'
 
You're close, but constant also means that the interpreter inlines it at runtime.

That means that using private constant x y z is not computationally more expensive than using the value directly.

Also, private constant integer malaria='B00I' is unacceptable for public resources. You should name your constants with private constant integer MALARIA_RAWCODE standard nomenclature.
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
basically you mean this...?
[Jass=]
globals
private group g1=CreateGroup()
private group g2=CreateGroup()
private group g3=CreateGroup()
constant integer MALARIA_B00I='B00I'
constant integer PLAGUE_B00H='B00H'
constant integer FEVER_Brej='Brej'
endglobals
[/code]

and then use (MALARIA_B00I)
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
oh i see...
i though the RAWCODE, was actually the raw code...
then i will name it MALARIA_BUFF
because it is basically the buff of the malaria disease spell...
 
Status
Not open for further replies.
Top