Z source messed up in cliffs?

waaaks!

Zinctified
Reaction score
255
Hello.

I have this fade lightning library I made that lets you create lightning (duh!) from a unit to a unit, both requires a Z offset. The library works fine in means of creating the lightning and fading it, but the Z offset thing is pissing me off.

When I used 600.0 for the sourceZ offset and 0.0 for the targetZ offset (to make it touch the ground) created in a level 3 or any level cliffs, the lightning tends to use the lowest level of the cliff as the z offset, which means 0 offset is the lowest level of terrain, creating the lightning under the cliff like this illustration:
terrainheight.jpg


looks like GetLocationZ is what I need to fix this, but I heard that GetLocationZ can cause desync, is there any solution?

in this code, I used to add the input Z offset to the fly height of the unit, but still it doesn't work, because the unit's fly height is 0 which adds nothing.
JASS:
library FadeLightning

private struct vdata
    lightning l
    real dur
    real ctr
    unit t
    real tz
    real x
    real y
    real z
    real R
    real G
    real B
endstruct

private function callBacks takes nothing returns boolean
    local timer t = GetExpiredTimer()
    local vdata d = GetTimerData(t)
    local real A
    set A = d.ctr / d.dur
    call MoveLightningEx(d.l,true,GetUnitX(d.t),GetUnitY(d.t),d.tz,d.x,d.y,d.z)
    call SetLightningColor(d.l,d.R,d.G,d.B,d.ctr)
    set d.ctr = d.ctr - 0.035
    if d.ctr <= 0 then
        set A = 0
        call DestroyLightning(d.l)
        call ReleaseTimer(t)
        call d.destroy()
    endif
    set t = null
    return true
endfunction

function LightningSourceTarget takes unit source, real sourcez, real targetx, real targety, real targetz, string light, real dur, real R, real G, real B returns nothing
    local timer t = NewTimer()
    local vdata d = vdata.create()
    set d.l = AddLightningEx(light, true, GetUnitX(source), GetUnitY(source), sourcez + GetLocationZ(Location(GetUnitX(source),GetUnitY(source))), targetx, targety, targetz + GetLocationZ(Location(targetx,targety)))
    set d.dur = dur
    set d.ctr = dur
    set d.t = source
    set d.tz = sourcez + GetLocationZ(Location(GetUnitX(source),GetUnitY(source)))
    set d.x = targetx
    set d.y = targety
    set d.z = targetz + GetLocationZ(Location(targetx,targety))
    set d.R = R
    set d.G = G
    set d.B = B
    call SetLightningColor(d.l,R,G,B,1.0)
    call TimerStart(t,0.035,true, function callBacks)
    call SetTimerData(t,d)
    set t = null
endfunction


endlibrary
 

Viikuna

No Marlo no game.
Reaction score
265
GetLocationZ can return different values for different players, because of some graphics setting thigny, so yea it can cause desyncs in some cases.

This is not a problems with lightnings. You can move lightnings with different target z data without having to worry about desyncs, because lightnings dont really affects gameplay anyway.

edit. So, GetLocationZ + UnitFlyHeight should be enough to attach lightning to units origin. Just note that your current code leaks shitloads of locations. I suggest you to use one global location with MoveLocation and GetLocationZ for getting Z height.
 

Weep

Godspeed to the sound of the pounding
Reaction score
400
I've read that GetLocationZ can cause desyncs if there are differences in terrain deformations between computers, such as if a unit uses a spell like Shockwave and the various players have their spell detail level options set differently.

I think a cliff level is 128 units, so you could use GetTerrainCliffLevel, though cliffs have a sort of smooth fall-off at their edges that would make the result approximate (cliff level jumps sharply) and it wouldn't stop at water level if used over water, and of course it wouldn't work if you've used raise/lower terrain for smooth hills.

And then, since flying units have gradual height transitions when flying over cliffs and trees, and their "flying height" doesn't change to account for this, I don't think there's any way to accurately get the Z position of a flying unit...
 

waaaks!

Zinctified
Reaction score
255
GetLocationZ can return different values for different players, because of some graphics setting thigny, so yea it can cause desyncs in some cases.

This is not a problems with lightnings. You can move lightnings with different target z data without having to worry about desyncs, because lightnings dont really affects gameplay anyway.

edit. So, GetLocationZ + UnitFlyHeight should be enough to attach lightning to units origin. Just note that your current code leaks shitloads of locations. I suggest you to use one global location with MoveLocation and GetLocationZ for getting Z height.
about the leak, how about storing the location in a variable and destroy it later? I have more functions using locations in that library, I just showed 1.
 

Viikuna

No Marlo no game.
Reaction score
265
Well, this is fully multi instanceable and probably the fastest way to do it:

JASS:


globals
    location Loc=Location(0.0,0.0)
endglobals

function somefunction takes nothing returns nothing
  local real x // = something
  local real y // = something
  local real z

  // some stuff
 
// use MoveLocation and getLocationZ to find z in some point:  

  call MoveLocation(Loc,x,y)
  set z=GetLocationZ(Loc)

endfunction
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top