• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Solved] Measuring a model's width?

Status
Not open for further replies.
Level 13
Joined
May 11, 2008
Messages
1,198
update: solved. +rep for grid size is 32x32 information.

so i was wondering if anyone made some map/system which measures the width of models. i'm not good with effects but i've been learning little by little and i'm wondering about the measurement of models because if i can for example figure out that a certain model at size of 1.0 has a width of 300 aoe then i can know increasing the size to 1.5 will make the model have a width of 450. but i'm not sure how to measure the models so any ideas about how to do it or if someone already has a proven method, i would like to know about it. maybe it's something very basic and simple that a model maker/editor would know but since i'm not one of those i don't know it.
 
Last edited:
Level 37
Joined
Mar 6, 2006
Messages
9,243
In World Editor's main window, press G to toggle grid. There are four option. No grid, large grid, medium grid and small grid. Press G until you can see the small grid.

Each of the very small squares is 32x32, medium squares are 128x128. Place the model and then you can quite accurately approximate the width.

You can use the mouse to track the coordinates for even more accurate width. The coordinates are shown in the lower left corner of the editor.
 
Level 13
Joined
May 11, 2008
Messages
1,198
hmm...no i don't think this is working as i expected it would. 0.5 model 4 tiny squares wide while 1.0 is 6 tiny wide

the results i'm finding is unit not getting big enough when increasing siz eand not gettting small enough when lowering size. is there some formula for model size i'm not aware of?
since .5 is half of 1.0 and 1.0 half of 2.0 you'd think the measurements would reflect that difference but they don't.
 
Last edited:
hmm...no i don't think this is working as i expected it would. 0.5 model 4 tiny squares wide while 1.0 is 6 tiny wide

the results i'm finding is unit not getting big enough when increasing siz eand not gettting small enough when lowering size. is there some formula for model size i'm not aware of?
since .5 is half of 1.0 and 1.0 half of 2.0 you'd think the measurements would reflect that difference but they don't.

Step 1: Take the measurements of about 6 or 7 different sizes.
Step 2: Try to find a relation between the ratios.

If you want, just post the results here, and I'll find the formula for you :)
 
Level 13
Joined
May 11, 2008
Messages
1,198
Step 1: Take the measurements of about 6 or 7 different sizes.
Step 2: Try to find a relation between the ratios.

If you want, just post the results here, and I'll find the formula for you :)

ah nevermind i think i figured it out...
JASS:
//add divine shield mdx for
//graphics...make the size get start small
//go to big...
//
//------------------------------------------------------------------------------------\\
//                               Magnetic Field [v3]                                  \\
//                                   by kenny!                                        \\
//                            Constructed using vJASS                                 \\
//                         Requires NewGen WE & GTrigger                              \\
//------------------------------------------------------------------------------------\\

scope ShieldApparition initializer onInit

    globals
        // Configurables:
        private constant integer ABIL_ID       = 'A07V'    // Raw code of the Magnetic Field ability.
        private constant integer DUMMY_ID      = 'u00Q'    // Raw code of the dummy unit used to destroy trees.
        private constant real    INTERVAL      = 0.03125   // Used in the periodic timer to move units.
        private constant real    COLLISION     = 150.00    // Area around the moving units in which trees will be destroyed.
        private constant real    DISTANCE      = 75.00     // DISTANCE for checking pathability. Should be at least 25.00 distance less than COLLISION!!!
        private constant string  CASTED_SFX    = "Abilities\\Spells\\Undead\\Darksummoning\\DarkSummonTarget.mdl"   // Special effect that is attached to the caster.
        private constant string  CASTED_POINT  = "origin"  // where the special effect is attached to the caster.
        private constant boolean DESTROY_TREES = true      // Whether or not to allow destroying trees.
        private constant boolean ALLOW_PRELOAD = true      // Whether or not to allow preloading of effects.
    endglobals

    private function Duration takes integer lvl returns real
        return 2.00 + (3.00 * lvl)
    endfunction

    private function Move_dist takes integer lvl returns real
        return 20.00 + (0.00 * lvl)
    endfunction

    private function Radius takes integer lvl returns real
        return 300.00 + (300.00 * lvl)
    endfunction

    //=======================================================================\\
    //   DO NOT TOUCH PAST THIS POINT UNLESS YOU KNOW WHAT YOU ARE DOING!    \\
    //=======================================================================\\
    
    public struct Data
    
        unit    cast    = null
        effect  sfx     = null
        real    time    = 0.00
        integer lvl     = 0
        
        static Data     array D
        static item     array Hidden
        static integer  Hidden_max   = 0
        static integer  DT           = 0
        static rect     Rect1        = null
        static timer    Timer        = null
        static group    Group        = null
        static unit     Tree_dummy   = null
        static item     Item         = null
        static boolexpr Tree_filt    = null
        static boolexpr Unit_filt    = null
        static real     Game_maxX    = 0.00
        static real     Game_minX    = 0.00
        static real     Game_maxY    = 0.00
        static real     Game_minY    = 0.00
        static real     Max_range    = 10.00

        static method hide takes nothing returns nothing
            if IsItemVisible(GetEnumItem()) then
                set .Hidden[.Hidden_max] = GetEnumItem()
                call SetItemVisible(.Hidden[.Hidden_max],false)
                set .Hidden_max = .Hidden_max + 1
            endif
        endmethod

        static method pathability takes real x1, real y1 returns boolean
            local real x2 = 0.00
            local real y2 = 0.00
            
            call SetRect(.Rect1,0.00,0.00,128.00,128.00)
            call MoveRectTo(.Rect1,x1,y1)
            call EnumItemsInRect(.Rect1,null,function Data.hide)

            call SetItemPosition(.Item,x1,y1)
            set x2 = GetItemX(.Item)
            set y2 = GetItemY(.Item)
            call SetItemVisible(.Item,false)

            loop
                exitwhen .Hidden_max <= 0
                set .Hidden_max = .Hidden_max - 1
                call SetItemVisible(.Hidden[.Hidden_max],true)
                set .Hidden[.Hidden_max] = null
            endloop

            return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) < .Max_range * .Max_range
        endmethod

        static method safex takes real x returns real
            if x < .Game_minX then
                return .Game_minX
            elseif x > .Game_maxX then
                return .Game_maxX
            endif
            return x
        endmethod

        static method safey takes real y returns real
            if y < .Game_minY then
                return .Game_minY
            elseif y > .Game_maxY then
                return .Game_maxY
            endif
            return y
        endmethod
        
        static method destroyenumtrees takes nothing returns nothing
            call KillDestructable(GetEnumDestructable())
        endmethod
        
        static method treefilt takes nothing returns boolean
            local destructable dest   = GetFilterDestructable()
            local boolean      result = false
            
            if GetDestructableLife(dest) > 0.405 then
                call ShowUnit(.Tree_dummy,true)
                call SetUnitX(.Tree_dummy,GetWidgetX(dest))
                call SetUnitY(.Tree_dummy,GetWidgetY(dest))
                
                set result = IssueTargetOrder(.Tree_dummy,"harvest",dest)
                call IssueImmediateOrder(.Tree_dummy,"stop")
                call ShowUnit(.Tree_dummy,false)
                
                set dest = null
                return result
            endif
            
            set dest = null
            return result
        endmethod
        
        static method unitfilt takes nothing returns boolean
            return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) == false
        endmethod
        
        private method onDestroy takes nothing returns nothing
            call DestroyEffect(.sfx)
            set .sfx = null
            set .cast = null
        endmethod
        
        static method update takes nothing returns nothing
            local Data    d      = 0
            local integer i      = 1
            local unit    u      = null
            local real    castx  = 0.00
            local real    casty  = 0.00
            local real    angle  = 0.00
            local real    sin    = 0.00
            local real    cos    = 0.00
            local real    ux     = 0.00
            local real    uy     = 0.00
            
            loop
                exitwhen i > .DT
                
                set d = .D[i]
                
                set castx = GetUnitX(d.cast)
                set casty = GetUnitY(d.cast)
                
                if d.time >= Duration(d.lvl) or GetWidgetLife(d.cast) < 0.405 then
                    call d.destroy()
                    set .D[i] = .D[.DT]
                    set .DT = .DT - 1
                    set i = i - 1
                else
                    call GroupEnumUnitsInRange(.Group,castx,casty,Radius(d.lvl),.Unit_filt)
                    call GroupRemoveUnit(.Group,d.cast)
                    loop
                        set u = FirstOfGroup(.Group)
                        exitwhen u == null
                        call GroupRemoveUnit(.Group,u)
                        set ux = GetUnitX(u)
                        set uy = GetUnitY(u)
                        set angle = Atan2((uy - casty),(ux - castx))
                        set sin = Sin(angle)
                        set cos = Cos(angle)
                        if .pathability(ux + DISTANCE * cos,uy + DISTANCE * sin) then
                            set ux = .safex(ux + Move_dist(d.lvl) * cos)
                            set uy = .safey(uy + Move_dist(d.lvl) * sin)
                            call SetUnitPosition(u,ux,uy)
                            if DESTROY_TREES then
                                call SetRect(.Rect1,ux - COLLISION,uy - COLLISION,ux + COLLISION,uy + COLLISION)
                                call EnumDestructablesInRect(.Rect1,.Tree_filt,function Data.destroyenumtrees)
                            endif                            
                        endif
                    endloop
                    
                    set d.time = d.time + INTERVAL
                endif
                
                set i = i + 1
            endloop
            
            if .DT <= 0 then
                call PauseTimer(.Timer)
                set .DT = 0
            endif               
                
            set u = null
        endmethod
        
        static method actions takes nothing returns boolean
            local Data d = Data.create()
            
            set d.cast = GetTriggerUnit()
            set d.lvl  = GetUnitAbilityLevel(d.cast,ABIL_ID)
            set d.sfx  = AddSpecialEffectTarget(CASTED_SFX,d.cast,CASTED_POINT)
            
            set .DT = .DT + 1
            set .D[.DT] = d
            if .DT == 1 then
                call TimerStart(.Timer,INTERVAL,true,function Data.update)
            endif
            
            return false
        endmethod

        static method onInit takes nothing returns nothing
            set .Timer     = CreateTimer()
            set .Group     = CreateGroup()
            set .Rect1     = Rect(0.00,0.00,1.00,1.00)
            set .Tree_filt = Filter(function Data.treefilt)
            set .Unit_filt = Filter(function Data.unitfilt)
            
            set .Game_maxX = GetRectMaxX(bj_mapInitialPlayableArea) - 64.00
            set .Game_maxY = GetRectMaxY(bj_mapInitialPlayableArea) - 64.00
            set .Game_minX = GetRectMinX(bj_mapInitialPlayableArea) + 64.00
            set .Game_minY = GetRectMinY(bj_mapInitialPlayableArea) + 64.00
            
            // Register event.
            call GT_AddStartsEffectAction(function Data.actions,ABIL_ID)
            
            set .Tree_dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),DUMMY_ID,400,-400,0.00)
            call SetUnitPathing(.Tree_dummy,false)
            call ShowUnit(.Tree_dummy,false)
            
            set .Item  = CreateItem('ciri',400,-400)
            call SetItemVisible(.Item,false)
            
            if ALLOW_PRELOAD then
                call DestroyEffect(AddSpecialEffect(CASTED_SFX,400,-400))
            endif            
        endmethod
    
    endstruct

endscope

actually eh....the circle isn't working so well because it's wider than it is long. perhaps that's what's been frustrating me so much.

WOOOOOOWWWWW.... this ring model is seeming pretty good because the size is actually changing...there's another circle model which has a size that is changing very little if at all...

ya i just realized that the displacement of the units was instantaneous, so that takes a lot of guess work out. if anyone's interested...here's the final code(includes some cjass, but that can be replaced if necessary)

you'll notice i can edit the x,y,z stuff if necessary later on...since the length does seem a little smaller than the width. that might mean increasing the y real by a small amount, i'm not sure. it can be fine-tuned later, i suppose.
JASS:
//------------------------------------------------------------------------------------\\
//                               Magnetic Field [v3]                                  \\
//                                   by kenny!                                        \\
//                            Constructed using vJASS                                 \\
//                         Requires NewGen WE & GTrigger                              \\
//                   Edited by SanKakU to have a visual boundary                      \\
//                            Constructed using cJASS                                 \\
//                            Model by JetFangInferno                                 \\
//               hiveworkshop.com/forums/models-530/divinering-50484                  \\
//------------------------------------------------------------------------------------\\

scope ShieldCK initializer onInit
globals
// Configurables:
private constant integer ABIL_ID='A07V'// Raw code of the Magnetic Field ability.
private constant integer DUMID='e00K'// Raw code of the dummy unit circle that shows boundary.
private constant integer DUMMY_ID='u00Q'// Raw code of the dummy unit used to destroy trees.
private constant real INTERVAL=0.03125// Used in the periodic timer to move units.
private constant real COLLISION=150.00// Area around the moving units in which trees will be destroyed.
private constant real DISTANCE=75.00 // DISTANCE for checking pathability. Should be at least 25.00 distance less than COLLISION!!!
private constant string  CASTED_SFX= "Abilities\\Spells\\Undead\\Darksummoning\\DarkSummonTarget.mdl"   // Special effect that is attached to the caster.
private constant string  CASTED_POINT  = "origin"  // where the special effect is attached to the caster.
private constant boolean DESTROY_TREES = true  // Whether or not to allow destroying trees.
private constant boolean ALLOW_PRELOAD = true  // Whether or not to allow preloading of effects.
endglobals
private real Radius (integer lvl){return 330.00 + (110.00 * lvl)}//MEASURED AGAINST MODEL SIZE
//SHOULD BE 110.00 FOR EVERY 1.00 OF MODEL SIZE...
private real scalex (integer lvl){return 3.00 + (1.00 * lvl)}//WIDTH
private real scaley (integer lvl){return 3.00 + (1.00 * lvl)}//LENGTH
//NEEDS SOME MINOR ADJUSTMENT...
private real scalez (integer lvl){return 1.00 + (0.00 * lvl)}//HEIGHT
private real Duration (integer lvl){return 4.00 + (6.00 * lvl)}//CHANGE AS DESIRED
private real Move_dist (integer lvl){return 20.0 + (0.00 * lvl)}//WOULDN'T ADVISE TOUCH THIS ONE
//END OF CONFIGURABLES

    
    public struct Data
    
        unit dum=null
        unit    cast    = null
        effect  sfx     = null
        real    time    = 0.00
        integer lvl     = 0
        
        static Data     array D
        static item     array Hidden
        static integer  Hidden_max   = 0
        static integer  DT           = 0
        static rect     Rect1        = null
        static timer    Timer        = null
        static group    Group        = null
        static unit     Tree_dummy   = null
        static item     Item         = null
        static boolexpr Tree_filt    = null
        static boolexpr Unit_filt    = null
        static real     Game_maxX    = 0.00
        static real     Game_minX    = 0.00
        static real     Game_maxY    = 0.00
        static real     Game_minY    = 0.00
        static real     Max_range    = 10.00

        static method hide takes nothing returns nothing
            if IsItemVisible(GetEnumItem()) then
                set .Hidden[.Hidden_max] = GetEnumItem()
                call SetItemVisible(.Hidden[.Hidden_max],false)
                set .Hidden_max = .Hidden_max + 1
            endif
        endmethod

        static method pathability takes real x1, real y1 returns boolean
            local real x2 = 0.00
            local real y2 = 0.00
            
            call SetRect(.Rect1,0.00,0.00,128.00,128.00)
            call MoveRectTo(.Rect1,x1,y1)
            call EnumItemsInRect(.Rect1,null,function Data.hide)

            call SetItemPosition(.Item,x1,y1)
            set x2 = GetItemX(.Item)
            set y2 = GetItemY(.Item)
            call SetItemVisible(.Item,false)

            loop
                exitwhen .Hidden_max <= 0
                set .Hidden_max = .Hidden_max - 1
                call SetItemVisible(.Hidden[.Hidden_max],true)
                set .Hidden[.Hidden_max] = null
            endloop

            return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) < .Max_range * .Max_range
        endmethod

        static method safex takes real x returns real
            if x < .Game_minX then
                return .Game_minX
            elseif x > .Game_maxX then
                return .Game_maxX
            endif
            return x
        endmethod

        static method safey takes real y returns real
            if y < .Game_minY then
                return .Game_minY
            elseif y > .Game_maxY then
                return .Game_maxY
            endif
            return y
        endmethod
        
        static method destroyenumtrees takes nothing returns nothing
            call KillDestructable(GetEnumDestructable())
        endmethod
        
        static method treefilt takes nothing returns boolean
            local destructable dest   = GetFilterDestructable()
            local boolean      result = false
            
            if GetDestructableLife(dest) > 0.405 then
                call ShowUnit(.Tree_dummy,true)
                call SetUnitX(.Tree_dummy,GetWidgetX(dest))
                call SetUnitY(.Tree_dummy,GetWidgetY(dest))
                
                set result = IssueTargetOrder(.Tree_dummy,"harvest",dest)
                call IssueImmediateOrder(.Tree_dummy,"stop")
                call ShowUnit(.Tree_dummy,false)
                
                set dest = null
                return result
            endif
            
            set dest = null
            return result
        endmethod
        
        static method unitfilt takes nothing returns boolean
            return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) == false
        endmethod
        
        private method onDestroy takes nothing returns nothing
            call DestroyEffect(.sfx)
            RemoveUnit(.dum)
            set .sfx = null
            set .cast = null
        endmethod
        
        static method update takes nothing returns nothing
            local Data    d      = 0
            local integer i      = 1
            local unit    u      = null
            local real    castx  = 0.00
            local real    casty  = 0.00
            local real    angle  = 0.00
            local real    sin    = 0.00
            local real    cos    = 0.00
            local real    ux     = 0.00
            local real    uy     = 0.00
            
            loop
                exitwhen i > .DT
                
                set d = .D[i]
                
                set castx = GetUnitX(d.cast)
                set casty = GetUnitY(d.cast)
                call SetUnitPosition(d.dum,castx,casty)
                
                if d.time >= Duration(d.lvl) or GetWidgetLife(d.cast) < 0.405 then
                    call d.destroy()
                    set .D[i] = .D[.DT]
                    set .DT = .DT - 1
                    set i = i - 1
                else
                    call GroupEnumUnitsInRange(.Group,castx,casty,Radius(d.lvl),.Unit_filt)
                    call GroupRemoveUnit(.Group,d.cast)
                    loop
                        set u = FirstOfGroup(.Group)
                        exitwhen u == null
                        call GroupRemoveUnit(.Group,u)
                        set ux = GetUnitX(u)
                        set uy = GetUnitY(u)
                        set angle = Atan2((uy - casty),(ux - castx))
                        set sin = Sin(angle)
                        set cos = Cos(angle)
                        if .pathability(ux + DISTANCE * cos,uy + DISTANCE * sin) then
                            set ux = .safex(ux + Move_dist(d.lvl) * cos)
                            set uy = .safey(uy + Move_dist(d.lvl) * sin)
                            call SetUnitPosition(u,ux,uy)
                            if DESTROY_TREES then
                                call SetRect(.Rect1,ux - COLLISION,uy - COLLISION,ux + COLLISION,uy + COLLISION)
                                call EnumDestructablesInRect(.Rect1,.Tree_filt,function Data.destroyenumtrees)
                            endif                            
                        endif
                    endloop
                    
                    set d.time = d.time + INTERVAL
                endif
                
                set i = i + 1
            endloop
            
            if .DT <= 0 then
                call PauseTimer(.Timer)
                set .DT = 0
            endif               
                
            set u = null
        endmethod
        
        static method actions takes nothing returns boolean
            local Data d = Data.create()
            
            set d.cast = GetTriggerUnit()
            set d.lvl  = GetUnitAbilityLevel(d.cast,ABIL_ID)
           set d.sfx  = AddSpecialEffectTarget(CASTED_SFX,d.cast,CASTED_POINT)
           set d.dum = CreateUnit(GetOwningPlayer(d.cast),DUMID,GetUnitX(d.cast),GetUnitY(d.cast),GetUnitFacing(d.cast))
           SetUnitScale(d.dum,scalex(d.lvl),scaley(d.lvl),scalez(d.lvl))
           
           
            
            set .DT = .DT + 1
            set .D[.DT] = d
            if .DT == 1 then
                call TimerStart(.Timer,INTERVAL,true,function Data.update)
            endif
            
            return false
        endmethod

        static method onInit takes nothing returns nothing
            set .Timer     = CreateTimer()
            set .Group     = CreateGroup()
            set .Rect1     = Rect(0.00,0.00,1.00,1.00)
            set .Tree_filt = Filter(function Data.treefilt)
            set .Unit_filt = Filter(function Data.unitfilt)
            
            set .Game_maxX = GetRectMaxX(bj_mapInitialPlayableArea) - 64.00
            set .Game_maxY = GetRectMaxY(bj_mapInitialPlayableArea) - 64.00
            set .Game_minX = GetRectMinX(bj_mapInitialPlayableArea) + 64.00
            set .Game_minY = GetRectMinY(bj_mapInitialPlayableArea) + 64.00
            
            // Register event.
            call GT_AddStartsEffectAction(function Data.actions,ABIL_ID)
            
            set .Tree_dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),DUMMY_ID,400,-400,0.00)
            call SetUnitPathing(.Tree_dummy,false)
            call ShowUnit(.Tree_dummy,false)
            
            set .Item  = CreateItem('ciri',400,-400)
            call SetItemVisible(.Item,false)
            
            if ALLOW_PRELOAD then
                call DestroyEffect(AddSpecialEffect(CASTED_SFX,400,-400))
            endif            
        endmethod
    
    endstruct

endscope
 
Last edited:
Status
Not open for further replies.
Top