• 🏆 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!

[JASS] Need suggestive feedback

Status
Not open for further replies.
Level 14
Joined
Apr 20, 2009
Messages
1,543
Is there any way of increasing the performance of this trigger?:

JASS:
function IsInRect takes real x1, real y1,real x2, real y2,real x3, real y3,real x4, real y4,real px, real py returns boolean
    local real d1 = SquareRoot((x1-px) * (x1-px) + (y1-py) * (y1-py))
    local real d2 = SquareRoot((x2-px) * (x2-px) + (y2-py) * (y2-py))
    local real d3 = SquareRoot((x3-px) * (x3-px) + (y3-py) * (y3-py))
    local real d4 = SquareRoot((x4-px) * (x4-px) + (y4-py) * (y4-py))
    local real s1 = SquareRoot((x1-x2) * (x1-x2) + (y1-y2) * (y1-y2))
    local real s2 = SquareRoot((x2-x3) * (x2-x3) + (y2-y3) * (y2-y3))
    local real s3 = SquareRoot((x3-x4) * (x3-x4) + (y3-y4) * (y3-y4))
    local real s4 = SquareRoot((x4-x1) * (x4-x1) + (y4-y1) * (y4-y1))
    local real cos1 = (d1*d1+d2*d2-s1*s1)/ (2 * (d1*d2))
    local real cos2 = (d2*d2+d3*d3-s2*s2)/ (2 * (d2*d3))
    local real cos3 = (d3*d3+d4*d4-s3*s3)/ (2 * (d3*d4))
    local real cos4 = (d4*d4+d1*d1-s4*s4)/ (2 * (d4*d1))
    local real output = cos1+cos2+cos3+cos4
    return output < 0
endfunction

function checkIfUnitsOnBridge takes nothing returns nothing
    local group g = CreateGroup()
    local unit u
    local unit cliffDummy = gg_unit_h000_0012
    local location cliffDummyLoc = GetUnitLoc(cliffDummy)
    local real uZ
    local real uX
    local real uY
    local real cliffZ = GetLocationZ(cliffDummyLoc)
    local real heightDifference
    call RemoveLocation(cliffDummyLoc)
    set cliffDummyLoc = null
    set cliffDummy = null
    call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        if IsInRect(udg_CornerX1Rect[2], udg_CornerY1Rect[2], udg_CornerX2Rect[2], udg_CornerY2Rect[2], udg_CornerX3Rect[2], udg_CornerY3Rect[2], udg_CornerX4Rect[2], udg_CornerY4Rect[2], GetUnitX(u), GetUnitY(u)) or IsInRect(udg_CornerX1Rect[3], udg_CornerY1Rect[3], udg_CornerX2Rect[3], udg_CornerY2Rect[3], udg_CornerX3Rect[3], udg_CornerY3Rect[3], udg_CornerX4Rect[3], udg_CornerY4Rect[3], GetUnitX(u), GetUnitY(u)) then
                if GetUnitUserData(u) == null then
                    set udg_unit_user_data = udg_unit_user_data + 1
                    call SetUnitUserData(u, udg_unit_user_data)
                endif
                if GetUnitUserData(u) != null and (udg_is_on_bridge_unit[GetUnitUserData(u)] == 2) then
                    set udg_is_on_bridge_unit[GetUnitUserData(u)] = 1
                    call UnitAddAbility(u, 'Amrf')
                    call SetUnitFlyHeight(u, 0.00, 0.00)
                    call UnitRemoveAbility(u, 'Amrf')
                endif
                if GetUnitUserData(u) != null and (udg_is_on_bridge_unit[GetUnitUserData(u)] == 0) then
                    set udg_is_on_bridge_unit[GetUnitUserData(u)] = 1
                endif
        endif
        if IsInRect(udg_CornerX1Rect[1], udg_CornerY1Rect[1], udg_CornerX2Rect[1], udg_CornerY2Rect[1], udg_CornerX3Rect[1], udg_CornerY3Rect[1], udg_CornerX4Rect[1], udg_CornerY4Rect[1], GetUnitX(u), GetUnitY(u)) and udg_is_on_bridge_unit[GetUnitUserData(u)] == 1 or udg_is_on_bridge_unit[GetUnitUserData(u)] == 2 then
                set udg_is_on_bridge_unit[GetUnitUserData(u)] = 2
                call UnitAddAbility(u, 'Amrf')
                set udg_uLoc[GetUnitUserData(u)] = GetUnitLoc(u)
                set uZ = GetLocationZ(udg_uLoc[GetUnitUserData(u)])
                set heightDifference = cliffZ-uZ+40
                call SetUnitFlyHeight(u, heightDifference, 0.00)
                call UnitRemoveAbility(u, 'Amrf')
        endif
        
        if (not(IsInRect(udg_CornerX1Rect[1], udg_CornerY1Rect[1], udg_CornerX2Rect[1], udg_CornerY2Rect[1], udg_CornerX3Rect[1], udg_CornerY3Rect[1], udg_CornerX4Rect[1], udg_CornerY4Rect[1], GetUnitX(u), GetUnitY(u)))) and udg_is_on_bridge_unit[GetUnitUserData(u)] == 2 then
            set uX = GetLocationX(udg_uLoc[GetUnitUserData(u)])
            set uY = GetLocationY(udg_uLoc[GetUnitUserData(u)])
            call SetUnitX(u, uX)
            call SetUnitY(u, uY)
        endif
        
        if (not(IsInRect(udg_CornerX1Rect[1], udg_CornerY1Rect[1], udg_CornerX2Rect[1], udg_CornerY2Rect[1], udg_CornerX3Rect[1], udg_CornerY3Rect[1], udg_CornerX4Rect[1], udg_CornerY4Rect[1], GetUnitX(u), GetUnitY(u)))) and (not(IsInRect(udg_CornerX1Rect[2], udg_CornerY1Rect[2], udg_CornerX2Rect[2], udg_CornerY2Rect[2], udg_CornerX3Rect[2], udg_CornerY3Rect[2], udg_CornerX4Rect[2], udg_CornerY4Rect[2], GetUnitX(u), GetUnitY(u)))) and (not(IsInRect(udg_CornerX1Rect[3], udg_CornerY1Rect[3], udg_CornerX2Rect[3], udg_CornerY2Rect[3], udg_CornerX3Rect[3], udg_CornerY3Rect[3], udg_CornerX4Rect[3], udg_CornerY4Rect[3], GetUnitX(u), GetUnitY(u)))) and udg_is_on_bridge_unit[GetUnitUserData(u)] == 1 then
            call RemoveLocation(udg_uLoc[GetUnitUserData(u)])
            set udg_uLoc[GetUnitUserData(u)] = null
            set udg_is_on_bridge_unit[GetUnitUserData(u)] = 0
        endif
        call GroupRemoveUnit(g, u)
    endloop
    set g = null
endfunction

function InitTrig_Bridges takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterTimerEvent( t, 0.03, true )
    call TriggerAddAction( t, function checkIfUnitsOnBridge )
    set t = null
endfunction
 
Last edited:
For simplicity, I would do something like this:
JASS:
globals
    region unitInRectRegion = CreateRegion()
endglobals

function IsUnitInRect takes unit u, rect r returns boolean
    local boolean b 
    call RegionAddRect(unitInRectRegion, r)
    set b = IsUnitInRegion(unitInRectRegion, u)
    call RegionClearRect(unitInRectRegion, r)
    return b
endfunction

Or even this:
http://www.thehelper.net/forums/showthread.php/59915-IsUnitInRect?p=527979#post527979

It will make the code a lot simpler and neater.

Also, since you need to use UnitAddAbility(u, 'Amrf') and the remove equivalent, you should just use a script like AutoFly.
http://www.thehelper.net/forums/showthread.php/139729-AutoFly

That will allow you to cut down on a few of the unnecessary functions. [if you implement that, you don't have to add and remove the ability at all]

Once you make those changes, it will be easier to see if there are any further optimizations you can make. Good luck. :)
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
It's not only to determine if a unit is in a rectangle, but also any other geometrical shape. As long as it has 4 points.
It checks wether the unit is in the customized shape (which I will call rect).

This way I can create rects like these:
customrects.jpg


Take refference here: http://www.hiveworkshop.com/forums/...98/question-about-invisible-platforms-212271/

I've created 3 of them. 1 on a clif infront of a bridge one on the other side of the bridge and one of the bridge itself.
Whenever a unit enters the first or last rect it sets units_on_bridge to 1 so that whenever the unit enters the bridge rect it will set it to 2 so that it starts using the crowform bug in order to fly above the ground on the same height as the bridge.
Respectively since the first and second rect are on top of the cliff other units can simultaniously walk underneath the bridge since they did not get units_on_bridge set to 1 but to 0.

Refference Image:
refference.jpg


This seems to completely work so that's not an issue.
I'm just wondering if it's possible to optimize it.

PurgeandFire111 said:
Also, since you need to use UnitAddAbility(u, 'Amrf') and the remove equivalent, you should just use a script like AutoFly.
http://www.thehelper.net/forums/show...139729-AutoFly

Will this really help that much?
I know that it'll use less function calls making it more efficient.
But is it really that noticeable?

PurgeandFire111 said:
It won't work for my system if I use this. I need my own custom rect system...

As soon as I have time to learn more about vJass I'll try to re-create it in vJass.
I might want to use structs for the custom rects so that it's easyer to specify them...
 
Last edited:
Level 17
Joined
Nov 13, 2006
Messages
1,814
what i noticed this work well event with more than 4 point until all degree inside is lower than 180, else give false result

but anyway, i am lazy, could be nice if u make test map :pPPPP

(i hope u just joking with make in vjass, coz i dont like the vjass, often srew up my map when i start jassing :D)

why u use group also if u use why dont use just a global variable, coz example i use everywhere a global unit group for temp thing, so its less with 1 create group and 1 destroy and null group :p

i think about u can use linked list, who enter to one of the 1 area add to unit list and check his position periodical in another trigger, when he leave remove from linked list, or if enter to bridge add to the another linked list, maybe that faster

also u can use path blockers or doodas for make walls to 2 side when unit on bridge
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
what i noticed this work well event with more than 4 point until all degree inside is lower than 180, else give false result

Are you saying that there is a bug in your system ^.^? Could you elaborate?

but anyway, i am lazy, could be nice if u make test map :pPPPP

I probably will soon...

why u use group also if u use why dont use just a global variable, coz example i use everywhere a global unit group for temp thing, so its less with 1 create group and 1 destroy and null group :p

Lol if you're looking at it this way then why not use only global variables instead xD? I hope you get my point :p
EDIT: PurplePoot prove your point xD My bad...

i think about u can use linked list, who enter to one of the 1 area add to unit list and check his position periodical in another trigger, when he leave remove from linked list, or if enter to bridge add to the another linked list, maybe that faster

Good suggestion that would optimize it quite a bit. I'll be working on this.

also u can use path blockers or doodas for make walls to 2 side when unit on bridge

Actually, I set the position of the unit to the previous position within the bridge area when the unit is within the bridge and when the assigned value of that unit is 2. This way whenever the unit wants to leave the bridge while it's on top from either one of the two sides it's position will be set to the position before leaving the rect. This looks quite natural and works flawlessly.

(i hope u just joking with make in vjass, coz i dont like the vjass, often srew up my map when i start jassing :D)

Actually, I was not joking. However if I make a vJass version I will also post a Jass version for those who don't like vJass.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Unless this has changed in my long absence (which I doubt), the general preferred method of handling GetLocationZ is something along the lines of this:

JASS:
globals
    location someLocation = Location(0,0)
endglobals

...

function ...
    local unit u = ...
    local real height
    call MoveLocation(someLocation,GetUnitX(u),GetUnitY(u))
    set height = GetLocationZ(someLocation)
endfunction

Similarly, for enums:

JASS:
globals
    group theG = CreateGroup()
endglobals

...

function ...
    call GroupEnumUnitsIn...(theG,...)
    {group loop or ForGroup or whatever}
endfunction

Both allow you to skip the whole creation/destruction of handles unnecessarily.
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
Unless this has changed in my long absence (which I doubt), the general preferred method of handling GetLocationZ is something along the lines of this:

JASS:
globals
    location someLocation = Location(0,0)
endglobals

...

function ...
    local unit u = ...
    local real height
    call MoveLocation(someLocation,GetUnitX(u),GetUnitY(u))
    set height = GetLocationZ(someLocation)
endfunction

Similarly, for enums:

JASS:
globals
    group theG = CreateGroup()
endglobals

...

function ...
    call GroupEnumUnitsIn...(theG,...)
    {group loop or ForGroup or whatever}
endfunction

Both allow you to skip the whole creation/destruction of handles unnecessarily.

Thank you! This makes a lot of sense to me and helps me improve my system! :)
+rep

I just learned something new here :D
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Are you saying that there is a bug in your system ^.^? Could you elaborate?

Lol if you're looking at it this way then why not use only global variables instead xD? I hope you get my point :p

1. its not bug but its just simple if u add all degree and it is higher than 360 and this math based on 360 grade then obviously dont work, but this kinda impossible in your case, mostly when u make a bridge with 5 side instead 4

2. its somthing like purge said because in vjass globals kinda similiar than globals in gui just shorter the name when u use in jass :p
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
1. its not bug but its just simple if u add all degree and it is higher than 360 and this math based on 360 grade then obviously dont work, but this kinda impossible in your case, mostly when u make a bridge with 5 side instead 4

2. its somthing like purge said because in vjass globals kinda similiar than globals in gui just shorter the name when u use in jass :p

1. I understand, thank you.
2. Yeah I noticed that with PurplePoot's post. I added a EDIT to that too :)
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Oh, you should also be nesting your ifs.

JASS:
if {statement a} and {statement b} then
    {code Y}
endif

if {statement a} and {statement c} and {statement d} and {statement e} then
    {code Z}
endif

might be better expressed as

if {statement a} then
    if {statement b} then
        {code Y}
    elseif {statement c} and {statement d} and {statement e}
        {code Z}
    endif
endif

if {statement a} is long, such as one of your giant rect checks.
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
Thank you, I'll make it more readable as suggested.
By the way why are you using brackets? {}
I understand that it is possible to use these in Zinc, but are you using them as a refference to show what you mean?
Then wouldn't it be more logical to use ()? Unless this was for some kind of purpose ofcourse :S?
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Thank you, I'll make it more readable as suggested.
By the way why are you using brackets? {}
I understand that it is possible to use these in Zinc, but are you using them as a refference to show what you mean?
Then it would be more logical to use () right?
No particular reason. I was just using them because they aren't valid code.

--

More disjointed thoughts: use ==0 rather than ==null (and !=0 rather than !=null) when comparing to integers (such as GetUnitUserData). Null works fine but still, it's ugly. You seem to be mostly checking to avoid errors in arrays, but I can't think of a single time in my modding history where I had an issue with a "returns integer" function returning null.

In addition, I don't see why your code looks like this even assuming that integer funcs could return null:

JASS:
if {userdata is null} then
    {fix the issue}
endif

if {userdata is still null} and {other stuff} then //how would userdata still be null? You fixed the issue
    ...
endif
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
No particular reason. I was just using them because they aren't valid code.

--

More disjointed thoughts: use ==0 rather than ==null (and !=0 rather than !=null) when comparing to integers (such as GetUnitUserData). Null works fine but still, it's ugly. You seem to be mostly checking to avoid errors in arrays, but I can't think of a single time in my modding history where I had an issue with a "returns integer" function returning null.

In addition, I don't see why your code looks like this even assuming that integer funcs could return null:

JASS:
if {userdata is null} then
    {fix the issue}
endif

if {userdata is still null} and {other stuff} then //how would userdata still be null? You fixed the issue
    ...
endif

Thank you once again, you're helping me big time here :goblin_good_job:
It would be more logical doing this indeed even though null works aswell.

I don't know what I was thinking when creating the second if for userdata.
I must have been stoned at that moment... I'll remove this. :goblin_boom:
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
still buggy with 1st floor, at cliff have few problem :/
but work, u can use 3 floor


header
JASS:
function UnitOnRect takes unit u, integer bridge returns boolean
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    return RectContainsCoords(LoadRectHandle(udg_Bridge_Table, bridge, 14), x, y) or RectContainsCoords(LoadRectHandle(udg_Bridge_Table, bridge, 15), x, y)
endfunction

function UnitOnBridge takes unit u, integer bridge returns boolean
    local real x1 = LoadReal(udg_Bridge_Table, bridge, 1)
    local real y1 = LoadReal(udg_Bridge_Table, bridge, 2)
    local real x2 = LoadReal(udg_Bridge_Table, bridge, 3)
    local real y2 = LoadReal(udg_Bridge_Table, bridge, 4)
    local real x3 = LoadReal(udg_Bridge_Table, bridge, 5)
    local real y3 = LoadReal(udg_Bridge_Table, bridge, 6)
    local real x4 = LoadReal(udg_Bridge_Table, bridge, 7)
    local real y4 = LoadReal(udg_Bridge_Table, bridge, 8)
    local real px = GetUnitX(u)
    local real py = GetUnitY(u)
    local real d1 = SquareRoot((x1 - px) * (x1 - px) + (y1 - py) * (y1 - py))
    local real d2 = SquareRoot((x2 - px) * (x2 - px) + (y2 - py) * (y2 - py))
    local real d3 = SquareRoot((x3 - px) * (x3 - px) + (y3 - py) * (y3 - py))
    local real d4 = SquareRoot((x4 - px) * (x4 - px) + (y4 - py) * (y4 - py))
    local real s1 = LoadReal(udg_Bridge_Table, bridge, 10)
    local real s2 = LoadReal(udg_Bridge_Table, bridge, 11)
    local real s3 = LoadReal(udg_Bridge_Table, bridge, 12)
    local real s4 = LoadReal(udg_Bridge_Table, bridge, 13)
    local real cos1 = (d1 * d1 + d2 * d2 - s1 * s1) / (2 * (d1 * d2))
    local real cos2 = (d2 * d2 + d3 * d3 - s2 * s2) / (2 * (d2 * d3))
    local real cos3 = (d3 * d3 + d4 * d4 - s3 * s3) / (2 * (d3 * d4))
    local real cos4 = (d4 * d4 + d1 * d1 - s4 * s4) / (2 * (d4 * d1))
    local real output = cos1 + cos2 + cos3 + cos4

    //call DisplayTextToForce( GetPlayersAll(), " x1 " + R2S(x1) + " y1 " + R2S(y1) + " s1 " + R2S(s1) + " d1 " + R2S(d1))
    //call DisplayTextToForce( GetPlayersAll(), " x2 " + R2S(x2) + " y2 " + R2S(y2) + " s2 " + R2S(s2) + " d2 " + R2S(d2))
    //call DisplayTextToForce( GetPlayersAll(), " x3 " + R2S(x3) + " y3 " + R2S(y3) + " s3 " + R2S(s3) + " d3 " + R2S(d3))
    //call DisplayTextToForce( GetPlayersAll(), " x4 " + R2S(x4) + " y4 " + R2S(y4) + " s4 " + R2S(s4) + " d4 " + R2S(d4))
    //call DisplayTextToForce( GetPlayersAll(), "Output" + R2S(output) )

    return output < 0.01
endfunction

function MakeBridgeFromCoord takes real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4, real height returns nothing
    local real s1 = SquareRoot((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
    local real s2 = SquareRoot((x2 - x3) * (x2 - x3) + (y2 - y3) * (y2 - y3))
    local real s3 = SquareRoot((x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4))
    local real s4 = SquareRoot((x4 - x1) * (x4 - x1) + (y4 - y1) * (y4 - y1))
    set udg_Bridge_Table_Index = udg_Bridge_Table_Index + 1
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 1, x1)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 2, y1)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 3, x2)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 4, y2)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 5, x3)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 6, y3)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 7, x4)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 8, y4)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 9, height)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 10, s1)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 11, s2)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 12, s3)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 13, s4)
endfunction

function MakeBridgeFromUnit takes unit u1, unit u2, unit u3, unit u4, real height, boolean removeunit returns nothing
    local real x1 = GetUnitX(u1)
    local real y1 = GetUnitY(u1)
    local real x2 = GetUnitX(u2)
    local real y2 = GetUnitY(u2)
    local real x3 = GetUnitX(u3)
    local real y3 = GetUnitY(u3)
    local real x4 = GetUnitX(u4)
    local real y4 = GetUnitY(u4)
    local real s1 = SquareRoot((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
    local real s2 = SquareRoot((x2 - x3) * (x2 - x3) + (y2 - y3) * (y2 - y3))
    local real s3 = SquareRoot((x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4))
    local real s4 = SquareRoot((x4 - x1) * (x4 - x1) + (y4 - y1) * (y4 - y1))
    set udg_Bridge_Table_Index = udg_Bridge_Table_Index + 1
    if height == - 1 then
        call MoveLocation(udg_Point, x1, y1)
        set height = GetLocationZ(udg_Point) + GetUnitFlyHeight(u1)
    endif
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 1, x1)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 2, y1)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 3, x2)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 4, y2)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 5, x3)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 6, y3)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 7, x4)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 8, y4)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 9, height)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 10, s1)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 11, s2)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 12, s3)
    call SaveReal(udg_Bridge_Table, udg_Bridge_Table_Index, 13, s4)
    if udg_Bridge_Table_Index == 1 then
        call SaveRectHandle(udg_Bridge_Table, udg_Bridge_Table_Index, 14, gg_rct_BridgeStart1)
        call SaveRectHandle(udg_Bridge_Table, udg_Bridge_Table_Index, 15, gg_rct_BridgeEnd1)
    elseif udg_Bridge_Table_Index == 2 then
        call SaveRectHandle(udg_Bridge_Table, udg_Bridge_Table_Index, 14, gg_rct_BridgeStart2)
        call SaveRectHandle(udg_Bridge_Table, udg_Bridge_Table_Index, 15, gg_rct_BridgeEnd2)
    endif
    if removeunit then
        call RemoveUnit(u1)
        call RemoveUnit(u2)
        call RemoveUnit(u3)
        call RemoveUnit(u4)
    endif
endfunction


function MakeLightningBorders takes nothing returns nothing
    local real x1
    local real y1
    local real x2
    local real y2
    local real x3
    local real y3
    local real x4
    local real y4
    local real height
    local integer i = 1
    local lightning l
    local real red
    local real green
    local real blue
    loop
        exitwhen LoadReal(udg_Bridge_Table, i, 9) == 0
        set x1 = LoadReal(udg_Bridge_Table, i, 1)
        set y1 = LoadReal(udg_Bridge_Table, i, 2)
        set x2 = LoadReal(udg_Bridge_Table, i, 3)
        set y2 = LoadReal(udg_Bridge_Table, i, 4)
        set x3 = LoadReal(udg_Bridge_Table, i, 5)
        set y3 = LoadReal(udg_Bridge_Table, i, 6)
        set x4 = LoadReal(udg_Bridge_Table, i, 7)
        set y4 = LoadReal(udg_Bridge_Table, i, 8)
        set height = LoadReal(udg_Bridge_Table, i, 9)

        if i== 1 then
            set red = 1
            set green = 0
            set blue = 0
        elseif i== 2 then
            set red = 0
            set green = 0
            set blue = 1
        elseif i== 3 then
            set red = 1
            set green = 1
            set blue = 0

        endif
        set l = AddLightningEx ("DRAL", true, x1, y1, height, x2, y2, height)
        call SetLightningColor(l, red, green, blue, 0.5)
        set l = AddLightningEx ("DRAL", true, x2, y2, height, x3, y3, height)
        call SetLightningColor(l, red, green, blue, 0.5)
        set l = AddLightningEx ("DRAL", true, x3, y3, height, x4, y4, height)
        call SetLightningColor(l, red, green, blue, 0.5)
        set l = AddLightningEx ("DRAL", true, x4, y4, height, x1, y1, height)
        call SetLightningColor(l, red, green, blue, 0.5)
        set i = i + 1
    endloop
    set l = null
endfunction

function RemoveUnitFromBridge takes integer index returns nothing
    local unit dummy = udg_Bridge_Unit[index]
    local integer cv = GetUnitUserData(dummy)
    local unit u = udg_Bridge_Old_Unit[cv]
    call SetUnitPosition (u, udg_LastBridgeX[index], udg_LastBridgeY[index])
    call SetUnitFacing(u, GetUnitFacing(dummy))
    call ShowUnit(u, true)
    if GetLocalPlayer() == GetOwningPlayer(u) then
        call SelectUnit(u, true)
    endif

//call FlushChildHashtable(udg_Bridge_UI_Table, GetHandleId(udg_Bridge_Unit[index]))
    set udg_Bridge_Unit_Index[cv] = 0
    set udg_Bridge_Old_Unit[cv] = null
    call RemoveUnit(dummy)
    if index != udg_Bridge_Index then
        set udg_Bridge_Level[index] = udg_Bridge_Level[udg_Bridge_Index]
        set udg_Bridge_Unit[index] = udg_Bridge_Unit[udg_Bridge_Index]
        set udg_LastBridgeX[index] = udg_LastBridgeX[udg_Bridge_Index]
        set udg_LastBridgeY[index] = udg_LastBridgeY[udg_Bridge_Index]
        set udg_Bridge_Unit_Index[GetUnitUserData(udg_Bridge_Unit[index])] = index
    endif
    set udg_Bridge_Index = udg_Bridge_Index - 1
    set u = null
endfunction

function AddUnitToBridge takes unit u, integer lv returns nothing
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real z = LoadReal(udg_Bridge_Table, lv, 9)
    local unit old = u
    local integer cv = GetUnitUserData(u)
    if udg_Bridge_Unit_Index[cv] == 0 then
        call ShowUnit(old, false)
        set u = CreateUnit(GetOwningPlayer(old), GetUnitTypeId(old), x, y, GetUnitFacing(old))
        set cv = GetUnitUserData(u)
        if GetLocalPlayer() == GetOwningPlayer(old) then
            call SelectUnit(u, true)
        endif
        if LoadInteger(udg_Bridge_UI_Table, GetHandleId(u), 1) > 0 then
            call RemoveUnitFromBridge(udg_Bridge_Unit_Index[cv])
        endif
        set udg_Bridge_Index = udg_Bridge_Index + 1
        set udg_Bridge_Level[udg_Bridge_Index] = lv
        set udg_Bridge_Unit[udg_Bridge_Index] = u
        set udg_LastBridgeX[udg_Bridge_Index] = x
        set udg_LastBridgeY[udg_Bridge_Index] = y
        set udg_Bridge_Unit_Index[cv] = udg_Bridge_Index
        set udg_Bridge_Old_Unit[cv] = old
        call MoveLocation(udg_Point, x, y)
        call UnitAddAbility( u, 'Amrf' )
        call UnitRemoveAbility( u, 'Amrf' )
        set z = z - GetLocationZ(udg_Point)
        call SetUnitFlyHeight( u, z, 0.00 )
        call SetUnitPathing(u , false)
    endif
    set old = null
endfunction

rest

JASS:
function Trig_Unit_Coord_Check_Actions takes nothing returns nothing
local integer i = 1
local real height
local real z
local real x
local real y
loop
exitwhen i > udg_Bridge_Index
   set x = GetUnitX(udg_Bridge_Unit[i])
   set y = GetUnitY(udg_Bridge_Unit[i])
   if UnitOnBridge (udg_Bridge_Unit[i] , udg_Bridge_Level[i]) then
   call MoveLocation(udg_Point, x, y)
   set height = LoadReal(udg_Bridge_Table,udg_Bridge_Level[i],9)
   set z = GetLocationZ(udg_Point)
   call DisplayTextToForce( GetPlayersAll(), GetUnitName(udg_Bridge_Unit[i]) + " floor level:" +I2S(udg_Bridge_Level[i])+ " floor height" + R2S(height) + " z " + R2S(z) )
   call SetUnitFlyHeight( udg_Bridge_Unit[i], height-z+10, 0.00 )
   set udg_LastBridgeX[i] = x
   set udg_LastBridgeY[i] = y
   else
     if UnitOnRect(udg_Bridge_Unit[i],udg_Bridge_Level[i]) then
         call RemoveUnitFromBridge(i)
     else     
       call SetUnitPosition(udg_Bridge_Unit[i], udg_LastBridgeX[i], udg_LastBridgeY[i])
     endif
   endif
set i = i + 1
endloop
endfunction

//===========================================================================
function InitTrig_Unit_Coord_Check takes nothing returns nothing
    set gg_trg_Unit_Coord_Check = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_Unit_Coord_Check, 0.07 )
    call TriggerAddAction( gg_trg_Unit_Coord_Check, function Trig_Unit_Coord_Check_Actions )
endfunction


JASS:
function Trig_Bridge_1_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local integer index = udg_Bridge_Unit_Index[GetUnitUserData(u)]
    if index > 0 then
        call RemoveUnitFromBridge(index)
   else
        if UnitOnBridge(u, 1) then
            call AddUnitToBridge(u, 1)
         endif
    endif
call DisplayTextToForce( GetPlayersAll(), GetUnitName(u) + " index " + I2S(index))

endfunction

//===========================================================================
function InitTrig_Bridge_1 takes nothing returns nothing
    set gg_trg_Bridge_1 = CreateTrigger( )
    call TriggerRegisterLeaveRectSimple( gg_trg_Bridge_1, gg_rct_BridgeEnd1 )
    call TriggerRegisterLeaveRectSimple( gg_trg_Bridge_1, gg_rct_BridgeStart1 )
    call TriggerAddAction( gg_trg_Bridge_1, function Trig_Bridge_1_Actions )
endfunction


JASS:
function Trig_Bridge_2_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local integer index = udg_Bridge_Unit_Index[GetUnitUserData(u)]


    if index > 0 then
        call RemoveUnitFromBridge(index)
   else
        if UnitOnBridge(u, 2) then
            call AddUnitToBridge(u, 2)
         endif
    endif
call DisplayTextToForce( GetPlayersAll(), GetUnitName(u) + " index " + I2S(index))
endfunction

//===========================================================================
function InitTrig_Bridge_2 takes nothing returns nothing
    set gg_trg_Bridge_2 = CreateTrigger(  )
    call TriggerRegisterLeaveRectSimple( gg_trg_Bridge_2, gg_rct_BridgeEnd2 )
    call TriggerRegisterLeaveRectSimple( gg_trg_Bridge_2, gg_rct_BridgeStart2 )
    call TriggerAddAction( gg_trg_Bridge_2, function Trig_Bridge_2_Actions )
endfunction
 

Attachments

  • 1.jpg
    1.jpg
    200.2 KB · Views: 166
  • multiple platform1.w3x
    32 KB · Views: 101
Level 14
Joined
Apr 20, 2009
Messages
1,543
I haven't had the time to work on my map due to exams.
Anyways, I'll check your map out soon. But I'm not sure if I'm going to use it since my system works for me too, so that's not really an issue ;)

Thanks anyways though, I'll check this out soon.

EDIT: I want to rep you again, but I have to spread... I'm not so active these days :(
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
I haven't had the time to work on my map due to exams.
Anyways, I'll check your map out soon. But I'm not sure if I'm going to use it since my system works for me too, so that's not really an issue ;)

Thanks anyways though, I'll check this out soon.

EDIT: I want to rep you again, but I have to spread... I'm not so active these days :(

still i got problem with moveing to bridge from cliff but Adiktuz said if i replace then normal movement to SetUnitX/Y then its work.

i am crusios to your map really :p
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
still i got problem with moveing to bridge from cliff but Adiktuz said if i replace then normal movement to SetUnitX/Y then its work.

i am crusios to your map really :p

Yeah... I have 5 exams comming up next week, another 5 the week after that, then I still have to do 3 exams and when that's done I need to do 2 more so...
It'll take some time before I'm up to mapping again :(

Hopefully I get a lot of spare time after that to complete my map :)
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,199
JASS:
    local real d1 = SquareRoot((x1-px) * (x1-px) + (y1-py) * (y1-py)) // working out sqrt
    local real d2 = SquareRoot((x2-px) * (x2-px) + (y2-py) * (y2-py))
    local real d3 = SquareRoot((x3-px) * (x3-px) + (y3-py) * (y3-py))
    local real d4 = SquareRoot((x4-px) * (x4-px) + (y4-py) * (y4-py))
    local real s1 = SquareRoot((x1-x2) * (x1-x2) + (y1-y2) * (y1-y2))
    local real s2 = SquareRoot((x2-x3) * (x2-x3) + (y2-y3) * (y2-y3))
    local real s3 = SquareRoot((x3-x4) * (x3-x4) + (y3-y4) * (y3-y4))
    local real s4 = SquareRoot((x4-x1) * (x4-x1) + (y4-y1) * (y4-y1))
    local real cos1 = (d1*d1+d2*d2-s1*s1)/ (2 * (d1*d2)) // now working back to square
    local real cos2 = (d2*d2+d3*d3-s2*s2)/ (2 * (d2*d3))
    local real cos3 = (d3*d3+d4*d4-s3*s3)/ (2 * (d3*d4))
    local real cos4 = (d4*d4+d1*d1-s4*s4)/ (2 * (d4*d1)) // and here again!?
    local real output = cos1+cos2+cos3+cos4

You are working out the square root of a number just to go and work out its square again. This seems like a big waste of time to me...

Surely this would be better?
JASS:
    local real d1 = (x1-px) * (x1-px) + (y1-py) * (y1-py)
    local real d2 = (x2-px) * (x2-px) + (y2-py) * (y2-py)
    local real d3 = (x3-px) * (x3-px) + (y3-py) * (y3-py)
    local real d4 = (x4-px) * (x4-px) + (y4-py) * (y4-py)
    local real s1 = (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2)
    local real s2 = (x2-x3) * (x2-x3) + (y2-y3) * (y2-y3)
    local real s3 = (x3-x4) * (x3-x4) + (y3-y4) * (y3-y4)
    local real s4 = (x4-x1) * (x4-x1) + (y4-y1) * (y4-y1)
    local real cos1 = (d1+d2-s1) / (2 * SquareRoot(d1*d2))
    local real cos2 = (d2+d3-s2) / (2 * SquareRoot(d2*d3))
    local real cos3 = (d3+d4-s3) / (2 * SquareRoot(d3*d4))
    local real cos4 = (d4+d1-s4) / (2 * SquareRoot(d4*d1))
    local real output = cos1+cos2+cos3+cos4

4 less function calls, 12 less multiplications and 12 fewer literals to resolve.

JASS:
    local real output = cos1+cos2+cos3+cos4
    return output < 0
no need to create a local here... Just return the result.
JASS:
    return (cos1+cos2+cos3+cos4) < 0
Saves a local decleration.
 
Level 3
Joined
Jan 31, 2012
Messages
42
JASS:
function IsPointInTriangle takes real x1, real y1, real x2, real y2, real x3, real y3, real x, real y returns boolean
    local boolean b = (x2 - x) * (y3 - y2) - (x3 - x2) * (y2 - y) > .0
    return (x1 - x) * (y2 - y1) - (x2 - x1) * (y1 - y) > .0 == b and (x3 - x) * (y1 - y3) - (x1 - x3) * (y3 - y) > .0 == b
endfunction

function IsPointInQuadrangle takes real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4, real x, real y returns boolean
    return IsPointInTriangle(x1, y1, x2, y2, x3, y3, x, y) or IsPointInTriangle(x1, y1, x3, y3, x4, y4, x, y)
endfunction
Works for any convex quadrangles.
 
Status
Not open for further replies.
Top