Viikuna
No Marlo no game.
- Reaction score
- 265
Here is a spell i made for wc3creations spell contest.
It is vJass and MUI. Requires Cohadars TT, Vexorians CheckPathability and SafeX/Y -functions. ( You find all these from testmap. )
code:
Here is the testmap:
View attachment All the Birds.w3x
Download it and give me some comments.
Spell description would be something like this:
It sends few angry Birds flying towards the target location. When Birds collide with something or meet the maximum range, they spread out and deal damage to enemies and knock them them away.
EDIT. some shots:
It is vJass and MUI. Requires Cohadars TT, Vexorians CheckPathability and SafeX/Y -functions. ( You find all these from testmap. )
code:
JASS:
// Bird Strike by Viikuna
// This spell is made for wc3Creations Spell Contest
// Theme: Missile, Light. ( and Birds )
scope Birds initializer init
// this uses SomeNeatFunctions, TT ( Credits go to Cohadar )
globals
//==================================================================================
//==================================================================================
// Ability is based on Channel
private constant integer ABILITY_ID = 039;A000039;
// AoE for Knockback
private constant real AOE = 300.0
// AoE fot missile collinsion
private constant real MISSILE_AOE = 50.0
// Damage is calculated like this: DAMAGE_LEVEL*AbilityLevel+DAMAGE_BASE
private constant real DAMAGE_BASE = 0.0
private constant real DAMAGE_LEVEL = 50.0
// All the Birds
private constant integer MISSILE_ID0 = 039;h000039;
private constant integer MISSILE_ID1 = 039;h001039;
private constant integer MISSILE_ID2 = 039;h002039;
private constant integer MISSILE_ID3 = 039;h003039;
private constant integer MISSILE_ID4 = 039;h004039;
// Damage types
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_MAGIC
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MAGIC
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
// When unit collides with some object, the damage is calculated like this:
// Units Sliding Velocity * DAMAGE_FACTOR
private constant real DAMAGE_FACTOR = 2.5
// The bigger the number, the bigger the knockback
private constant real KNOCKBACK_FACTOR = 0.01
// missiles Maximum travelling range
private constant real MAX_RANGE = 1500.0
// Missiles move speed
private constant real STARTING_VELOCITY = 10.0
private constant real ACCELERATION = 0.5 / 2
// How fast sliding units stop
private constant real FRICTION = 2.5 / 2
// Maximum targets knocked per Missile
private constant integer MAX_TARGETS = 10
//==================================================================================
//==================================================================================
private integer array MISSILE_ID
private filterfunc F
private filterfunc True
private group TempG = CreateGroup()
private unit TempU
endglobals
private struct Data2
unit u
unit knocker
real sin
real cos
real x
effect e
real y
real velocity
boolean impact = false
method move takes nothing returns nothing
set this.velocity = this.velocity - FRICTION
set this.x = SafeX(this.x + this.velocity * this.cos)
set this.y = SafeY(this.y + this.velocity * this.sin)
set this.velocity = this.velocity - FRICTION
if CheckPathability(this.x,this.y) == true then
call SetUnitX(this.u,this.x)
call SetUnitY(this.u,this.y)
else
set this.impact = true
endif
endmethod
method onDestroy takes nothing returns nothing
call PauseUnit(this.u,false)
call DestroyEffect(this.e)
if this.impact == true then
call UnitDamageTarget(this.knocker,this.u,this.velocity*DAMAGE_FACTOR,false,false,ATTACK_TYPE,DAMAGE_TYPE,WEAPON_TYPE)
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl",this.x,this.y))
endif
endmethod
endstruct
private function Loop2 takes nothing returns boolean
local Data2 D = TT_GetData()
if D.impact == true or D.velocity <= 0 then
call D.destroy()
return true
endif
call D.move()
return false
endfunction
private struct Data
unit array bird[10]
unit shooter
real velocity
real range = 0.0
real x
real y
real array birdX[10]
real array birdY[10]
real sin
real cos
real array birdCos[10]
real array birdSin[10]
boolean spreaded = false
boolean end = false
method KnockThem takes nothing returns nothing
local unit u
local real x
local real y
local real dx
local real dy
local real a
local Data2 D
local integer i = 0
set TempU = this.shooter
call GroupEnumUnitsInRange(TempG,this.x,this.y,AOE,F)
loop
set u = FirstOfGroup(TempG)
set i = i + 1
exitwhen u == null or i == MAX_TARGETS
set x = GetUnitX(u)
set y = GetUnitY(u)
set dx = x - this.x
set dy = y - this.y
set D = Data2.create()
set D.velocity = (AOE - (SquareRoot(dx * dx + dy * dy)/2) ) * ( this.velocity / 2 ) * KNOCKBACK_FACTOR
set a = Atan2(dy,dx)
set D.sin = Sin(a)
set D.cos = Cos(a)
set D.x = x
set D.y = y
set D.u = u
set D.e = AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\FaerieDragonInvis\\FaerieDragon_Invis.mdl",D.u,"chest")
set D.knocker = this.shooter
call PauseUnit(D.u,true)
call D.move()
call TT_Start(function Loop2,D)
call UnitDamageTarget(this.shooter,u,DAMAGE_LEVEL*GetUnitAbilityLevel(this.shooter,ABILITY_ID)+DAMAGE_BASE,false,false,ATTACK_TYPE,DAMAGE_TYPE,WEAPON_TYPE)
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\ProcMissile\\ProcMissile.mdl",x,y))
call GroupRemoveUnit(TempG,u)
endloop
call GroupClear(TempG)
endmethod
method move takes nothing returns nothing
local unit u
local real a
local real dx
local real dy
local real d
local real r
local integer i = 0
local real cos = this.velocity * this.cos
local real sin = this.velocity * this.sin
set this.x = SafeX( this.x + cos)
set this.y = SafeY( this.y + sin)
set TempU = this.shooter
call GroupEnumUnitsInRange(TempG,this.x,this.y,MISSILE_AOE,F)
set u = FirstOfGroup(TempG)
if this.range >= MAX_RANGE or u != null or CheckPathability(this.x,this.y) == false then
call GroupClear(TempG)
set this.spreaded = true
set r = bj_PI / 5
set a = 0
set this.range = 0.0
call this.KnockThem()
loop
exitwhen i > 9
set a = a + r
call SetUnitFacing(this.bird<i>,a*bj_RADTODEG)
set this.birdCos<i> = Cos(a)
set this.birdSin<i> = Sin(a)
set i = i + 1
endloop
return
endif
loop
exitwhen i > 9
set dx = this.x - this.birdX<i>
set dy = this.y - this.birdY<i>
set d = SquareRoot(dx * dx + dy * dy)
if d > 150.0 then
set a = Atan2(dy,dx)
set this.birdSin<i> = Sin(a)
set this.birdCos<i> = Cos(a)
else
if d < 10 then
set this.birdSin<i> = GetRandomReal(0.0,1.0)
set this.birdCos<i> = GetRandomReal(0.0,1.0)
endif
endif
set this.birdX<i> = SafeX(this.birdX<i> + cos)
set this.birdY<i> = SafeY(this.birdY<i> + sin)
set this.birdX<i> = SafeX(this.birdX<i> + 5.0 * this.birdCos<i>)
set this.birdY<i> = SafeY(this.birdY<i> + 5.0 * this.birdSin<i>)
call SetUnitX(this.bird<i>,this.birdX<i>)
call SetUnitY(this.bird<i>,this.birdY<i>)
set i = i + 1
endloop
set this.velocity = this.velocity + ACCELERATION
set this.range = this.range + this.velocity
set this.velocity = this.velocity + ACCELERATION
set u = null
endmethod
method spread takes nothing returns nothing
local integer i = 0
if this.range > AOE then
set this.end = true
return
endif
loop
exitwhen i > 9
set this.birdX<i> = SafeX(this.birdX<i> + this.velocity * this.birdCos<i>)
set this.birdY<i> = SafeY(this.birdY<i> + this.velocity * this.birdSin<i>)
call SetUnitX(this.bird<i>,this.birdX<i>)
call SetUnitY(this.bird<i>,this.birdY<i>)
set i = i + 1
endloop
set this.velocity = this.velocity + ACCELERATION
set this.range = this.range + this.velocity
set this.velocity = this.velocity + ACCELERATION
endmethod
method onDestroy takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 9
call KillUnit(this.bird<i>)
set i = i + 1
endloop
endmethod
endstruct
private function ItIsTrue takes nothing returns boolean
return true
endfunction
private function filter takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(TempU)) == true and GetWidgetLife(GetFilterUnit()) > 0.0451 and GetUnitFlyHeight(GetFilterUnit()) == 0 and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false
endfunction
private function Loop takes nothing returns boolean
local Data D = TT_GetData()
if D.end == true then
call D.destroy()
return true
endif
if D.spreaded == true then
call D.spread()
else
call D.move()
endif
return false
endfunction
private function B takes nothing returns nothing
local Data D = Data.create()
local integer i = 0
local unit u = GetTriggerUnit()
local location loc = GetSpellTargetLoc()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real x2 = GetLocationX(loc)
local real y2 = GetLocationY(loc)
local real dx = x2 - x
local real dy = y2 - y
local real angle = Atan2(dy, dx)
set D.sin = Sin(angle)
set D.cos = Cos(angle)
set D.x = x
set D.y = y
set D.shooter = u
set D.velocity = STARTING_VELOCITY
loop
exitwhen i > 9
set D.bird<i> = CreateUnit(Player(13),MISSILE_ID[GetRandomInt(0,4)],D.x,D.y,angle*bj_RADTODEG)
call PauseUnit(D.bird<i>,true)
set D.birdX<i> = x
set D.birdY<i> = y
set D.birdCos<i> = GetRandomReal(0.0,1.0)
set D.birdSin<i> = GetRandomReal(0.0,1.0)
set i = i + 1
endloop
call TT_Start(function Loop, D)
call RemoveLocation(loc)
set loc = null
set u = null
endfunction
private function A takes nothing returns boolean
return GetSpellAbilityId() == ABILITY_ID
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
set MISSILE_ID[0] = MISSILE_ID0
set MISSILE_ID[1] = MISSILE_ID1
set MISSILE_ID[2] = MISSILE_ID2
set MISSILE_ID[3] = MISSILE_ID3
set MISSILE_ID[4] = MISSILE_ID4
set True = Filter(function ItIsTrue)
loop
call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,True)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t,Condition(function A))
call TriggerAddAction(t,function B)
set F = Filter(function filter)
endfunction
endscope</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>
Here is the testmap:
View attachment All the Birds.w3x
Download it and give me some comments.
Spell description would be something like this:
It sends few angry Birds flying towards the target location. When Birds collide with something or meet the maximum range, they spread out and deal damage to enemies and knock them them away.
EDIT. some shots: