- Joined
- May 31, 2008
- Messages
- 698
shoot stuff, triggered by casting a spell 
should work on unit target, location target, and instant cast spells
includes speed, duration, damage, and aoe of projectile
It also changes the projectiles height based on the terrain height below it, so it actually moves straight and doesnt go up and down when going over cliffs or raised terrain. And the projectile will die if it hits a unit/doodad or the ground/cliff
just in regular jass, do i have to make it vjass to make it more efficient and stuff? cause i dont know how to do that lol..
Edit:
Should this be in spells section?? if so could someone please move it?
should work on unit target, location target, and instant cast spells
includes speed, duration, damage, and aoe of projectile
It also changes the projectiles height based on the terrain height below it, so it actually moves straight and doesnt go up and down when going over cliffs or raised terrain. And the projectile will die if it hits a unit/doodad or the ground/cliff
just in regular jass, do i have to make it vjass to make it more efficient and stuff? cause i dont know how to do that lol..
JASS:
function Cond takes nothing returns boolean
return GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(udg_Caster)) == true
endfunction
function doodadcount takes nothing returns nothing
if GetDestructableLife(GetEnumDestructable()) > 0 then
set udg_doodadcount = udg_doodadcount + 1
endif
endfunction
function dmg takes nothing returns nothing
set udg_TargetZ = (GetUnitFlyHeight(GetEnumUnit()) + GetLocationZ(GetUnitLoc(GetEnumUnit())))
if GetUnitState(GetEnumUnit(), UNIT_STATE_LIFE) > 0 and ((udg_MissileZ > udg_TargetZ) and (udg_MissileZ < (udg_TargetZ + 190))) then
call UnitDamageTarget(udg_Caster, GetEnumUnit(), udg_damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
endif
endfunction
function unitcount takes nothing returns nothing
local location temploc
set temploc = GetUnitLoc(GetEnumUnit())
set udg_TargetZ = (GetUnitFlyHeight(GetEnumUnit()) + GetLocationZ(temploc))
if GetUnitState(GetEnumUnit(), UNIT_STATE_LIFE) > 0 and ((udg_MissileZ > udg_TargetZ) and (udg_MissileZ < (udg_TargetZ + 190))) then
set udg_unitcount = udg_unitcount + 1
set udg_Target = GetEnumUnit()
endif
call RemoveLocation(temploc)
endfunction
function Projectile takes real speed, real duration, real damage, real aoe returns nothing
local integer i = (GetPlayerId(GetOwningPlayer(GetEnumUnit())) + 1)
local group units = CreateGroup()
local real dist
local real z
local real z2
local real x
local real y
local real x2
local real y2
local real x3
local real y3
local real x4
local real y4
local real x5
local real y5
local real dx
local real dy
local real missile_h //CHANGE
local real facing = GetUnitFacing(GetEnumUnit())
local location loca
set udg_unitcount = 0
set udg_doodadcount = 0
set udg_damage = damage
set x = GetUnitX(GetEnumUnit()) // loc3
set y = GetUnitY(GetEnumUnit()) // loc3
call MoveRectTo(udg_Rect1, x, y)
call MoveRectTo(udg_Rect2, x, y)
set x2 = x + speed * Cos(facing * bj_DEGTORAD) // loc6
set y2 = y + speed * Sin(facing * bj_DEGTORAD) // loc6
call MoveLocation(udg_LocZ, x2, y2)
set loca = Location(x2, y2)
set z = GetLocationZ(loca)
call UnitApplyTimedLife(GetEnumUnit(), 'BTLF', duration)
call SetUnitFlyHeight( GetEnumUnit(), (udg_InitialHeight[GetUnitUserData(GetEnumUnit())] - z), 0.00 )
set udg_Caster = GetEnumUnit()
set udg_TempLoc = GetUnitLoc(GetEnumUnit())
set udg_MissileZ = GetUnitFlyHeight(GetEnumUnit()) + z
set missile_h = GetUnitFlyHeight(GetEnumUnit()) //CHANGE
set x3 = x + speed * Cos(facing * bj_DEGTORAD) // moveloc
set y3 = y + speed * Sin(facing * bj_DEGTORAD) // moveloc
set udg_MoveLoc = Location(x3, y3)
call GroupEnumUnitsInRange(units, x, y, 75, Condition(function Cond)) // units
call DestroyBoolExpr(Condition(function Cond))
if missile_h < 290 then //CHANGE
call EnumDestructablesInRect(udg_Rect1, null, function doodadcount)
endif
call ForGroup(units, function unitcount)
call DestroyGroup(units)
if ( (udg_doodadcount != 0) or (udg_unitcount != 0) ) then
call UnitDamagePoint(udg_Hunter[i], 0, aoe, x, y, damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
call KillUnit(GetEnumUnit())
call GroupRemoveUnit(udg_ProjectileGroup, GetEnumUnit())
endif
if (GetUnitFlyHeight(GetEnumUnit()) <= 1) or (IsPointBlighted(x, y)) then
set udg_damage = damage
set units = CreateGroup()
call GroupEnumUnitsInRange(units, x, y, aoe, null)
call ForGroup(units, function dmg)
call KillUnit(GetEnumUnit())
call GroupRemoveUnit(udg_ProjectileGroup, GetEnumUnit())
call DestroyGroup(units)
endif
call RemoveLocation(udg_TempLoc)
call DestroyGroup(units)
set udg_Caster = null
endfunction
function Temp takes nothing returns nothing
if GetUnitTypeId(GetEnumUnit()) == 'XXXX' then // check which projectile is being picked
call Projectile(20, 3, 50, 250) // (speed, duration, damage, area of effect)
endif // max distance = duration * (speed * 33.33)
call SetUnitPositionLoc(GetEnumUnit(), udg_MoveLoc) // NOTE: Projectile aoe will damage allied units, but projectiles will not explode on allied units
call RemoveLocation(udg_MoveLoc)
endfunction
function Pick takes nothing returns nothing
call ForGroup(udg_ProjectileGroup, function Temp)
endfunction
function Set2 takes integer abilityId, integer unitId, boolean two, real off, real h, boolean loccast, boolean targetcast, boolean instantcast returns nothing
local unit u = GetTriggerUnit()
local integer i = (GetPlayerId(GetOwningPlayer(GetTriggerUnit())) + 1)
local real height
local integer chance
local unit u1
local unit u2 = null
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real x2
local real y2
local real mana
local real mana1
local real mana2
local location loc = GetUnitLoc(u)
local location targetloc = GetSpellTargetLoc()
local real locx = GetLocationX(targetloc)
local real locy = GetLocationY(targetloc)
local location targetunitloc = GetUnitLoc(GetSpellTargetUnit())
local real unitx = GetLocationX(targetunitloc)
local real unity = GetLocationY(targetunitloc)
local unit target = GetSpellTargetUnit()
local real angle
local real offset
if loccast == true then // if casted on a location
set angle = bj_RADTODEG * Atan2(locy - y, locx - x)
endif
if target != null and targetcast == true then // if casted on a unit
set angle = bj_RADTODEG * Atan2(unity - y, unitx - x)
endif
if instantcast == true then // if casted instantly (no target)
set angle = GetUnitFacing(u)
endif
if GetSpellAbilityId() == abilityId then //projectile 1
set offset = off // how far to the left/right of the unit the projectile is created
set x = GetUnitX(u) + offset * Cos((angle + 90) * bj_DEGTORAD) // for the first projectile launched
set y = GetUnitY(u) + offset * Sin((angle + 90) * bj_DEGTORAD) // (this will be to the left of the caster if offset > 0)
set x2 = GetUnitX(u) + offset * Cos((angle - 90) * bj_DEGTORAD) // for the second projectile launched
set y2 = GetUnitY(u) + offset * Sin((angle - 90) * bj_DEGTORAD) // (this is optional, if you want to launch 2 projectiles, one on each side of the caster)
endif
if GetUnitState(u, UNIT_STATE_LIFE) > 0 then // creates projectiles if the caster is alive
if ((GetSpellAbilityId() == abilityId))then // creates projectile 1
set u1 = CreateUnit(Player(i - 1), unitId, x, y, angle)
if two == true then
set u2 = CreateUnit(Player(i - 1), unitId, x2, y2, angle) // put "//" in front of this line if you want only one projectile
endif
set height = h
endif
if two == true then
call UnitAddAbility(u2, 'Arav')
call SetUnitFlyHeight( u2, GetUnitFlyHeight(u) + height, 0.00 )
call UnitRemoveAbility(u2, 'Arav')
call SetUnitPosition(u2, x2, y2)
call GroupAddUnit(udg_ProjectileGroup, u2)
set udg_CustomValue = udg_CustomValue + 1
call SetUnitUserData( u2, udg_CustomValue )
set udg_InitialHeight[udg_CustomValue] = GetLocationZ(loc) + height + GetUnitFlyHeight(u)
endif
call UnitAddAbility(u1, 'Arav')
call SetUnitFlyHeight( u1, GetUnitFlyHeight(u) + height, 0.00 )
call UnitRemoveAbility(u1, 'Arav')
call SetUnitPosition(u1, x, y)
call GroupAddUnit(udg_ProjectileGroup, u1)
set udg_CustomValue = udg_CustomValue + 1
call SetUnitUserData( u1, udg_CustomValue )
if udg_CustomValue >= 4950 then
set udg_CustomValue = 0
endif
set udg_InitialHeight[udg_CustomValue] = GetLocationZ(loc) + height + GetUnitFlyHeight(u)
call TimerStart(udg_Timer, .03, true, function Pick)
endif
set u1 = null
set u2 = null
set u = null
call RemoveLocation(loc)
set target = null
endfunction
function Set takes nothing returns nothing
call Set2('A003', 'h000', false, 0, 140, false, false, true)
// (Ability ID, Unit ID, Create Two Projectiles?, Offset Of Projectiles, Projectile Height, Location Cast?, Unit Cast?, Instant Cast?)
// if you create 2 projectiles, make an offset. Typical offset around 100
// To launch one projectile from one side, make an offset. Positive offset = left side, negative offset = right side
endfunction
//===========================================================================
function InitTrig_ProjectileSystem takes nothing returns nothing
set gg_trg_ProjectileSystem = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( gg_trg_ProjectileSystem, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddAction(gg_trg_ProjectileSystem, function Set)
endfunction
Edit:
Should this be in spells section?? if so could someone please move it?
Last edited: