Jass Efficiency Questions

General talk about editing, cheating, and deprotecting maps.

Moderator: Cheaters

Post Reply
User avatar
weirdone2
Forum Staff
Posts: 1008
Joined: June 3rd, 2007, 8:03 pm

Jass Efficiency Questions

Post by weirdone2 »

Well this here was a doozy prolly had 50+ excess function calls and the leaks this thing would probably have left... Anyway just wondering if I got all the leaks and made it pure efficient? I'm going to have to declare those I2S as a var aren't I. >.<

Spoiler:

Code: Select all

function Trig_Killing_Spree_Func005Func004A takes nothing returns nothing
call SetPlayerState(GetEnumPlayer(),PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(GetEnumPlayer(),PLAYER_STATE_RESOURCE_GOLD)+GetHeroLevel(GetTriggerUnit())*20)
endfunction
function Trig_Killing_Spree_Actions takes nothing returns nothing
local player p0=GetOwningPlayer(GetTriggerUnit())
local player p1=GetOwningPlayer(GetKillingUnit())
local string s0=GetPlayerName(p0)
local string s1=GetPlayerName(p1)
local location l=GetUnitLoc(GetKillingUnit())
local integer i0=GetPlayerId(p0)
local integer i1=GetPlayerId(p1)
local integer ti=GetHeroLevel(GetDyingUnit())
if IsUnitType(GetTriggerUnit(),UNIT_TYPE_HERO)then
if udg_KillSpree[i0]>=5then
call SetPlayerState(p1,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(p1,PLAYER_STATE_RESOURCE_GOLD)+500)
call DisplayTextToPlayer(GetLocalPlayer(),0,0,s0+" has ended "+s1+" |cffff0000Killing Spree|r")
endif
set udg_KillSpree[i0]=0
call DisplayTextToPlayer(GetLocalPlayer(),0,0,"|cffffff00"+s1+" has killed "+s0+"|r")
if p1!=Player(0)and p1!=Player(1)and p1!=Player(12)then
set udg_KillSpree[i1]=udg_KillSpree[i1]+1
call SetPlayerState(p1,PLAYER_STATE_RESOURCE_GOLD,GetHeroLevel(GetTriggerUnit())*50)
call DisplayTextToPlayer(p1,0,0,"|cff00ccccYou receive:|r |cff00ffff"+I2S(ti*50)+"|r |cff00ffffgold|r")
call UnitRemoveItemFromSlot(GetTriggerUnit(),GetRandomInt(2,5))
if udg_KillSpree[i1]==5then
call SetPlayerState(p1,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(p1,PLAYER_STATE_RESOURCE_GOLD)+500)
call DisplayTextToPlayer(GetLocalPlayer(),0,0,s0+" is on a |cffff0000KILLING SPREE!!|r")
call DisplayTextToPlayer(p1,0,0,"|cff00ccccYou receive 500gold|r")
call StartSound(gg_snd_KillingSpree)
call AddSpecialEffectLoc("Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl",l)
elseif udg_KillSpree[i1]==10then
call StartSound(gg_snd_Dom)
call SetPlayerState(p1,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(p1,PLAYER_STATE_RESOURCE_GOLD)+750)
call DisplayTextToPlayer(GetLocalPlayer(),0,0,s1+" is |cffff0000DOMINATING|r")
call DisplayTextToPlayer(p1,0,0,"|cff00ccccYou receive 750gold|r")
call AddSpecialEffectLoc("Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl",l)
endif
endif
if p1==Player(0)then
call DisplayTextToForce(fhumans,"|cff33ff33An Orc Hero has Died|r")
call DisplayTextToForce(fhumans,"|cff00ccccYou receive:|r |cff00ffff"+I2S(ti*20)+"|r |cff0000ccgold|r" )
call ForForce(fhumans,function Trig_Killing_Spree_Func005Func004A)
elseif p1==Player(1)then
call DisplayTextToForce(forcs,"|cff33ff33A Human Hero has Died|r")
call DisplayTextToForce(forcs,"|cff00ccccYou receive:|r |cff00ffff"+I2S(ti*20)+"|r |cff0000ccgold|r" )
call ForForce(forcs,function Trig_Killing_Spree_Func005Func004A)
endif
endif
call RemoveLocation(l)
set l=null
set p1=null
set p0=null
set s1=""
set s0=""
endfunction


Well I've never really messed with timers so I hope this works rite and is all good? Something i'm wondering on though is whats the deal with the timerdialogdisplay to force and to player, player=show force all = dont show... should I maybe just change timerdialogdisplay(td,true) to false and take out the for force? Also the timer is being registered in a getexpiredtimerevent so am I destroying it too soon for that or is the wait time all good?

Spoiler:

Code: Select all

function Trig_Start_Timer_Func002Func004A takes nothing returns nothing
call TimerDialogDisplayForPlayerBJ(false,GetLastCreatedTimerDialogBJ(),GetEnumPlayer())
endfunction
function Trig_Start_Timer_Actions takes nothing returns nothing
local player p=GetOwningPlayer(GetTriggerUnit())
local integer i=GetPlayerId(p)
local timerdialog td=CreateTimerDialog(bj_crippledTimer[i+100])
if IsUnitType(GetTriggerUnit(),UNIT_TYPE_HERO)and p!=Player(0)and p!=Player(1)then
set udg_DeadHero[i]=GetTriggerUnit()
call TimerDialogSetTitle(td,"Revive:")
call TimerDialogDisplay(td,true)
call TimerStart(bj_crippledTimer[i+100],I2R(GetUnitLevel(GetTriggerUnit()))*5,false,null)
call ForForce(bj_FORCE_ALL_PLAYERS,function Trig_Start_Timer_Func002Func004A)
call TimerDialogDisplayForPlayerBJ(true,td,p)
set udg_Window[i]=td
endif
call TriggerSleepAction(I2R(GetUnitLevel(GetTriggerUnit()))*5+3)
call DestroyTimerDialog(td)
call DestroyTimer(bj_crippledTimer[i+100])
set td=null
set bj_crippledTimer[i+100]=null
set p=null
endfunction
function InitTrig_Start_Timer takes nothing returns nothing
set gg_trg_Start_Timer = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(gg_trg_Start_Timer,EVENT_PLAYER_UNIT_DEATH)
call TriggerAddAction(gg_trg_Start_Timer,function Trig_Start_Timer_Actions)
endfunction

function Trig_Revive3_Actions takes nothing returns nothing
local integer i=2
local location l=GetRectCenter(gg_rct_Dungeon)
local player p
loop
exitwhen i>11
set p=Player(i)
if GetExpiredTimer()==bj_crippledTimer[i+100]then
if IsPlayerInForce(p,fhumans)then
if GetUnitState(gg_unit_hcas_0000,UNIT_STATE_LIFE)>0then
call PanCameraToTimedLocForPlayer(p,human_city_center,0)
call ReviveHeroLoc(udg_DeadHero[i],human_city_center,true)
else
call PanCameraToTimedLocForPlayer(p,l,0)
call ReviveHeroLoc(udg_DeadHero[i],l,true)
endif
elseif IsPlayerInForce(p,forcs)then
if GetUnitState(gg_unit_ofrt_0001,UNIT_STATE_LIFE)>0then
call PanCameraToTimedLocForPlayer(p,orc_city_center,0)
call ReviveHeroLoc(udg_DeadHero[i],orc_city_center,true)
else
call PanCameraToTimedLocForPlayer(p,l,0)
call ReviveHeroLoc(udg_DeadHero[i],l,true)
endif
endif
call DestroyTimerDialog(udg_Window[i])
call SelectUnitForPlayerSingle(GetLastCreatedUnit(),p)
endif
set i=i+1
endloop
call RemoveLocation(l)
set l=null
endfunction
function InitTrig_Revive3 takes nothing returns nothing
local integer i=2
set gg_trg_Revive3=CreateTrigger()
loop
exitwhen i>11
call TriggerRegisterTimerExpireEvent(gg_trg_Revive3,bj_crippledTimer[i+100])
set i=i+1
endloop
call TriggerAddAction(gg_trg_Revive3,function Trig_Revive3_Actions)
endfunction
User avatar
Aero
Forum Staff
Posts: 830
Joined: January 28th, 2007, 8:10 pm
Title: JASS Programmer
Location: Canada

Re: Jass Efficiency Questions

Post by Aero »

Spoiler:

Code: Select all

function AwardKillersTeamWithGold takes nothing returns nothing
local player p=GetEnumPlayer()
local integer gold=GetHeroLevel(GetTriggerUnit())*20
call DisplayTextToPlayer(p,"|cff00ccccYou receive:|r |cff00ffff"+I2S(gold)+"|r |cff0000ccgold|r")
call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)+gold)
set p=null
endfunction
function Killing_Spree_Conditions takes nothing returns boolean
return IsUnitType(GetTriggerUnit(),UNIT_TYPE_HERO)
endfunction
function Killing_Spree takes nothing returns nothing
local unit k=GetKillingUnit()
local unit t=GetTriggerUnit()
local real kx=GetUnitX(k)
local real ky=GetUnitY(k)
local player pk=GetOwningPlayer(k)
local player pt=GetOwningPlayer(t)
local integer pkid=GetPlayerId(pk)
local integer ptid=GetPlayerId(pt)
local integer level=GetHeroLevel(t)
local integer goldearned=0
local string pkname=GetPlayerName(pk)
local string ptname=GetPlayerName(pt)
call DisplayTextToPlayer(GetLocalPlayer(),0,0,pkname+" has killed "+ptname+"!!|r")
if udg_KillSpree[ptid]>4then
    set goldearned=500
    call SetPlayerState(pk,PLAYER_STATE_RESOURCE_GOLD,cgold)
    call DisplayTextToPlayer(GetLocalPlayer(),0,0,pkname+" has ended "+pkname+"'s |cffff0000Killing Spree|r")
endif
set udg_KillSpree[ptid]=0
if pkid==0then
    call DisplayTextToForce(fhumans,"|cff33ff33An Orc Hero has Died|r")
    call ForForce(fhumans,function AwardKillersTeamWithGold)
elseif pkid==1then
    call DisplayTextToForce(forcs,"|cff33ff33A Human Hero has Died|r")
    call ForForce(forcs,function AwardKillersTeamWithGold)
elseif pkid!=12then
    set udg_KillSpree[pkid]=udg_KillSpree[pkid]+1
    if udg_KillSpree[pkid]==5then
        set goldearned=goldearned+500
        call DisplayTextToPlayer(GetLocalPlayer(),0,0,pkname+" is on a |cffff0000KILLING SPREE!!|r")
        call StartSound(gg_snd_KillingSpree)
        call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl",kx,ky))
    elseif
        set goldearned=goldearned+750
        call DisplayTextToPlayer(GetLocalPlayer(),0,0,pkname+" is |cffff0000DOMINATING|r")
        call StartSound(gg_snd_Dom)
        call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl",kx,ky))
    endif
    set goldearned=goldearned+level*50
    call SetPlayerState(pk,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(pk,PLAYER_STATE_RESOURCE_GOLD)+goldearned)
    call DisplayTextToPlayer(pk,0,0,"|cff00ccccYou receive:|r |cff00ffff"+I2S(goldearned)+"|r |cff00ffffgold|r")
    call UnitRemoveItemFromSlot(t,GetRandomInt(2,5))
endif
set k=null
set t=null
set pk=null
set pt=null
endfunction


A few tips...
1. Start by renaming functions
2. Notice how you call "GetKillingUnit()" more than once. You also call GetDyingUnit() and GetTriggerUnit() (TriggerUnit multiple times) which return the same unit (Thus this is also a double call). As a side note, GetTriggerUnit() is faster than GetDyingUnit(). If more than one of the same call are made (Takes nothing returns something functions), store it in a variable (I used 'k').
3. Name your locals better. p0 and p1 ect. can get confusing; confusion leads to error. Then again, whatever works for you.
4. Instead of having an entire if statement, turn it into a condition. Then, if the condition catches that the dying unit is not a hero, you don't end up making a bunch of function calls (GetTriggerUnit(), variable declaration ect.) for nothing.
5. The x has killed y should be before the checking for "has ended x's kiling spree" (IMO)
6. Special Effects LEAK!
7. Instead of doing if p1==Player(x), we can just compare the id. If i1==0 then... This way, we can avoid the Player call.
8. We can use a goldearned variable to track how much gold to add in total. Then, you have less calls and only 1 gold display message.
9. I also fused the display messages with the "AwardKillersTeamWithGold" function since they are the same...

I'll tackle the timers now...

[Edit] The timer functions can be easily integrated into the death... I'll do this.

You'll need an integer array called "udg_IdPointer" (So it would be called IdPointer in the variable editor)
I integrated the timer and death functions.
I optimized it the best I could given the information provided. There is still room for optimization but this will suffice.
If you have any questions, let me know (Also, this is untested so there could be an error).

Spoiler:

Code: Select all

function H2I takes handle h returns integer
return h
return 0
endfunction
function AttachIntToHandle takes handle h,integer id returns nothing
local integer i=H2I(h)
set i=i*0x7F400000
set i=i/0x80000+0x1000
set udg_IdPointer[i]=id
endfunction
function GetIntFromHandle takes handle h returns integer
local integer i=H2I(h)
set i=i*0x7F400000
set i=i/0x80000+0x1000
return udg_IdPointer[i]
endfunction
function ReviveAndKillWindows takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer id=GetIntFromHandle(t)
local player p=Player(id)
local real dungeonx=GetRectCenterX(gg_rct_Dungeon)
local real dungeony=GetRectCenterY(gg_rct_Dungeon)
if IsPlayerInForce(p,fhumans)then
    if GetWidgetLife(gg_unit_hcas_0000)>=.405then
        call PanCameraToTimedLocForPlayer(p,human_city_center,0)
        call ReviveHeroLoc(udg_DeadHero[id],human_city_center,true)
    else
        call PanCameraToTimedForPlayer(p,dungeonx,dungeony,.0)
        call ReviveHero(udg_DeadHero[id],dungeonx,dungeony,true)
    endif
else
    if GetWidgetLife(gg_unit_ofrt_0001)>=.405then
        call PanCameraToTimedLocForPlayer(p,orc_city_center,0)
        call ReviveHeroLoc(udg_DeadHero[i],orc_city_center,true)
    else
        call PanCameraToTimedForPlayer(p,dungeonx,dungeony,.0)
        call ReviveHero(udg_DeadHero[id],dungeonx,dungeony,true)
    endif
endif
call DestroyTimerDialog(udg_Window[id])
call DestroyTimer(t)
set p=null
set t=null
endfunction
function SetupHeroRevive takes timer t,integer id,real timerdur,player p returns nothing
set udg_Window[id]=CreateTimerDialog(t)
call TimerDialogSetTitle(udg_Window[id],"Revive:")
call TimerDialogDisplay(udg_Window[id],GetLocalPlayer()==p)
call AttachIntToHandle(t,id)
call TimerStart(t,timerdur,false,function ReviveAndKillWindow)
endfunction
function AwardKillersTeamWithGold takes nothing returns nothing
local player p=GetEnumPlayer()
local integer gold=GetHeroLevel(GetTriggerUnit())*20
call DisplayTextToPlayer(p,"|cff00ccccYou receive:|r |cff00ffff"+I2S(gold)+"|r |cff0000ccgold|r")
call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)+gold)
set p=null
endfunction
function Killing_Spree_Conditions takes nothing returns boolean
return IsUnitType(GetTriggerUnit(),UNIT_TYPE_HERO)
endfunction
function Killing_Spree takes nothing returns nothing
local unit k=GetKillingUnit()
local unit t=GetTriggerUnit()
local real kx=GetUnitX(k)
local real ky=GetUnitY(k)
local player pk=GetOwningPlayer(k)
local player pt=GetOwningPlayer(t)
local integer pkid=GetPlayerId(pk)
local integer ptid=GetPlayerId(pt)
local integer level=GetHeroLevel(t)
local integer goldearned=0
local string pkname=GetPlayerName(pk)
local string ptname=GetPlayerName(pt)
call DisplayTextToPlayer(GetLocalPlayer(),0,0,pkname+" has killed "+ptname+"!!|r")
if udg_KillSpree[ptid]>4then
    set goldearned=500
    call SetPlayerState(pk,PLAYER_STATE_RESOURCE_GOLD,cgold)
    call DisplayTextToPlayer(GetLocalPlayer(),0,0,pkname+" has ended "+pkname+"'s |cffff0000Killing Spree|r")
endif
set udg_KillSpree[ptid]=0
if pkid==0then
    call DisplayTextToForce(fhumans,"|cff33ff33An Orc Hero has Died|r")
    call ForForce(fhumans,function AwardKillersTeamWithGold)
elseif pkid==1then
    call DisplayTextToForce(forcs,"|cff33ff33A Human Hero has Died|r")
    call ForForce(forcs,function AwardKillersTeamWithGold)
elseif pkid!=12then
    set udg_KillSpree[pkid]=udg_KillSpree[pkid]+1
    if udg_KillSpree[pkid]==5then
        set goldearned=goldearned+500
        call DisplayTextToPlayer(GetLocalPlayer(),0,0,pkname+" is on a |cffff0000KILLING SPREE!!|r")
        call StartSound(gg_snd_KillingSpree)
        call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl",kx,ky))
    elseif
        set goldearned=goldearned+750
        call DisplayTextToPlayer(GetLocalPlayer(),0,0,pkname+" is |cffff0000DOMINATING|r")
        call StartSound(gg_snd_Dom)
        call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl",kx,ky))
    endif
    set goldearned=goldearned+level*50
    call SetPlayerState(pk,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(pk,PLAYER_STATE_RESOURCE_GOLD)+goldearned)
    call DisplayTextToPlayer(pk,0,0,"|cff00ccccYou receive:|r |cff00ffff"+I2S(goldearned)+"|r |cff00ffffgold|r")
    call UnitRemoveItemFromSlot(t,GetRandomInt(2,5))
endif
if ptid>1then
    set udg_DeadHero[ptid]=t
    call SetupHeroRevive(CreateTimer(),ptid,I2R(level*5),pt)
endif
set k=null
set t=null
set pk=null
set pt=null
endfunction
User avatar
weirdone2
Forum Staff
Posts: 1008
Joined: June 3rd, 2007, 8:03 pm

Re: Jass Efficiency Questions

Post by weirdone2 »

Ooo missed quite a bit on that first one. :S Though I figured since killing unit is only used twice didn't really care to name it as a vars, never knew that dyeunit was slower then triggerunit though and for the vars p1,p0 just ezyer for me to remember then anything besides a long name. :) Now calling the effect while destroying it that's jsut plain neat woulda never thought to do something like that even if knew about the leak. :S As for the arrangement tip 5, I didn't rearrange them from what they were before I started optimizing it.

Now for the timer I do have a few questions on it first whats with the .405 for checking if unit is dead does 0 not work? Also what is with the calculations in the attachinttohandle and viceversa functions, it just some random calc to make sure the integers are within the 8192 range?

Now if ever you think I didn't give enough information on something you can just ask, though I do believe I provide all the juicy details. or if you don't even want to wait for my reply you can look rite in the map if you want, it's called human vs orcs 4.0a, heres a link even from epicwar. http://epicwar.com/maps/3938/

Anyway thanks for all the good info learned quite a bit in this one. >:O

Edit: Well decided to look at that inthandle function and I'm very doubtful that it's used for what I suggested earlier. ;/ Also their are quite a few things you ended up leaving out in your functions aero like cgold among other things, guess you were sleepy. >:O
Post Reply