| 06-30-2010, 08:49 AM | #1 |
So, i made a spell and wanted to check if it is possible to make faster and efficient. So here's the code. You can choose the poll options. Good code, or Bad code. JASS:library StrengthAura initializer Init globals // CLOSE_RANGE_BONUS = How much strength you get when in Close Range private constant integer CLOSE_RANGE_BONUS = 15 // MEDIUM_RANGE_BONUS = How much strength you get when in Medium Range private constant integer MEDIUM_RANGE_BONUS = 10 // LONG_RANGE_BONUS = How much strength you get when in Long Range private constant integer LONG_RANGE_BONUS = 5 // CLOSE_RANGE = Indicates how long Close Range is. private constant real CLOSE_RANGE = 200 // MEDIUM_RANGE = Indicates how long Medium Range is. private constant real MEDIUM_RANGE = 400 // LONG_RANGE = Indicates how long Long Range is. private constant real LONG_RANGE = 600 // FULL_STR = Should it Include Bonuses from strength gain?? private constant boolean FULL_STR = TRUE // SPELL_ID = ... private constant integer SPELL_ID = 'A000' // BUFF_ID = ... private constant integer BUFF_ID = 'B000' // TIMERTICK = Every X seconds ticks, checking and adding strength. ( A tip, dont have it below 0.05. private constant real TIMERTICK = .05 //Dont Touch. Just dont do it. //**==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*=| /* */private real globX //=| /* */private real globY //=| /* */private group tmpGrp = CreateGroup() //=| /* */private unit picked //=| /* */private unit Owner //=| /* */private timer ti //=| /* */private hashtable table = InitHashtable() //=| /* */private unit array HeroWithAura //=| /* */private integer HeroWithAuraCount = 0 //=| //**==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*=| endglobals private constant function TYPES takes nothing returns boolean return IsUnitType(picked, UNIT_TYPE_HERO) and not/* Picked unit is a Hero */ IsUnitType(picked, UNIT_TYPE_ANCIENT) and not/* The picked unit is not an Ancient */ IsUnitType(picked, UNIT_TYPE_ETHEREAL) and not/* The picked unit is not etheral */ IsUnitType(picked, UNIT_TYPE_MAGIC_IMMUNE) and not/* The picked unit is not magic immune */ IsUnitType(picked, UNIT_TYPE_SUMMONED) and/* The picked unti is Not summoned */ IsUnitInGroup(picked, tmpGrp) // And the picked unit is in the group. endfunction private constant function CLOSE takes integer lvl returns integer return 15 * lvl endfunction private constant function MEDIUM takes integer lvl returns integer return 10 * lvl endfunction private constant function FAR takes integer lvl returns integer return 5 * lvl endfunction //================================================================================================================== private struct Data private real x private real y private real range private real xx private real yy private real r private unit Enum private method ApplyBonus takes unit u, integer bonus returns nothing //As name, the function used to add bonuses. if HaveSavedInteger(table, GetHandleId(u), 1) then call SetHeroStr(u, GetHeroStr(u, FULL_STR)-LoadInteger(table, GetHandleId(u), 1), FULL_STR) if bonus == 0 then call RemoveSavedInteger(table, GetHandleId(u), 1) else call SaveInteger(table, GetHandleId(u), 1, bonus) endif else if bonus != 0 then call SaveInteger(table, GetHandleId(u), 1, bonus) endif endif call SetHeroStr(u, GetHeroStr(u, FULL_STR)+bonus, FULL_STR) endmethod static method GetUnitAuraBonus takes unit u returns integer //This function "checks" where the unit is, and adds bonus after that condition local integer i = 0 local integer m = 0 loop exitwhen i == HeroWithAuraCount if IsUnitInRange(u, HeroWithAura[i], LONG_RANGE) then if IsUnitInRange(u, HeroWithAura[i], CLOSE_RANGE) then if CLOSE(GetUnitAbilityLevel(HeroWithAura[i],SPELL_ID)) > m then set m = CLOSE(GetUnitAbilityLevel(HeroWithAura[i],SPELL_ID)) endif elseif IsUnitInRange(u, HeroWithAura[i], MEDIUM_RANGE) then if MEDIUM(GetUnitAbilityLevel(HeroWithAura[i],SPELL_ID)) > m then set m = MEDIUM(GetUnitAbilityLevel(HeroWithAura[i],SPELL_ID)) endif elseif IsUnitInRange( u ,HeroWithAura[i], LONG_RANGE) then if FAR(GetUnitAbilityLevel(HeroWithAura[i],SPELL_ID)) > m then set m = FAR(GetUnitAbilityLevel(HeroWithAura[i],SPELL_ID)) endif endif endif set i = i + 1 endloop return m endmethod static method loopFuncEnum takes nothing returns nothing local thistype this = allocate() set Enum = GetEnumUnit() call ApplyBonus(Enum, GetUnitAuraBonus(Enum)) //Applies the bonus. endmethod endstruct //================================================================================================================== private function onLearn takes nothing returns nothing set HeroWithAura[HeroWithAuraCount] = GetTriggerUnit() set HeroWithAuraCount = HeroWithAuraCount + 1 endfunction //================================================================================================================== private function hasBuff takes nothing returns boolean return GetUnitAbilityLevel(GetFilterUnit(), BUFF_ID) > 0 // Filter, which picks all units in the range Which has the buff. endfunction //================================================================================================================== private function Conditions takes nothing returns boolean return GetLearnedSkill() == SPELL_ID // Gets the Learned Skill. endfunction //================================================================================================================== private function doLoop takes nothing returns nothing local rect r = GetWorldBounds() call ForGroup(tmpGrp, function Data.loopFuncEnum) call GroupEnumUnitsInRect(tmpGrp, r, Filter(function hasBuff)) call ForGroup(tmpGrp, function Data.loopFuncEnum) call RemoveRect(r) set r = null endfunction //================================================================================================================== //================================================================================================================== private function Init takes nothing returns nothing local trigger t = CreateTrigger() local integer i = 0 set ti = CreateTimer() call TimerStart( ti , TIMERTICK , true , function doLoop ) //========================================================== loop exitwhen i == 16 call TriggerRegisterPlayerUnitEvent( t , Player(i) , EVENT_PLAYER_HERO_SKILL , null ) set i = i + 1 endloop call TriggerAddCondition( t , Condition(function Conditions )) call TriggerAddAction( t , function onLearn ) //=========================================================== endfunction //================================================================================================================== //================================================================================================================== endlibrary Thanks KillStr34kz[MK] |
| 07-04-2010, 04:05 PM | #2 |
The code really doesn't need to run so often, you could multiply TIMERTICK by 10 and players wouldn't really notice any difference. The WC3 auras themselves already update very rarely. Apart from that, the code seems reasonably efficient. It would likely be better if you enumerated units in range of each hero instead of enumerating the entire map, though. I think this could be further improved to require less code execution if you moved away from checking for a buff from an in-game aura and instead triggered the aura completely. The aura module of my ABuff system does that quite elegantly. |
