Warcraft Zone Control - 2nd Edition

PiCkstix

New Member
Reaction score
18
No offense but it looks like its gonna be kind of boring, not enough info given . . . Although you probably have abandoned the map anyway so ye . . .:p
 

Doomhammer

Bob Kotick - Gamers' corporate spoilsport No. 1
Reaction score
67
@ PiCkstix. That's no offense at all once you see the details: this map has been worked on a lot already and it's far from dead, it's simply very extensive! The current ver is .90, which means 90 saves already whenever I had a major breakthrough which required saving. According to the editor it's map version 2273, which is the amount of times I pressed the save-button.

Thing is, that I've been working a lot over the last two months with not too much time for Map-Making, and barely any time online. :mad:

The good thing however is that even without internet I've achieved an awesome lot of work for this map. :) The main achievement after a a few weeks of brain-and jaw-braking, I finalized my custom motion system which will from now on add a lot more fun to my spells. I already pimped some of my spells with it. For those following this thread I will publish a pre-release of my motion system right here in the next post.
 

Doomhammer

Bob Kotick - Gamers' corporate spoilsport No. 1
Reaction score
67
CMS - Custom Motion System

History:

Writing this was a bit like cooking: take a bit of knockback,
squeeze out the juice of a jump system, add some rotation,
mix in motion queuing, finish it up with a strong look on
collections, and spread it all out on vJass...yummy yummy,
dinner is served!


Functionality - What can it do?

basically, this is meant to make your spells more fun: have units fly through the air and knocked back on ground
with a bunch of basic commands.


*Knockbacks&Slides
Operate with the parameters speed and (negative) acceleration to get a slide or knockback effect
if effects are set, your slider gets a dust effect on ground and a splash effect on water

*Jumps
Operate with the parameters speed and height to get a jump effect
if effects are set here, an additional e.g. to get a burning trail is attached to your flyer

*Rotations
The linear movements named above can easily be "upgraded" to add circular motions around
the positions as marked by the linear trajectory using the parameters radius, radius increment, angle speed,
angle acceleration and facing speed.

*Collisions
Sliders can collide with other sliders and non-sliders, which affects their movement speed and direction.
(still in progress)

*Motion Queuing
Motion Queuing allows you to setup whole "choreographies" for units. Simply mark a motion as
"queued", attach it to a previously set motion, and the system will work off one motion after the other.


Maximum efficiency - Pimp my code!

Thanks to vJass, code can be written in a highly efficient manner. To get to the maximum possible efficiency
in terms of computing, I strictly followed a set of rules:

*No game-cache related variable attachment
*As few function calls as possible
*As little calculation as possible in the timer child functions:
-Do without trigonometric functions for all the linear motions
-Precalculate as much data as possible before calling the child function
-Additional handles such as groups, effects and rects are created once and used on instances as long as necessary
(instead of creating and destroying them on every timer call)
*optionally the whole system can be paused when no units are to be moved around, so its timer won't be "running empty"

Requirements:
*Jass NewGen


Credits:

Credits go to vile for his knockback system and for his knockback effects, to Waldbaer for his jump system, and to cohadar for his collections.
Big Thanks to all the Grimoire and vJass gosus and last but not least to SFLIP for writing TESH, which changed in-WE-codewriting
from demonic pain to holy pleasure ;)



JASS:
    library CustomMotions initializer init_cm

	globals
		private constant real move_interval=0.04
		private constant real move_minhitspeed=30.0  //minimum speed to knockback units and desroy doodads
		private constant integer move_flyability='Amrf'
		private constant string move_slidewater="MDX\\SlideWater.mdx" 
		private constant string move_slideground="MDX\\Dust.mdx"
		private constant string move_flyburning="Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeDamageTarget.mdl"
                 private timer move_timer
		private group move_hitgroup=CreateGroup() 
		private rect move_r
                 public boolexpr move_hitfilter
		public boolexpr move_destfilter
                 private boolean timer_pause=false
                 public integer extent = 0		
                 public move array MO
                 move cm_lastAddedMove  //to be used in the same way as bj globals: see multijump example for further reference
	endglobals
    
private function UnitInMO takes unit u returns integer
    local integer i = 0
    loop
        exitwhen (i>=extent)
        if u == MO<i>.u then
            return i
        endif
        set i = i + 1
    endloop
    return -1
endfunction

private function dont_hit takes nothing returns boolean  //dont affect those unit types: 2=structure, 3=flying, 9=giant
	local unit u=GetFilterUnit()
	local boolean b
	set b=(GetWidgetLife(u)&gt;0.405) and not (IsUnitType(u, ConvertUnitType(2)) or IsUnitType(u, ConvertUnitType(3)) or IsUnitType(u, ConvertUnitType(9)))
	set u=null
	return b
endfunction

private function IsDestructableVulnerable takes nothing returns boolean
	return not(IsDestructableInvulnerable(GetEnumDestructable()))
endfunction

private function DamageDestructable takes nothing returns nothing
	call SetWidgetLife(GetEnumDestructable(),GetWidgetLife(GetEnumDestructable())-bj_enumDestructableRadius)
endfunction  //use bj_enumDestructableRadius as damage

private function init_cm takes nothing returns nothing
	set move_destfilter=Filter(function IsDestructableVulnerable)
	set move_hitfilter=Filter(function dont_hit)
	set move_r=Rect(-128.0,-128.0,128.0,128.0)
        set MO[8190]=1
        set move_timer=CreateTimer()
endfunction

struct move
    unit u  //unit
    real x = 0.0  //initial x
    real y = 0.0  //initial y
    real z = 0.0  //initial z - NOT for slides and knockbacks
    real dx = 0.0 //difference target x - unit x
    real dy = 0.0 //difference target y - unit y
    real dz = 0.0 //difference target z - unit z
    real maxz = 0.0 //maximum flying height - NOT for slides and knockbacks
    real d = 0.0   //total distance
    real v = 0.0  // (initial) speed
    real a = 0.0  // acceleration
    real w = 0.0  // initial circling angle
    real vw = 0.0 // ciricling angle speed [degree/sec] note: should circle anticlockwise if negative
    real aw = 0.0 //circling acceleration
    real r = 0.0  //circling radius
    real vr = 0.0 //circling radius incremental - only if the radius is to be increased
    real vf = 0.0 //facing angle speed [degree/sec]
    real time = 0.0 //time passed travelling
    real ttime = 0.0 //total time
    integer anid  = -1 //unitanimationid while executing the move
    boolean effects = false  //sets if burning effect for jumpers or water/dust effect for sliders are shown
    boolean hitothers = false  //includes colliding units and destructables
    boolean wait = false // false: do motion; true: wait with (attached) motion
    integer continuewith = -1 //id of following struct if further structs are to be queued
    boolean water_soil = false // true for last terrain was water, false for was soil
    effect fx  //the special effect to be attached over time 
	
    static method set_motion takes unit u, real x, real y, real speed, real acceleration, real height, integer animationid, boolean hitothers, boolean effects, boolean queued returns move
		local move m=move.allocate()
        if timer_pause then
            call ResumeTimer(move_timer)
            call CustomMotions_StartCM.execute()
        endif
		set m.u=u
        set m.maxz=height
        set m.v=speed
        set m.a=acceleration
        set m.effects=effects
        if (animationid&gt;=0) then
            set m.anid=animationid
        endif
        set m.hitothers=hitothers
        if queued then
            set m.wait=true
            set m.x=x
            set m.y=y
        else
            set m.x=GetUnitX(u)
            set m.y=GetUnitY(u) 
            set m.dx=x-m.x
            set m.dy=y-m.y
            set m.d=SquareRoot(m.dx*m.dx+m.dy*m.dy+0.01)
            set m.w=Atan2(m.dy,m.dx)
            if (m.a==0.0) and (m.v!=0.0) then
                set m.ttime=m.d/m.v
            elseif (m.a!=0.0) then
                set m.ttime=(SquareRoot(m.v*m.v+2*m.a*m.d)-m.v)/m.a
            elseif (m.a==0.0) and (m.v==0.0) then
                set m.ttime=move_interval
            endif
            if (animationid&gt;=0) then
                call SetUnitAnimationByIndex(u,m.anid)
            endif
            if (height==0.0) then
                if effects then
                    if IsTerrainPathable(m.x,m.y,ConvertPathingType(6)) then
                        set m.water_soil=false
                        set m.fx=AddSpecialEffectTarget(move_slideground, m.u, &quot;right foot&quot;)
                    elseif not IsTerrainPathable(m.x,m.y,ConvertPathingType(1)) then
                        set m.water_soil=true
                        set m.fx=AddSpecialEffectTarget(move_slidewater, m.u, &quot;right foot&quot;)
                    endif
                endif
            else
                if effects then
                    set m.fx=AddSpecialEffectTarget(move_flyburning, m.u, &quot;chest&quot;)
                endif
                set m.z=GetLocationZ(GetUnitLoc(u))
                if (GetUnitFlyHeight(u)&gt;0.0) then
                    set m.z=m.z+GetUnitFlyHeight(u)
                endif
                set m.dz=GetLocationZ(Location(x,y))-m.z
                call SetUnitPathing(m.u, false)
                call UnitAddAbility(m.u, move_flyability)
                call UnitRemoveAbility(m.u, move_flyability)
            endif
        endif
        return m
    endmethod
    
    method reset_motion takes nothing returns nothing
        local real x=GetUnitX(.u)
        local real y=GetUnitY(.u)
        set .wait=false
        set .dx=.x-x
        set .dy=.y-y
        set .x=x
        set .y=y
        set .d=SquareRoot(.dx*.dx+.dy*.dy+0.01)
        set .w=Atan2(.dy,.dx)
        if (.a==0.0) and (.v!=0.0) then
            set .ttime=.d/.v
        elseif (.a!=0.0) then
            set .ttime=(SquareRoot(.v*.v+2*.a*.d)-.v)/.a
        elseif (.a==0.0) and (.v==0.0) then
            set .ttime=move_interval
        endif
        if (.anid&gt;=0) then
            call SetUnitAnimationByIndex(.u,.anid)
        endif
        if (.maxz==0.0) then 
            if .effects then
                if IsTerrainPathable(x,y,ConvertPathingType(6)) then
                    set .water_soil=false
                    set .fx=AddSpecialEffectTarget(move_slideground, .u, &quot;right foot&quot;)
                elseif not IsTerrainPathable(x,y,ConvertPathingType(1)) then
                    set .water_soil=true
                    set .fx=AddSpecialEffectTarget(move_slidewater, .u, &quot;right foot&quot;)
                endif
            endif
        else
            if .effects then
                set .fx=AddSpecialEffectTarget(move_flyburning, .u, &quot;chest&quot;)
            endif
            set .z=GetLocationZ(Location(x,y))
            if (GetUnitFlyHeight(.u)&gt;0.0) then
                set .z=.z+GetUnitFlyHeight(.u)
            endif
            set .dz=GetLocationZ(Location(.x+.dx,.y+.dy))-.z
            call SetUnitPathing(.u, false)
            call UnitAddAbility(.u, move_flyability)
            call UnitRemoveAbility(.u, move_flyability)
        endif    
    endmethod
    
    method add_spin takes real v_facing, real v_rot, real a_rot, real radius, real radiusincrement returns nothing
        set .vw=v_rot*bj_DEGTORAD
        set .aw=a_rot*bj_DEGTORAD
        set .r=radius
        set .vr=radiusincrement
        set .vf=v_facing
    endmethod
        
    static method add takes move m returns boolean
        if extent &lt; 8191 then
		    set MO[extent] = m
            set cm_lastAddedMove = m
		    set extent = extent + 1
			return true
		else
		    call BJDebugMsg(&quot;|C00FF0000ERROR: MO array overflow&quot;)
		    return false
		endif
    endmethod
    
    static method add_attach takes move m1, move m2 returns boolean
        if (m1.continuewith==-1) then
            set m1.continuewith=m2  //attaches next struct
            call move.add(m2)
            if (m2.wait==false) then
                set m2.wait=true
            endif
            return true
        endif
        call BJDebugMsg(&quot;|C00FF0000ERROR:Queue position for attached move already taken&quot;)
        return false
    endmethod
    
    static method col_speed takes real v1, real m1, real v2, real m2 returns real
        return (m1*v1+m2*(2*v2-v1))/(m1+m2)
    endmethod
    
    method collide takes real x, real y, unit u returns nothing
        local real dx=GetUnitX(u)-x
        local real dy=GetUnitY(u)-y
        local real d=SquareRoot(dx*dx+dy*dy+.1)
        local real m1=SquareRoot(GetUnitPointValue(.u))
        local real m2=SquareRoot(GetUnitPointValue(u))
        local real v=(2*.v*m1)/(m1+m2)
        local real w=Atan2(dy,dx)
        if UnitInMO(u)&gt;-1 then
        else //the construction site: to be finished!
            set.v=.v*(m1-m2)/(m1+m2)
        endif
    endmethod
    
    method do_hit takes real x, real y returns nothing
        local integer j
        local unit u
        call MoveRectTo(move_r,x,y)
        set bj_enumDestructableRadius=.v
        call EnumDestructablesInRect(move_r,move_destfilter, function DamageDestructable)
        call GroupEnumUnitsInRect(move_hitgroup,move_r,move_hitfilter)
        if FirstOfGroup(move_hitgroup)!=null then
            loop
                set u=FirstOfGroup(move_hitgroup)
                exitwhen u==null
                call this.collide(x,y,u)                
                call GroupRemoveUnit(move_hitgroup,u)
                //set u=null
            endloop
            call GroupClear(move_hitgroup)
        endif
    endmethod
	
	method do_motion takes nothing returns nothing
		local real x
		local real y
		local real d
        local integer i=0
        local boolean flying=((.maxz!=0.0)or(.dz!=0.0))
        local boolean spinning=((.vw!=0.0) or (.aw!=0.0) or (.r!=0.0) or (.vr!=0.0))
        if not(.wait) then
            set .time=.time+move_interval
            if (.time &lt; .ttime) then
                set d=(0.5*.a*.time*.time+.v*.time)/.d
                set x=.x+d*.dx
                set y=.y+d*.dy
                if .vf!=0.0 then 
                    call SetUnitFacing(.u, GetUnitFacing(.u)+.vf*.time)
                endif
                if spinning then  //add circling
                    set .r=.r+.vr*.time
                    set d=0.5*.aw*.time*.time+.vw*.time+.w
                    set x=x+.r*Cos(d)
                    set y=y+.r*Sin(d)
                endif
                call SetUnitPosition(.u,x,y)
                if flying then   //add z-movement
                    set d=.time/.ttime
                    call SetUnitFlyHeight(.u,(.z+4*.maxz*d*(1-d)+d*.dz-GetLocationZ(Location(x,y))),0)
                else	
                    if .effects then
                        if .water_soil and IsTerrainPathable(x,y,ConvertPathingType(6)) then
                            set .water_soil=false
                            call DestroyEffect(.fx)
                            set .fx=AddSpecialEffectTarget(move_slideground, .u, &quot;right foot&quot;)
                        elseif not.water_soil and not IsTerrainPathable(x,y,ConvertPathingType(6)) then
                            set .water_soil=true
                            call DestroyEffect(.fx)
                            set .fx=AddSpecialEffectTarget(move_slidewater, .u, &quot;right foot&quot;)
                        endif
                    endif
                    if .hitothers and (.v&gt;=move_minhitspeed) then
            //       call this.do_hit(x,y)
                    endif
                endif
            else
                if flying then
                    call SetUnitPathing(.u, true)
                    call SetUnitFlyHeight(.u,.z-GetLocationZ(Location(.x,.y)),0) 
                    if .hitothers and (.v&gt;=move_minhitspeed) and (.continuewith&lt;0) then
    //           call this.do_hit(GetUnitX(.u),GetUnitY(.u))  //hitting others at the end of a jump/toss
                    endif
                endif
                if (.continuewith&gt;=0) then   // checks if another motion is attached to the current one, and...
                    loop
                        exitwhen (i&gt;=extent)
                        if (MO<i>==.continuewith) then
                            call MO<i>.reset_motion() //...if so it is unfrozen and reset
                            exitwhen true
                        endif
                        set i=i+1
                    endloop
                endif   
                set i=0
                loop          // destroys current motion and sets the last struct in the array to its (free) position
                    exitwhen (i&gt;=extent)
                    if (this==MO<i>) then
                        call .destroy()
                        set extent = extent - 1
                        set MO<i> = MO[extent]
                        exitwhen true
                    endif
                    set i=i+1
                endloop
            endif
        endif
	endmethod
    
    method onDestroy takes nothing returns nothing
        if .fx!=null then
            call DestroyEffect(.fx)
            set .fx=null
        endif
        set .u=null
    endmethod
    
endstruct

public function TimerControl takes nothing returns nothing
    if (extent&lt;=0) and not(timer_pause) then
        call PauseTimer(move_timer)
        set timer_pause=true
    endif
endfunction

public function CM takes nothing returns nothing
    local integer i = 0
    loop
        exitwhen (i&gt;=extent)
        call MO<i>.do_motion()
        set i = i + 1
    endloop
endfunction

public function StartCM takes nothing returns nothing
    call TimerStart(move_timer,move_interval,true,function CM)
    set timer_pause=false
endfunction

    endlibrary
    
//===========================================================================
function InitTrig_MotionSystem takes nothing returns nothing
endfunction

</i></i></i></i></i></i>
 

Doomhammer

Bob Kotick - Gamers' corporate spoilsport No. 1
Reaction score
67
changes:

* made spawning system more efficient using vjass

* jass-enhanced shockwave with fire art also getting rid of the laggy terrain transformation

* improved multi-jump using CMS instead of two seperate gc based systems

* jass-enhanced warstomp with units getting tossed away using CMS

* jass-enhanced thunder clap with units getting knocked back using CMS

* made the Voodoo mage Shrink spell more efficient using vJass instead of gc

* added the Beastmaster Plunder Aura; an aura which gives player units around the Beastmaster a chance of gaining extra gold when attacking an enemy building

* finished the Beastmaster Flying Axes spell using vjass and ABC:
here's a little sample of the spell

JASS:
 scope axes requires ABC, CSSafety, HelperFunctions
    
globals
    constant integer axes_spellid = &#039;A04B&#039;
    private constant real width = 90.0
    private constant integer leftaxe_id = &#039;n010&#039;
    private constant integer rightaxe_id =&#039;n001&#039;
    private constant real speed = 800.0
    private constant real interval = 0.04
    private constant real spilldamage = 0.2 //spilldamage factor
    private constant real flyheight = 65
    private rect ax_rect
    private boolexpr unitfilter
    private boolexpr destfilter
    private unit u
endglobals

private constant function Damage takes integer level returns real
    return 90.0 + level * 60.0
endfunction

public function AxesInit takes nothing returns nothing
    set ax_rect=Rect(-64.0,-64.0,64.0,64.0)
    set unitfilter=Filter(function IsEnemy) 
    set destfilter=Filter(function IsDestructableVulnerable)
endfunction

private function DamageDestructable takes nothing returns nothing
	call SetWidgetLife(GetEnumDestructable(),GetWidgetLife(GetEnumDestructable())-bj_enumDestructableRadius)
endfunction  //use bj_enumDestructableRadius to transfer damage

struct axes
    unit array u[4]
    real array r[14]  //total axes instances limited to 585
    
    method set_axes takes unit c, unit u, player p returns nothing
        set .u[0]=c
        set .u[1]=u
        set .r[0]=0.0  //t
        set .r[1]=GetUnitX(c)  //x
        set .r[2]=GetUnitY(c)  //y
        set .r[3]=GetUnitX(u)-.r[1]  //dx
        set .r[4]=GetUnitY(u)-.r[2]  //dy
        set .r[5]=SquareRoot(.r[3]*.r[3]+.r[4]*.r[4]+.1)  //d
        set .r[6]=width/(.r[5]*.r[5]) //a
        set .r[7]=-width*.r[4]/.r[5]  //xa
        set .r[8]=width*.r[3]/.r[5]   //ya
        set .r[9]=Atan2(.r[4],.r[3])      //w
        set .r[10]=Sin(.r[9])
        set .r[11]=Cos(.r[9])
        if GetUnitFlyHeight(u)!=0 then
            set .r[12]=GetUnitFlyHeight(u)-flyheight
        else
            set .r[12]=0.0
        endif
        set .r[13]=flyheight
        set .u[2]=CreateUnit(p,leftaxe_id,.r[1]+.r[7],.r[2]+.r[8],bj_RADTODEG*.r[9])
        set .u[3]=CreateUnit(p,rightaxe_id,.r[1]-.r[7],.r[2]-.r[8],bj_RADTODEG*.r[9])
    endmethod
    
    method onDestroy takes nothing returns nothing
        local integer i=0
        call KillUnit(.u[2])
        call KillUnit(.u[3])
        loop
            exitwhen i&gt;3
            set .u<i>=null
            set i=i+1
        endloop
	endmethod
    
endstruct

function HurtGroup takes nothing returns nothing
    call UnitDamageTarget(u, GetEnumUnit(), bj_enumDestructableRadius, false, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, null)
endfunction 

function TwinAxes_child takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local axes ax=GetStructA(t)
    local group g=CreateGroup()
    local real ds
    local real x
    local real y
    local real xr
    local real yr
    local real dam=Damage(GetUnitAbilityLevel(ax.u[0],axes_spellid))
    set ax.r[0]=ax.r[0]+interval
    set ds=ax.r[0]*speed
    if ds&lt;ax.r[5] then
        if ax.r[12]!=0.0 then
            set ax.r[13]=flyheight+ax.r[12]*ds/ax.r[5]
        endif
        set u=ax.u[0]
        set x=ds
        set y=-ax.r[6]*ds*ds
        set xr=x*ax.r[11]-y*ax.r[10]
        set yr=y*ax.r[11]+x*ax.r[10]
        call SetUnitPosition(ax.u[2],ax.r[1]+ax.r[7]+xr,ax.r[2]+ax.r[8]+yr)
        call SetUnitFlyHeight(ax.u[2],ax.r[13],0)
        call MoveRectTo(ax_rect,ax.r[1]+ax.r[7]+xr,ax.r[2]+ax.r[8]+yr)
        set bj_enumDestructableRadius=dam*spilldamage
        set bj_forceRandomCurrentPick=GetOwningPlayer(ax.u[0])
        call EnumDestructablesInRect(ax_rect,destfilter,function DamageDestructable)
        call GroupEnumUnitsInRect(g,ax_rect,unitfilter)
        if FirstOfGroup(g)!=null then
            call ForGroup(g, function HurtGroup)
            call GroupClear(g)
        endif
        set xr=x*ax.r[11]+y*ax.r[10]
        set yr=x*ax.r[10]-y*ax.r[11]
        call SetUnitPosition(ax.u[3],ax.r[1]-ax.r[7]+xr,ax.r[2]-ax.r[8]+yr)
        call SetUnitFlyHeight(ax.u[3],ax.r[13],0)
        call MoveRectTo(ax_rect,ax.r[1]-ax.r[7]+xr,ax.r[2]-ax.r[8]+yr)
        call EnumDestructablesInRect(ax_rect,destfilter,function DamageDestructable)
        call GroupEnumUnitsInRect(g,ax_rect,unitfilter)
        if FirstOfGroup(g)!=null then
            call ForGroup(g, function HurtGroup)
            call GroupClear(g)
        endif
    else
        call GroupEnumUnitsInRange(g, ax.r[1]+ax.r[3],ax.r[2]+ax.r[4],150.0,null)
        if IsUnitInGroup(ax.u[1],g) then
            call UnitDamageTarget(ax.u[0],ax.u[1], dam, false, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, null)
        endif
        call ax.destroy()
        call ClearStructA(t)        
        call ReleaseTimer(t)    
    endif
endfunction

function TwinAxes takes nothing returns nothing
	local axes ax=axes.create()
    local unit u=GetTriggerUnit()
    local timer t=NewTimer()
    call ax.set_axes(u,GetSpellTargetUnit(),GetOwningPlayer(u))
    call SetUnitAnimationByIndex(u, 9)
    call SetStructA(t, ax)
    call TimerStart(t, interval, true, function TwinAxes_child)
endfunction

    endscope

//===========================================================================
function InitTrig_Axes takes nothing returns nothing
    call axes_AxesInit()
    call OnAbilityEffect(axes_spellid, &quot;TwinAxes&quot;)
endfunction</i>
 

Doomhammer

Bob Kotick - Gamers' corporate spoilsport No. 1
Reaction score
67
current state:

*added Beastmaster Bear Spell Frighten:

an insta AoE Spell that makes the Raging Bear roar so that enemy units run away afraid

*added Beastmaster Bear Spell Head Bite:

makes the Raging Bear kill an enemy ground unit instantly and converts 25% of its hitpoints to the Bear

*added Nightelf Shadow Walker Shadow Aura: Finally, the invisibility aura (pic)

*added the Windmaster Spell Draftback which creates a field of fierce wind around the Windmaster thus pushing enemy units back. Also sets a chance that ground units are tossed away and hurt

*minor changes: replaced the Elf Swordsmen with the Nightelf Huntress (model: "sentry"), which add a far better feeling for the Nightelf tier1 ground units; the Huntress is a bit weaker than a Swordsman, but a lot more cunning; further replaced the moon den with the ancient of war, which can be upgraded to produce archers.

Adding more and more spells as well as the defense mechanisms, I'll in near future release an alpha version. unprotected, so interested people here can learn some.
 

Attachments

  • invis.jpg
    invis.jpg
    241.1 KB · Views: 254

Prometheus

Everything is mutable; nothing is sacred
Reaction score
589
Just a question, are you making your spells hero specific, or are they MUI?
 

Doomhammer

Bob Kotick - Gamers' corporate spoilsport No. 1
Reaction score
67
Spells are totally MUI

Auras are hero-specific (to hero unit type id), and thus limited to 1 per player.
 

Parsimony

New Member
Reaction score
4
Yep, I'm still here. And the map, apparently, still ain't finished as well. It's been a
loooooooong time now... yep.

ding :)
 

Doomhammer

Bob Kotick - Gamers' corporate spoilsport No. 1
Reaction score
67
yeah, I wish I had more time for map making...

To get a first impression, here's a somewhat playable alpha version. It's open for close inspection ;)
There are definitely more spells to come, the motion engine needs a fix with collisions, and defensive structures will become defense sectors meaning that a whole set of buildings is to be created (e.g. 2 Cannon Towers and 2 Guard Towers) to pose one defense sector. After all, I'm also tinkering with the initial defense mechanism to make sure that at least the 'home zones' are sufficiently protected against combined attacks. Also I thought of adding some additional auras to zones.

I actually wanted to add and improve more stuff before releasing this, but here we go.

Orc heroes are in a pretty good state of development already, so Orcs are a good catch for a run-around.
 

Attachments

  • Warcraft Zone Control 0-94.w3x
    1.7 MB · Views: 244

Prometheus

Everything is mutable; nothing is sacred
Reaction score
589
I just read the post
CMS - Custom Motion System
I <3 Doomhammer
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top