System Enter Rect

DrEvil

FCRI Associate!
Reaction score
111
Do I have to ? XD
ehh what the heck ..

So... say I change the struct to hold the cenX/Y of each rect , and wrap them , how will I find the other rect if they are not connected ?
Like one of the rectwraps gets entered I go to send it to the other rect ... but ... where is it ? Because its not in the same struct...
Unless I'm misreading I don't see a way to do what you suggested...
 

Jesus4Lyf

Good Idea™
Reaction score
397
Something like...
JASS:
private struct EnterRect
    private real xTarg
    private real yTarg
    // rect 2
    private integer level
    // level requirement to go through
    private string msg
    // custom msg if they can't enter

//...

    static method create takes rectwrap start,rectwrap end,integer level,string msg returns thistype
        local thistype d = thistype.allocate()
        
        //set d.start = rectwrap.wrap(start)
        //set d.end = rectwrap.wrap(end)
        set d.xTarg=end.cenX
        set d.yTarg=end.cenY
        set d.level = level
        set d.msg = msg
        // set the struct variables
        
        call start.registerEnter(thistype.Trig)
        //call d.end.registerEnter(thistype.Trig)
        // The above removed line will be called when this is run for end.
        
        set start.userData = d
        //set d.end.userData = d
        // Likewise like comment before.
        
        return d
        // the .creates require a return :S
    endmethod

function RegisterRectEnterEx takes rect r1,rect r2,integer level,string msg returns nothing
    local rectwrap a=rectwrap.wrap(r1)
    local rectwrap b=rectwrap.wrap(r2)
    call EnterRect.create(a,b,level,msg)
    call EnterRect.create(b,a,level,msg)
endfunction// I would recommend this for dungeons requiring levels to enter

And then in your trigger condition...
JASS:
if thistype.UnitFilter(u) then
            if GetUnitLevel(u) >= d.level then
                
                call DisableTrigger(thistype.Trig)
                
                call SetUnitX(u,d.xTarg)
                call SetUnitY(u,d.yTarg)// send the unit to the specified rect
                
                if thistype.SHOULD_PAN and GetLocalPlayer() == p then
                    call PanCameraToTimed(d.xTarg,d.yTarg,1)
                endif// pan the camera for player if user wants to
                
                call IssueImmediateOrder(u,"stop")
                //stop the unit
                call TimerStart(thistype.T,.0,false,function thistype.RestoreTrig)
                // start timer for enabling 
            else
            // the hero is not a high enough level..
                if d.msg == "" then
                    call DisplayTimedTextToPlayer(p,0,0,10,"You need to be level "+I2S(d.level)+" in order to pass")
                else
                    call DisplayTimedTextToPlayer(p,0,0,10,d.msg)
                endif
            endif
        endif

Hope that helps convey the idea.

And instead of returning true, you should return false so the blank actions don't get run. Just a mild efficiency thing. :)
 

DrEvil

FCRI Associate!
Reaction score
111
Updated , thanks to Jesus4Lyf.
I probably wouldn't have thought of doing that even if I wern't tired last night ^_^
 

Kenny

Back for now.
Reaction score
202
Your struct is still private. :p

Anyway, this looks very useful. Nicely done. :thup:
 

DrEvil

FCRI Associate!
Reaction score
111
...Didn't someone tell me to make it private ? XD
Or because its not a common name , I won't need it private ?
Isn't the whole point of 'private' so no one can access it outside the struct ?
 

Kenny

Back for now.
Reaction score
202
Actually my bad, the way its coded now, having struct syntax is useless, as you need those other two functions to wrap the rects.

Having the struct as private means no one can use struct syntax for the system. Having members/methods that are private means that they can use struct syntax but can't access things you don't want them to.

Anywho, don't worry. I didn't read the new script properly.
 

DrEvil

FCRI Associate!
Reaction score
111
Good to know :)
Just before you said make it private then Kenny said why private ?
Got me a bit confused:D
 

Kenny

Back for now.
Reaction score
202

DrEvil

FCRI Associate!
Reaction score
111
I was considering that earlier ( but isn't that like more memory than using a variable ? ) :
Instead of getting the x/y twice I'd set them to a var to save memory ? ( thus only calling them once )

but it would look cleaner ^_^
 

Kenny

Back for now.
Reaction score
202
d.tarX and d.tarY are variables... You are setting a variable to another variable, then using the new ones.
 

Jesus4Lyf

Good Idea™
Reaction score
397
Ahh. I was thinking of commenting on that, but I didn't really care. I think kenny!'s suggestion should actually be more efficient. I believe break even point for storing struct members (in other words, single array reads) in local variables is at 3 uses (or so). So having only 2, you might as well remove the locals. :D
 

DrEvil

FCRI Associate!
Reaction score
111
lol ... just re read some stuff.
I'm setting a variable to a variable to reduce memory usage ( which it doesn't ) ^_^ lawls

EDIT : In 'static method Enter' I used the player p variable , but it can only be used once in the whole function .. so should I remove it and use GetOwningPlayer(u) instead ? or just keep it like that ?
e.g. I use player p three times , but it can only be used once in that situation ( panning , displaying ( default , custom ) text )
( If you don't get it , look at the method Enter and see where p is used )
 

Azlier

Old World Ghost
Reaction score
461
A good improvement would be to not monopolize the rectwrap's user data. That's really only for private use, not in public systems. The solution is no less efficient than using userData directly.

JASS:
//Instead of using userData...
set rectwrap.userData = 0

//use the rectwrap as an index in an array!
private static EnterRect array ER_Data

set .ER_Data[rectwrap] = 0


Or...

JASS:
rectwrap start,rectwrap end


Instead of taking rectwraps, why not takes rects and wrap them internally? That way, they can't be destroyed from the outside and you are free to use the userData.
 

Azlier

Old World Ghost
Reaction score
461
>He does wrap them internally. Everything you said is redundant.

Well, as you just said, the struct isn't yet private :p.

So, I could call create from anywhere, anytime and provide my own rectwraps.

EDIT:
You don't need to create two EnterRect instances every time you provide rects. This is a Doorway struct I've been using in my map for quite a while now (exact same idea as what you have here). This teleports you close to the exit rect, rather than inside. I've had bad experiences with 0 second timers.

JASS:
struct Doorway

private static constant real DOORWAY_DISTANCE = 128

private rectwrap Enter
private rectwrap Exit

private real EnX
private real EnY
private real ExX
private real ExY

private real EnAngle
private real ExAngle

private static trigger Trig = CreateTrigger()

private static method EnterDoor takes nothing returns boolean
    local thistype this = GetTriggeringRectwrap().userData
    local unit u = GetTriggerUnit()
    if GetTriggeringRectwrap() == .Enter then
        call SetUnitPosition(u, .ExX, .ExY)
        call SetUnitFacing(u, .ExAngle)
        if GetLocalPlayer() == GetOwningPlayer(u) then
            call SetCameraPosition(.ExX, .ExY)
        endif
    else
        call SetUnitPosition(u, .EnX, .EnY)
        call SetUnitFacing(u, .EnAngle)
        if GetLocalPlayer() == GetOwningPlayer(u) then
            call SetCameraPosition(.EnX, .EnY)
        endif
    endif
    set u = null
    return false
endmethod

static method create takes rect r1, real angle1, rect r2, real angle2 returns thistype
    local thistype this = thistype.allocate()
    set .Enter = rectwrap.wrap(r1)
    set .Exit = rectwrap.wrap(r2)
    call .Enter.registerEnter(.Trig)
    call .Exit.registerEnter(.Trig)
    
    set .Enter.userData = this
    set .Exit.userData = this
    
    set .EnAngle = angle1
    set .ExAngle = angle2
    
    set angle1 = angle1 * bj_DEGTORAD
    set .EnX = .Enter.cenX + .DOORWAY_DISTANCE * Cos(angle1)
    set .EnY = .Enter.cenY + .DOORWAY_DISTANCE * Sin(angle1)
    
    set angle2 = angle2 * bj_DEGTORAD
    set .ExX = .Exit.cenX + .DOORWAY_DISTANCE * Cos(angle2)
    set .ExY = .Exit.cenY + .DOORWAY_DISTANCE * Sin(angle2)
    return this
endmethod

private static method onInit takes nothing returns nothing
    call TriggerAddCondition(.Trig, Condition(function thistype.EnterDoor))
endmethod

endstruct
 

DrEvil

FCRI Associate!
Reaction score
111
I had something like that originally , but Jesus4Lyf told me to not store the rectwrap's and only store the end x/y
but instead have two RectData's ( one for the start / end )
hmm...

If I change it back , Jesus4Lyf will say change it back ( to this ^_^ ) ,
and if I don't you say I don't need two instances ...
I'm stuck between a rock and a hard place... (XD)
 
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