• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Zephyr Challenge #6 - AOE Summon

Status
Not open for further replies.
Level 8
Joined
May 31, 2009
Messages
439
It's a little late, but I think I'll join in on the fun :)

Entry NameContestant Name

Nature's Call
Mjllonir

Will be releasing a picture soon.

Description :
Summon a tree at a chosen point. It will stay there for a set amount of time, releasing wisps that will detonate around a certain area.


[EDIT]

Alright here is a nice picture I just took :
 

Attachments

  • WC3ScrnShot_112809_132904_01_edited-1.jpg
    WC3ScrnShot_112809_132904_01_edited-1.jpg
    561.3 KB · Views: 95
Last edited:
Level 25
Joined
Jun 5, 2008
Messages
2,572
Well since uploading a vid of current work would take ages, you can run and test this unfinished version of it.

I only want your thoughts about the eyecandy/idea since i didn't code damage/effects on the spell, only the phoenixes motion and effect creation.

It is obvious i ain't gonna base the spell on cluster rockets, i only needed something to trigger the spell :p
 

Attachments

  • Flames of Ruin.w3x
    98.6 KB · Views: 45
Level 23
Joined
Nov 29, 2006
Messages
2,482
Nice, I love the bouncing collision idea:D And those red missiles at the end when the phoenixes already died looks cool too:p

And yeah, if I were you, dont use the cluster rockets ability as a base, or change the "data-missile count" for it. Whenever it is set to 0, it will make your hero to cast it in infinity, unless you press stop or move away.
 
Level 5
Joined
Oct 26, 2009
Messages
161
The caster system basically made spells for you, xe facilitates the creation of spells by abstracting very frequently used aspects of spells away. (xecast, for instance, is great for making special effects with z components or that play their stand animations) xe replaced the CS, sure, but xe is completely different and functions more on the level of tiny scripts than whole spell-templates.
 
Level 25
Joined
Jun 5, 2008
Messages
2,572
Yeah, gonna see if i can make use of the Zdummy model, if i can't figure out a smooth angle changing soon, gonna throw it out and just use phoenixs model.

I know the thingy for cluster rockets as base, gonna use a simple AoE spell as a base and remove it's dmg and other things from it.

I have a good idea for another summoning spell which i will see 2 make also, and then decide which one is better :)
 
Do we have to use TRUE filters, or can we just null filters now that the leak is fixed (for 1.24c)?

Static if's ftw.

JASS:
globals
    private constant boolean PRE_C = false
endglobals

function wtf takes nothing returns nothing
    static if PRE_C then
        call GroupEnumBlah(group, ..,Filter(function True))
    else
        call GroupEnumBlah(group, ..., null)
    endif
endfunction
 
Level 5
Joined
Oct 26, 2009
Messages
161
Just use a true filter. It's not like the world ends if you keep using it in the future even after the bug gets fixed. Chances are if you're using groups, you're probably using GroupUtils, which includes a global BOOLEXPR_TRUE anyways.
 
Level 14
Joined
Nov 18, 2007
Messages
816
Alright, just finished my coding spree. Uploading a WIP wouldve seriously disturbed me, and i dont like showing off unfinished work. Go to hell with your damn WIP rule. That one's for art contests. If you have doubts that i did all the work, feel free to ask me about the code. I should be able to explain it to you.

So, here my (perhaps unfinished) entry:
Code:
[B]Magic Chains[/B]

Interrupts all spells cast in target area. Summons a ward
that all enemy units in target area are chained to. Stops
all enemies in a target area from casting spells.
Fleeing units take damage equal to their movement speed.

[color=#ffcc00]Level 1[/color] - Small area, lasts 5 seconds.
[color=#ffcc00]Level 2[/color] - Medium area, lasts 6 seconds.
[color=#ffcc00]Level 3[/color] - Large area, lasts 7 seconds.

[color=#00bfff]Manacost[/color]: 100/120/140
[color=#00bfff]Cooldown[/color]: 10/12/14
attachment.php


This spell requires vJass, TimerUtils, GroupUtils, Table, SpellEvent and AutoIndex.

Credits:
  • Anitarf
  • Rising_Dusk
  • grim001
  • Vexorian
  • PitzerMike
  • MindWorX
  • Pipedream
  • SFilip
JASS:
library MagicChains initializer Init requires TimerUtils, GroupUtils, AutoIndex, SpellEvent
    
    private keyword Data // DO NOT TOUCH!
    
    globals
        private constant    integer                 AID                         = 'A000' // Ability triggering this spell
        private             integer         array   WARD_UID                    // the rawcode ID of the central ward
        private             real            array   AOE                         // AoE for each level // should match the AOE in the dummy ability
        private             real            array   DMG_FACTOR                  // DamageFactor for each level
        private             real            array   DURATION                    // Duration for each level // should match the duration of the dummy ability
        private constant    damagetype              DMG_DAMAGE_TYPE             = DAMAGE_TYPE_MAGIC // damage type of the damage affected units receive
        private constant    attacktype              DMG_ATTACK_TYPE             = ATTACK_TYPE_MAGIC // attack type of the damage affected unit receive
        
        private constant    real                    DISTANCE_CHANGE_SPEED       = 0.1 // from >0.0 to 1.0, please // closer to 0: longer time to sync with the wards position, closer to 1: less time to sync (1 being instant syncing)
        
        private constant    string                  LINK_LIGHTNING_TYPE         = "LEAS"
        private constant    real                    LINK_LIGHTNING_RED          = 1.0
        private constant    real                    LINK_LIGHTNING_GREEN        = 1.0
        private constant    real                    LINK_LIGHTNING_BLUE         = 1.0
        private constant    real                    LINK_LIGHTNING_ALPHA        = 0.8
        private constant    real                    LINK_LIGHTNING_ZOFFSET      = 64.
        private constant    string                  LINK_FX                     = "Abilities\\Spells\\Human\\AerialShackles\\AerialShacklesTarget.mdl" // FX attached to the affected units
        private constant    string                  LINK_FX_ATTPT               = "chest" // attachment point of LINK_FX
        
        private constant    real                    TICK                        = 1./40
    endglobals
    
    private function SetUpWARD_UID takes nothing returns nothing
        set WARD_UID[1]='h000'
        set WARD_UID[2]='h001'
        set WARD_UID[3]='h002'
    endfunction
    
    private function Ward_Uid takes integer level returns integer
        return WARD_UID[level]
    endfunction
    
    private function SetUpAOE takes nothing returns nothing
        set AOE[1]=300.
        set AOE[2]=450.
        set AOE[3]=600.
    endfunction
    
    private function Aoe takes integer level returns real
        return AOE[level]
    endfunction
    
    private function SetUpDMG_FACTOR takes nothing returns nothing
        set DMG_FACTOR[1]=0.10
        set DMG_FACTOR[2]=0.15
        set DMG_FACTOR[3]=0.20
    endfunction
    
    private function Dmg_Factor takes integer level returns real
        return DMG_FACTOR[level]
    endfunction
    
    private function SetUpDURATION takes nothing returns nothing
        set DURATION[1]=5.
        set DURATION[2]=6.
        set DURATION[3]=7.
    endfunction
    
    private function Duration takes integer level returns real
        return DURATION[level]
    endfunction
    
    private function ValidateTarget takes unit u, Data s returns boolean
        return     IsUnitType(u, UNIT_TYPE_DEAD)==false/*
            */ and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)==false/*
            */ and IsUnitType(u, UNIT_TYPE_STRUCTURE)==false/*
            */ and IsUnitType(u, UNIT_TYPE_MECHANICAL)==false/*
            */ and IsUnitEnemy(u, GetOwningPlayer(s.Caster))/*
            */ and IsUnitVisible(u, GetOwningPlayer(s.Caster))/*
            */
    endfunction
    
    private struct Link extends array
        lightning Light
        effect FX
        real Dist
    endstruct
    
    private struct Data
        unit Caster
        unit Ward
        integer Level
        group Affected
        
        private integer i
        
        static thistype tmps
        static boolexpr UnitFilter
        
        private static thistype array Structs
        private static integer Count=0
        private static timer T=CreateTimer()
        
        private static location LocZ=Location(0,0)
        
        private static method GetPointZ takes real x, real y returns real
            call MoveLocation(.LocZ, x, y)
            return GetLocationZ(.LocZ)
        endmethod
        
        private static method GetUnitZ takes unit u returns real
            return .GetPointZ(GetUnitX(u), GetUnitY(u))+GetUnitFlyHeight(u)
        endmethod
        
        private static method GroupDestroy takes nothing returns nothing
        local Link l=Link[GetUnitId(GetEnumUnit())]
            call DestroyLightning(l.Light)
            set l.Light=null
            call DestroyEffect(l.FX)
            set l.FX=null
        endmethod
        
        private method onDestroy takes nothing returns nothing
            set .tmps=this
            call ForGroup(.Affected, function thistype.GroupDestroy)
            call ReleaseGroup(.Affected)
            set .Caster=null
            set .Ward=null
            
            set .Count=.Count-1
            set .Structs[.i]=Structs[.Count]
            set .Structs[.i].i=.i
            if .Count==0 then
                call PauseTimer(.T)
            endif
        endmethod
        
        private static method GroupCallback takes nothing returns nothing
        local unit u=GetEnumUnit()
        local Link l=Link[GetUnitId(u)]
        local real tx=GetUnitX(u)
        local real ty=GetUnitY(u)
        local real dx
        local real dy
        local real ang
        local real d
            if ValidateTarget(u, .tmps) then
                set dx=tx-GetUnitX(.tmps.Ward)
                set dy=ty-GetUnitY(.tmps.Ward)
                set ang=Atan2(dy, dx)
                set d=RMaxBJ(SquareRoot(dx*dx+dy*dy)-l.Dist, 0.) // we dont want to keep the unit at a certain distance; Just at a maximum distance
                set d=d*DISTANCE_CHANGE_SPEED
                set tx=tx-d*Cos(ang)
                set ty=ty-d*Sin(ang)
                call SetUnitX(u, tx)
                call SetUnitY(u, ty)
                call MoveLightningEx(l.Light, true, GetUnitX(.tmps.Ward), GetUnitY(.tmps.Ward), .GetUnitZ(.tmps.Ward)+LINK_LIGHTNING_ZOFFSET, tx, ty, .GetUnitZ(u)+LINK_LIGHTNING_ZOFFSET)
                call UnitDamageTarget(.tmps.Caster, u, d*Dmg_Factor(.tmps.Level), true, true, DMG_ATTACK_TYPE, DMG_DAMAGE_TYPE, null)
            else // unit died/activated magic immunity
                call DestroyLightning(l.Light)
                set l.Light=null
                call DestroyEffect(l.FX)
                set l.FX=null
                call GroupRemoveUnit(.tmps.Affected, u)
            endif
            set u=null
        endmethod
        
        private static method Callback takes nothing returns nothing
        local integer i=.Count-1
        local thistype s
            loop
                exitwhen i<0
                set s=.Structs[i]
                if IsUnitType(s.Ward, UNIT_TYPE_DEAD)==false then
                    set .tmps=s
                    call ForGroup(s.Affected, function thistype.GroupCallback)
                else
                    call s.destroy() // Ward got killed/expired
                endif
                set i=i-1
            endloop
        endmethod
        
        private static method UnitFilterFunc takes nothing returns boolean
        local unit u=GetFilterUnit()
        local integer id
        local real dx
        local real dy
            if ValidateTarget(u, .tmps) then
                set id=GetUnitId(u)
                set dx=GetUnitX(u)-GetUnitX(.tmps.Ward)
                set dy=GetUnitY(u)-GetUnitY(.tmps.Ward)
                set Link[id].Light=AddLightningEx(LINK_LIGHTNING_TYPE, true, GetUnitX(.tmps.Ward), GetUnitY(.tmps.Ward), .GetUnitZ(.tmps.Ward)+LINK_LIGHTNING_ZOFFSET, GetUnitX(u), GetUnitY(u), .GetUnitZ(u)+LINK_LIGHTNING_ZOFFSET)
                call SetLightningColor(Link[id].Light, LINK_LIGHTNING_RED, LINK_LIGHTNING_GREEN, LINK_LIGHTNING_BLUE, LINK_LIGHTNING_ALPHA)
                set Link[id].FX=AddSpecialEffectTarget(LINK_FX, u, LINK_FX_ATTPT)
                set Link[id].Dist=SquareRoot(dx*dx+dy*dy)
                set u=null
                return true
            endif
            set u=null
            return false
        endmethod
        
        static method create takes unit caster, real x, real y returns thistype
        local thistype s=.allocate()
            set s.Caster=caster
            set s.Level=GetUnitAbilityLevel(s.Caster, AID)
            set s.Ward=CreateUnit(GetOwningPlayer(caster), Ward_Uid(s.Level), x, y, GetUnitFacing(caster))
            call UnitApplyTimedLife(s.Ward, 'BTLF', Duration(s.Level))
            set s.Affected=NewGroup()
            set .tmps=s
            call GroupEnumUnitsInArea(s.Affected, x, y, Aoe(s.Level), .UnitFilter) // this is actually part of GroupUtils
            
            set .Structs[.Count]=s
            set s.i=.Count
            if .Count==0 then
                call TimerStart(.T, TICK, true, function thistype.Callback)
            endif
            set .Count=.Count+1
            return s
        endmethod
        
        private static method onInit takes nothing returns nothing
            set .UnitFilter=Condition(function thistype.UnitFilterFunc)
            
            call SetUpWARD_UID()
            call SetUpAOE()
            call SetUpDURATION()
            call SetUpDMG_FACTOR()
        endmethod
    endstruct
    
    private function Actions takes nothing returns nothing
        call Data.create(SpellEvent.CastingUnit, SpellEvent.TargetX, SpellEvent.TargetY)
    endfunction
    
    private function Init takes nothing returns nothing
        call RegisterSpellEffectResponse(AID, Actions)
    endfunction
    
endlibrary
 

Attachments

  • WC3ScrnShot_112909_102702_02.jpg
    WC3ScrnShot_112909_102702_02.jpg
    266 KB · Views: 552
  • Deaod_MagicChains_1.0.0.w3x
    59.2 KB · Views: 122
Level 10
Joined
Jun 1, 2008
Messages
485
Umm, can I get some help from you guys?

Every time I test my map, before the map even loaded, wc3 will get fatal error.

I check my code, and nothing is wrong in my opinion.
I check the map's object editor stuff and dummy model, and still nothing seem wrong to me.

Anybody mind to help me?

P.S: I attach the map
I use vJASS
Here's the code:
JASS:
scope ThunderBird initializer InitTrig_Initialize
    globals
        private constant integer SpellID        = 'A000'
        private constant integer DummyID        = 'n000'
        private constant string DummyAttach     = "chest"
        
        private constant real Duration          = 5.
        private constant real DurationIncr      = 5.
        private constant real EggDuration       = 1.
        private constant real EggDurationIncr   = 0.5
        
        private constant real BirdHeight        = 100
        private constant real PassingBirdHeight = 400
        
        private constant real Damage            = 50.
        private constant real DamageIncr        = 25.
        private constant real ManaDmg           = 50.
        private constant real ManaIncr          = 25.
        
        private constant real SlowAmount        = 0.25
        private constant real SlowIncr          = 0.1
        private constant real SlowDur           = 1.
        private constant real SlowDurIncr       = 0.5
        
        private constant integer BirdSum        = 3
        private constant integer BirdIncr       = 1
        
        private constant real AoE               = 250.
        private constant real AoEIncr           = 100.
        private constant real ManaAoE           = 100.
        private constant real ManaAoEIncr       = 25.
        
        private constant real MoveSpeed         = 50.
        private constant real AngSpeed          = 0.25
        
        private constant string BirdModel       = "Abilities\\Weapons\\KeeperGroveMissile\\KeeperGroveMissile.mdl"
        private constant string PassBirdModel   = "units\\human\\phoenix\\phoenix.mdl"
        private constant string EggModel        = "Units\\Human\\Phoenix\\PhoenixEgg.mdl"
        private constant string AttachEffect    = "Abilities\\Spells\\Orc\\Purge\\PurgeBuffTarget.mdl"
        private constant string DeathEffect     = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl"
        private constant string BirthEffect     = "Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl"
        private constant string DmgEffect       = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
        private constant string ManaEffect      = "Abilities\\Weapons\\ProcMissile\\ProcMissile.mdl"
        private constant string BuffEffect      = "Abilities\\Spells\\Items\\AIlb\\AIlbSpecialArt.mdl"
        
        private constant real TimeOut           = 0.01
                                                
        private constant attacktype ATT         = ATTACK_TYPE_NORMAL
        private constant damagetype DGT         = DAMAGE_TYPE_NORMAL
        private constant weapontype WPT         = WEAPON_TYPE_WHOKNOWS
        
        private real array R
    endglobals
    private struct Struct3
        unit Affected
        real SlowAmount
        real TimeLeft
        effect Sfx
        
        static group Buffed
        
        static Struct3 array Index
        static integer Total
        static timer Timer
        
        static method Loop takes nothing returns nothing
            local Struct3 dat
            local integer i = 0
            loop
                exitwhen i >= Struct3.Total
                set dat = Struct3.Index[i]
                set dat.TimeLeft = dat.TimeLeft-TimeOut
                if dat.TimeLeft <= 0. then
                    call SetUnitMoveSpeed(dat.Affected,GetUnitMoveSpeed(dat.Affected)+dat.SlowAmount)
                    call DestroyEffect(dat.Sfx)
                    if IsUnitInGroup(dat.Affected,Struct3.Buffed) then
                        call GroupRemoveUnit(Struct3.Buffed,dat.Affected)
                    endif
                    call dat.destroy()
                    set Struct3.Total = Struct3.Total-1
                    set Struct3.Index[i] = Struct3.Index[Struct3.Total]
                    set i = i-1
                endif
                set i = i+1
            endloop
        endmethod
        
        static method Create takes unit u, real SlowAmount, real Duration, string Sfx returns nothing
            local Struct3 dat = Struct3.allocate()
            set dat.Affected = u
            call SetUnitMoveSpeed(u,GetUnitMoveSpeed(u)-SlowAmount)
            set dat.SlowAmount = SlowAmount
            set dat.TimeLeft = Duration
            set dat.Sfx = AddSpecialEffectTarget(Sfx,u,"chest")            
            if Struct3.Total == 0 then
                call TimerStart(Struct3.Timer,TimeOut,true,function Struct3.Loop)
            endif
            set Struct3.Index[Struct3.Total] = dat
            set Struct3.Total = Struct3.Total+1
        endmethod
    endstruct
    private struct Struct1
        unit Caster
        unit Bird
        unit Target
        real Angle
        real UnitX
        real UnitY
        real CentralX
        real CentralY
        real TimeLeft
        real HatchTime
        integer ActID
        integer level
        effect Sfx
        effect Sfx2
        
        static unit Temp
        
        static Struct1 array Index
        static integer Total
        static timer Timer
        
        static method IsEnemy takes nothing returns boolean
            return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(Struct1.Temp))
        endmethod
        
        static method Loop takes nothing returns nothing
            local Struct1 dat
            local integer i = 0
            local group g
            local unit u            
            loop
                exitwhen i >= Struct1.Total
                set dat = Struct1.Index[i]
                set dat.TimeLeft = dat.TimeLeft-TimeOut
                if dat.ActID == 0 then
                    set dat.HatchTime = dat.HatchTime-TimeOut
                    set Struct1.Temp = dat.Caster
                    call GroupEnumUnitsInRange(g,GetUnitX(dat.Bird),GetUnitY(dat.Bird),ManaAoE+(ManaAoEIncr*dat.level),Condition(function Struct1.IsEnemy))
                    loop
                        set u = FirstOfGroup(g)
                        exitwhen u == null
                        call GroupRemoveUnit(g,u)           
                        call SetUnitState(u,UNIT_STATE_MANA,GetUnitState(u,UNIT_STATE_MANA)-((ManaDmg+(ManaIncr*dat.level))*TimeOut))     
                        call AddSpecialEffect(ManaEffect,GetUnitX(u),GetUnitY(u))
                    endloop
                    set Struct1.Temp = null
                    if dat.HatchTime <= 0. then
                        call DestroyEffect(AddSpecialEffect(BirthEffect,GetUnitX(dat.Bird),GetUnitY(dat.Bird))) 
                        call DestroyEffect(dat.Sfx)
                        set dat.Sfx = AddSpecialEffectTarget(BirdModel,dat.Bird,DummyAttach)
                        set dat.Sfx2 = AddSpecialEffectTarget(AttachEffect,dat.Bird,DummyAttach)
                        call SetUnitFlyHeight(dat.Bird,BirdHeight,100.)
                        set dat.ActID = 1
                    endif
                elseif dat.ActID == 1 then
                    set R[0] = Atan2(dat.UnitY-GetUnitY(dat.Bird),dat.UnitX-GetUnitX(dat.Bird))    
                    set R[1] = GetUnitX(dat.Bird)+MoveSpeed*Cos(R[0])
                    set R[2] = GetUnitY(dat.Bird)+MoveSpeed*Cos(R[0])                    
                    call SetUnitX(dat.Bird,R[1])
                    call SetUnitY(dat.Bird,R[2])
                    call SetUnitFacing(dat.Bird,bj_RADTODEG*R[0])
                    set R[3] = R[1]-dat.UnitX
                    set R[4] = R[2]-dat.UnitY             
                    if  SquareRoot(R[3]*R[3]+R[4]*R[4]) <= 50. then
                        set dat.ActID = 2
                    endif
                elseif dat.ActID == 2 then
                    set dat.Angle = dat.Angle+AngSpeed
                    set dat.UnitX = dat.CentralX+(AoE+AoEIncr*dat.level)*Cos(dat.Angle*bj_DEGTORAD)
                    set dat.UnitY = dat.CentralY+(AoE+AoEIncr*dat.level)*Sin(dat.Angle*bj_DEGTORAD)            
                    call SetUnitX(dat.Bird,dat.UnitX)
                    call SetUnitY(dat.Bird,dat.UnitY)
                    call SetUnitFacing(dat.Bird,dat.Angle+90.)
                    set Struct1.Temp = dat.Caster
                    call GroupEnumUnitsInRange(g,dat.CentralX,dat.CentralY,AoE+(AoEIncr*dat.level),Condition(function Struct1.IsEnemy))
                    loop                        
                        set u = FirstOfGroup(g)
                        exitwhen u == null
                        call GroupRemoveUnit(g,u)
                        if not IsUnitInGroup(u,Struct3.Buffed) and dat.Target == null then
                            call GroupAddUnit(Struct3.Buffed,u)
                            set dat.Target = u
                            set dat.ActID = 3
                        endif
                    endloop
                    set Struct1.Temp = null
                    if dat.Angle >= 360. then
                        set dat.Angle = dat.Angle-360.
                    endif
                elseif dat.ActID == 3 then
                    set dat.Angle = dat.Angle+AngSpeed
                    set dat.UnitX = dat.CentralX+(AoE+AoEIncr*dat.level)*Cos(dat.Angle*bj_DEGTORAD)
                    set dat.UnitY = dat.CentralY+(AoE+AoEIncr*dat.level)*Sin(dat.Angle*bj_DEGTORAD)            
                    set R[0] = Atan2(GetUnitY(dat.Target)-GetUnitY(dat.Bird),GetUnitX(dat.Target)-GetUnitX(dat.Bird))
                    set R[1] = GetUnitX(dat.Bird)+MoveSpeed*Cos(R[0])
                    set R[2] = GetUnitY(dat.Bird)+MoveSpeed*Sin(R[0])
                    set R[3] = GetUnitX(dat.Target)-GetUnitX(dat.Bird)
                    set R[4] = GetUnitY(dat.Target)-GetUnitY(dat.Bird)
                    set R[5] = SquareRoot(R[3]*R[3]+R[4]*R[4])
                    call SetUnitX(dat.Bird,R[1])
                    call SetUnitY(dat.Bird,R[2])
                    call SetUnitFacing(dat.Bird,bj_RADTODEG*R[0])
                    if R[5] <= 100 then
                        call DestroyEffect(AddSpecialEffect(DmgEffect,GetUnitX(dat.Target),GetUnitY(dat.Target)))
                        call UnitDamageTarget(dat.Caster,dat.Target,Damage+(DamageIncr*dat.level),true,false,ATT,DGT,WPT)
                        call Struct3.Create(dat.Target,GetUnitMoveSpeed(dat.Target)*(SlowAmount+(SlowIncr*dat.level)),SlowDur+(SlowDurIncr*dat.level),BuffEffect)
                        set dat.Target = null
                        set dat.ActID = 4
                    endif
                    if dat.Angle >= 360. then
                        set dat.Angle = dat.Angle-360.
                    endif
                elseif dat.ActID == 4 then
                    set dat.Angle = dat.Angle+AngSpeed
                    set dat.UnitX = dat.CentralX+(AoE+AoEIncr*dat.level)*Cos(dat.Angle*bj_DEGTORAD)
                    set dat.UnitY = dat.CentralY+(AoE+AoEIncr*dat.level)*Sin(dat.Angle*bj_DEGTORAD)            
                    set R[0] = Atan2(GetUnitY(dat.Bird)-dat.UnitY,GetUnitX(dat.Bird)-dat.UnitX)
                    set R[1] = GetUnitX(dat.Bird)+MoveSpeed*Cos(R[0])
                    set R[2] = GetUnitY(dat.Bird)+MoveSpeed*Sin(R[0])
                    set R[3] = GetUnitX(dat.Bird)-dat.UnitX
                    set R[4] = GetUnitY(dat.Bird)-dat.UnitY
                    set R[5] = SquareRoot(R[3]*R[3]+R[4]*R[4])
                    call SetUnitX(dat.Bird,R[1])
                    call SetUnitY(dat.Bird,R[2])
                    call SetUnitFacing(dat.Bird,bj_RADTODEG*R[0])
                    if R[5] <= 100 then
                        call SetUnitX(dat.Bird,dat.UnitX)
                        call SetUnitY(dat.Bird,dat.UnitY)
                        call SetUnitFacing(dat.Bird,dat.Angle+90.)
                        set dat.ActID = 2
                    endif
                    if dat.Angle >= 360. then
                        set dat.Angle = dat.Angle-360.
                    endif
                endif
                if dat.TimeLeft <= 0 then
                    call DestroyEffect(AddSpecialEffectTarget(DeathEffect,dat.Bird,DummyAttach))
                    call DestroyEffect(dat.Sfx)
                    call DestroyEffect(dat.Sfx2)
                    set dat.Caster = null
                    set dat.Bird = null
                    set dat.Target = null
                    call RemoveUnit(dat.Bird)
                    call dat.destroy()
                    set Struct1.Total = Struct1.Total-1                    
                    set Struct1.Index[i] = Struct1.Index[Struct1.Total]                    
                    set i = i-1
                endif
                set i = i+1                 
            endloop
            set g = null
            set u = null
            if Struct1.Total == 0 then
                call PauseTimer(Struct1.Timer)
            endif
        endmethod
        
        static method Start takes unit Caster, real BirdSum, real Counter, real X, real Y, real Time, real Time2, integer level returns nothing
            local Struct1 dat = Struct1.allocate()
            set dat.Caster = Caster
            set dat.ActID = 0
            set dat.level = level
            set dat.Angle = (360/BirdSum)*Counter
            set dat.TimeLeft = Time
            set dat.HatchTime = Time2
            set dat.CentralX = X
            set dat.CentralY = Y
            set dat.UnitX = X+(AoE+AoEIncr*level)*Cos(dat.Angle*bj_DEGTORAD)
            set dat.UnitY = Y+(AoE+AoEIncr*level)*Sin(dat.Angle*bj_DEGTORAD)
            set R[1] = GetSpellTargetX()+GetRandomReal(0.,AoE+(AoEIncr*level))*Cos(GetRandomReal(0.,360.)*bj_DEGTORAD)
            set R[2] = GetSpellTargetY()+GetRandomReal(0.,AoE+(AoEIncr*level))*Sin(GetRandomReal(0.,360.)*bj_DEGTORAD)
            set dat.Bird = CreateUnit(GetOwningPlayer(Caster),DummyID,R[1],R[2],0.)
            call UnitAddAbility(dat.Bird,'Arav')
            call UnitRemoveAbility(dat.Bird,'Arav')
            call SetUnitFlyHeight(dat.Bird,0.,0.)
            set dat.Sfx = AddSpecialEffectTarget(EggModel,dat.Bird,DummyAttach)            
            if dat.Total == 0 then
                call TimerStart(Struct1.Timer, TimeOut, true, function Struct1.Loop)
            endif
            set Struct1.Index[Struct1.Total] = dat
            set Struct1.Total = Struct1.Total+1
        endmethod        
    endstruct
    
    private struct Struct2
        unit Caster
        unit PassingBird
        real CentralX
        real CentralY
        integer level
        real Time
        real Time2
        effect Sfx
        
        static Struct2 array Index
        static integer Total
        static timer Timer
        
        static method Loop takes nothing returns nothing
            local Struct2 dat
            local integer i = 0
            loop
                exitwhen i == Struct2.Total
                set dat = Struct2.Index[i]
                set R[0] = GetUnitFacing(dat.PassingBird)
                set R[1] = GetUnitX(dat.PassingBird)+MoveSpeed*Cos(R[0]*bj_DEGTORAD)
                set R[2] = GetUnitY(dat.PassingBird)+MoveSpeed*Sin(R[0]*bj_DEGTORAD)
                set R[3] = dat.CentralX-R[1]
                set R[4] = dat.CentralY-R[2]
                set R[5] = SquareRoot(R[3]*R[3]+R[4]*R[4])
                call SetUnitX(dat.PassingBird,R[1])
                call SetUnitY(dat.PassingBird,R[2])
                if R[5] <= 100. then
                    set R[7] = BirdSum+(BirdIncr*R[6])
                    set R[8] = 0
                    loop
                        exitwhen R[8] == R[9]
                        call Struct1.Start(dat.PassingBird,R[7],R[8],dat.CentralX,dat.CentralY,dat.Time,dat.Time2,dat.level)
                        set R[8] = R[8]+1
                    endloop
                    call DestroyEffect(AddSpecialEffectTarget(DeathEffect,dat.PassingBird,DummyAttach))
                    call DestroyEffect(dat.Sfx)
                    call RemoveUnit(dat.PassingBird)
                    call dat.destroy()
                    set Struct2.Total = Struct2.Total-1
                    set Struct2.Index[i] = Struct2.Index[Struct2.Total]
                    set i = i-1    
                endif
                set i = i+1
            endloop
            if Struct2.Total == 0 then
                call PauseTimer(Struct2.Timer)
            endif
        endmethod
        
        static method Create takes nothing returns nothing
            local Struct2 dat = Struct2.allocate()
            local unit u = GetTriggerUnit()
            set dat.Caster = u
            set dat.level = GetUnitAbilityLevel(u,SpellID)-1
            set dat.CentralX = GetSpellTargetX()
            set dat.CentralY = GetSpellTargetY()
            set dat.Time = Duration+(DurationIncr*dat.level)
            set dat.Time2 = EggDuration+(EggDurationIncr*R[0])
            set dat.PassingBird = CreateUnit(GetOwningPlayer(u),DummyID,GetUnitX(u),GetUnitY(u),0.)
            call UnitAddAbility(dat.PassingBird,'Arav')
            call UnitRemoveAbility(dat.PassingBird,'Arav')
            call SetUnitFlyHeight(dat.PassingBird,PassingBirdHeight,0.)
            set dat.Sfx = AddSpecialEffectTarget(PassBirdModel,dat.PassingBird,DummyAttach)
            call DestroyEffect(AddSpecialEffectTarget(BirthEffect,dat.PassingBird,DummyAttach))
            if dat.Total == 0 then
                call TimerStart(Struct2.Timer,TimeOut,true,function Struct2.Loop)
            endif
            set Struct2.Index[Struct2.Total] = dat
            set Struct2.Total = Struct2.Total+1
        endmethod      
    endstruct
    private function Conditions takes nothing returns boolean       
        return GetSpellAbilityId() == SpellID
    endfunction

    private function Actions takes nothing returns nothing
        call Struct2.Create()
    endfunction

    private function ReturnTrue takes nothing returns boolean
        return true
    endfunction
    
    private function InitTrig_Initialize takes nothing returns nothing
        local trigger t = CreateTrigger()         
        local integer index = 0
        loop
            exitwhen index == bj_MAX_PLAYER_SLOTS
            set index = index+1
            call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,Filter(function ReturnTrue))
        endloop
        call TriggerAddCondition(t, Condition(function Conditions))
        call TriggerAddAction(t, function Actions)
    endfunction
endscope
EDIT:
I post it in Trigger and Script forum
 

Attachments

  • Thunder Bird v1.0 [MG].w3x
    62 KB · Views: 120
Level 10
Joined
Jun 1, 2008
Messages
485
Remember to disable RtC, as RtC doesnt work with the latest patch.
I do. I never enable it from first.
btw, it's still 4 days before deadline, right? I've still got many time.

Some (stupid) question:
Is any Object Editor Spell allowed? I mean some heavily modified object editor spell like this.
Is it will reduce the judging point a lot? I'm just curious.
 
Last edited:
Level 14
Joined
Nov 18, 2007
Messages
816
I think youd lose at least 30% of all possible points (those related to Coding, since pure Object Editor hackjobs dont involve any coding).
You might very well be disqualified for not coding at all in a so-called "coding competition" (although id argue that its a spell creation contest with stupid rules).

I figured out your problem, btw: Youre calling Player(16) in your initialization function. Unlike in GUI Player(0) is red Player(1) blue and so on. There are only 16 players, so Player(15) is the last valid player. Player() is one of the few natives that can crash the game when supplied with invalid arguments.
Why are you inlining TriggerRegisterAnyUnitEventBJ anyway? Its one of the more useful BJs. And dont worry about leaks. null boolexprs never leaked in TriggerRegisterPlayerUnitEvent calls in the first place.
 
Level 13
Joined
Jun 22, 2004
Messages
783
Ill enter this contest as well.
**Dimensional Influence**

My spell is about complete, I am running a couple of last minor MUI bug testings(yes my spell is completely made in GUI), removing the last bits of leaks, and perhaps replacing some effects.

For now only screenshots of the tooltip for I am still working on the effects.
 

Attachments

  • Dimensional Influence01.jpg
    Dimensional Influence01.jpg
    30.3 KB · Views: 85
  • Dimensional Influence02.jpg
    Dimensional Influence02.jpg
    31.6 KB · Views: 82
Level 23
Joined
Nov 29, 2006
Messages
2,482
@ Daeod, your spell looks nice, but I think I've seen that before somewhere. Meh but it works good and so on and so forth :) And about the stupid wip rule, there are none. It just says you are to provide a wip. If that is the map or a video or an image or anything, it's up to yourself:p
 
Level 10
Joined
Jun 1, 2008
Messages
485
I think youd lose at least 30% of all possible points (those related to Coding, since pure Object Editor hackjobs dont involve any coding).
You might very well be disqualified for not coding at all in a so-called "coding competition" (although id argue that its a spell creation contest with stupid rules).
hm, so this is a coding-competition. well, it's also a bad thing to make object-editor-heavily-modified-spell though. it will be very hard to make and harder to import to other map.
I figured out your problem, btw: Youre calling Player(16) in your initialization function. Unlike in GUI Player(0) is red Player(1) blue and so on. There are only 16 players, so Player(15) is the last valid player. Player() is one of the few natives that can crash the game when supplied with invalid arguments.
Why are you inlining TriggerRegisterAnyUnitEventBJ anyway? Its one of the more useful BJs. And dont worry about leaks. null boolexprs never leaked in TriggerRegisterPlayerUnitEvent calls in the first place.
Oh, so this is it! thank you:xxd:!
so TriggerRegisterPlayerUnitEvent never leak boolexpr? this is a new info for me.
@ Daeod, your spell looks nice, but I think I've seen that before somewhere. Meh but it works good and so on and so forth :) And about the stupid wip rule, there are none. It just says you are to provide a wip. If that is the map or a video or an image or anything, it's up to yourself:p
Eccho, so WIP can be a map? thanks for the info:smile:.

[offtopic]ah, I get another error/bug/whatever-it-called, maybe vJASS hate me, my spell never run bug-free on me....[/offtopic]
 
Level 5
Joined
Oct 26, 2009
Messages
161
Eccho said:
And about the stupid wip rule, there are none. It just says you are to provide a wip. If that is the map or a video or an image or anything, it's up to yourself:p
As far as I'm concerned, posting a finished map and then updating it once or twice to fix minor bugs makes your original submission the WIP.
 
Level 12
Joined
Aug 31, 2008
Messages
1,121
I am now trying to enter this contest. I will really have to pull to get done before the deadline.
Btw, can I post my WIP with my submission?
EDIT: scratch that. I'm out. I got stuff to do, and my code was "spagetti code" anyway.
good luck to the contestants!
 
Last edited:
Level 20
Joined
Apr 22, 2007
Messages
1,960
Since apparently it's necessary to post a WIP, I guess this will be mine.

My spell is a no-target cast. It summons a monster which digs itself around the caster in random motion, leaving trails of dirt and vines. If units are within a certain range of the caster, then it digs towards them and either bites or ensnares them (not too sure about this part yet). If a unit walks across the vine trail, then it loses move speed (or something).

lawlz
 
Level 16
Joined
Feb 22, 2006
Messages
960
hm so I have a name for my spell :p

Ritual of Vengeance

^^

in general it summons a Lyrium Spirit which profits from hostile units sorrounding it, u will see in what way... on death it releases the sucked spirit power to save the caster from physical damage for up to 20seconds or untill the damage limit is reached
 
Level 5
Joined
Oct 26, 2009
Messages
161
I wish more people were making spells that were closer in functionality to the example spells; right now it seems like virtually everyone is just doing some AOE damage/disable effect tacked onto a single/few unit summon that isn't/aren't even user-controlled. AOE summon skills like Rain of Chaos or Animate Dead focus on summoning multiple user-controlled units in special ways (multi-meteors / corpses).
 
Level 25
Joined
Jun 5, 2008
Messages
2,572
@Duragon

Blame the rules, not the participant, it should have stated "User controlled units" in the rules if you really want that kind of spells.

Btw i think mine spell is a good hybrid of both aspects, the units can't be controlled directly, but they can be killed, targeted, and affected by spells :p
 
Level 5
Joined
Oct 26, 2009
Messages
161
Kingz said:
Blame the rules, not the participant, it should have stated "User controlled units" in the rules if you really want that kind of spells.
Nah, I do blame the participant as well. Just because the rules are intentionally vague doesn't mean the entrants should make spells that barely feel like summoning skills. So many entries have been using the summons as special effects instead of legit summons.
 
Status
Not open for further replies.
Top