LurkerAspect
Now officially a Super Lurker
- Reaction score
- 117
Hi there all 
I've been doing JASS for some time, and I've reached a level where I'm comfortable and don't really want to get any more advanced (not planning to be the next Jesus4Lyf!). The spell I have inserted below is what I consider to be the best example of my coding knowledge, I was just wondering where I've gone wrong and what I can do to improve the speed and security of my coding. Help will be rewarded with mention in my current map and a generous wallop of +rep
(considering I can give more than 1 rep point these days)
So take a look and tell me what you think! I'm personally concerned about the use of the HIT_GROUP group array, if there's a better MUI way instead of my current MPI (multiple player instanceability!) then please let me know!
For those who are curious, I'm using a blank dummy model with attachment references and adding special effects to them, instead of making hundreds of individualised dummies. Would a recycling system be a good idea? I'm also using an archaic struct system that I dug up somewhere (I can't remember where!) which enables my spells to run on one timer each.
Any tips, advice, and (constructive if possible!) criticism welcome
I've been doing JASS for some time, and I've reached a level where I'm comfortable and don't really want to get any more advanced (not planning to be the next Jesus4Lyf!). The spell I have inserted below is what I consider to be the best example of my coding knowledge, I was just wondering where I've gone wrong and what I can do to improve the speed and security of my coding. Help will be rewarded with mention in my current map and a generous wallop of +rep
So take a look and tell me what you think! I'm personally concerned about the use of the HIT_GROUP group array, if there's a better MUI way instead of my current MPI (multiple player instanceability!) then please let me know!
JASS:
//AF_0A_100100_FIRE_BLAST
//Quick synopsis for your convenience: Player casts spell at target point, caster breathes a cone of fire which damages and ignites units (hence the parasite ability)
scope FireBlast initializer init
private keyword FIRE
globals
private constant integer ABILCODE = 'A00A'
private constant integer DUMMY_ABILCODE = 'ACpa'
private constant real CONE_SIZE = 60
private constant real IMPACT_SIZE = 100
private constant real DAMAGE = 50
private constant real SPEED = 900
private constant real DISTANCE = 500
private constant string ATTACHMENT_SFX = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
private constant string HIT_SFX = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
private integer I = 0
private FIRE array DATA
private unit CASTER = null
private timer TIMER = CreateTimer()
private group array HIT_GROUP
endglobals
private function GC takes nothing returns boolean
local unit u = GetFilterUnit()
local unit d
local integer p = GetPlayerId(GetOwningPlayer(CASTER))
if CheckTarget(CASTER,u) and not IsUnitInGroup(u,HIT_GROUP[p]) then
set d = CreateUnit(Player(p),DUMMY,GetUnitX(u),GetUnitY(u),0)
call UnitAddAbility(d,DUMMY_ABILCODE)
call IssueTargetOrder(d,"parasite",u)
call UnitApplyTimedLife(d,EXPIRE,2)
call UnitDamageTarget(CASTER,u,DAMAGE,false,false,ATTACK_TYPE_HERO,DAMAGE_TYPE_FIRE,null)
call DestroyEffect(AddSpecialEffect(HIT_SFX,GetUnitX(u),GetUnitY(u)))
call GroupAddUnit(HIT_GROUP[p],u)
set d = null
endif
set u = null
return false
endfunction
private struct FIRE
unit caster
unit array dummy[99]
real array dX[99]
real array dY[99]
effect array attachment[99]
integer dummycount = 0
real step = 0
static method create takes unit caster, real X, real Y returns FIRE
local FIRE a = FIRE.allocate()
local real target_angle = Atan2(Y-GetUnitY(caster),X-GetUnitX(caster))*bj_RADTODEG
local real min_angle = target_angle-CONE_SIZE/2
local real max_angle = target_angle+CONE_SIZE/2
local real angle_step = (((2*bj_PI*DISTANCE)/IMPACT_SIZE)/(2*bj_PI*DISTANCE))*360
set a.caster = caster
if HIT_GROUP[GetPlayerId(GetOwningPlayer(a.caster))] == null then
set HIT_GROUP[GetPlayerId(GetOwningPlayer(a.caster))] = CreateGroup()
endif
loop
exitwhen min_angle > max_angle
set a.dummycount = a.dummycount+1
set a.dummy[a.dummycount] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),DUMMY,GetUnitX(a.caster),GetUnitY(a.caster),min_angle)
set a.attachment[a.dummycount] = AddSpecialEffectTarget(ATTACHMENT_SFX,a.dummy[a.dummycount],"head")
set a.dX[a.dummycount] = SPEED*INTERVAL*Cos(min_angle*bj_DEGTORAD)
set a.dY[a.dummycount] = SPEED*INTERVAL*Sin(min_angle*bj_DEGTORAD)
set min_angle = min_angle+angle_step
endloop
return a
endmethod
method Step takes nothing returns nothing
local integer i = 1
local real X = 0
local real Y = 0
loop
exitwhen i > .dummycount
set X = GetUnitX(.dummy<i>)+.dX<i>
set Y = GetUnitY(.dummy<i>)+.dY<i>
call SetUnitPosition(.dummy<i>,X,Y)
set CASTER = .caster
call GroupEnumUnitsInRange(GROUP,X,Y,IMPACT_SIZE,Filter(function GC))
set i = i+1
endloop
set .step = .step+SPEED*INTERVAL
endmethod
method destroy takes nothing returns nothing
local integer i = 1
loop
exitwhen i > .dummycount
call DestroyEffect(.attachment<i>)
call KillUnit(.dummy<i>)
set .dX<i> = 0
set .dY<i> = 0
set i = i+1
endloop
call GroupClear(HIT_GROUP[GetPlayerId(GetOwningPlayer(.caster))])
set .caster = null
set .step = 0
set .dummycount = 0
call .deallocate()
endmethod
endstruct
private function callback takes nothing returns nothing
local FIRE a
local integer i = 1
loop
exitwhen i > I
set a = DATA<i>
if a.step > DISTANCE then
call a.destroy()
set DATA<i> = DATA<i>
set I = I-1
set i=i-1
else
call a.Step()
endif
set i = i+1
endloop
if I == 0 then
call PauseTimer(TIMER)
endif
endfunction
private function Actions takes nothing returns nothing
local FIRE a = FIRE.create(GetTriggerUnit(),GetLocationX(GetSpellTargetLoc()),GetLocationY(GetSpellTargetLoc()))
set I = I+1
set DATA<i> = a
if I == 1 then
call TimerStart(TIMER,INTERVAL,true,function callback)
endif
endfunction
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == ABILCODE
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_CAST)
call TriggerAddCondition(t,Condition(function Conditions))
call TriggerAddAction(t,function Actions)
set t = null
call DestroyTrigger(t)
endfunction
endscope</i></i></i></i></i></i></i></i></i></i></i></i></i>
Any tips, advice, and (constructive if possible!) criticism welcome