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

[Solved] Script breaks when saving/loading

Status
Not open for further replies.
I'm having an issue with a custom script that won't load properly when transitioning between campaign maps (I'm using this for transitions). Basically the script calculates the height difference between the units Z value and the ground (or something), and then sets the camera height accordingly.

I have made two test campaigns.

  1. In this test campaign (Test Campaign 1) the script runs once on map initialization, and again every time a saved game is loaded. In this version the issues starts when you re-enter a map for the second time and on all subsequent entries. The camera will zoom in/out really fast in some areas, and then stutter in other areas.
  2. In this test campaign (Test Campaign 2) the script only runs once on map initialization, and is never ran when a saved game is loaded. The script completely stops working on all subsequent entries.
Here's the faulty script + related code:

  • Custom script: local u=udg_MyUnit TimerStart(CreateTimer(),0.03125000,true,function()if not udg_Indoors then SetCameraField(CAMERA_FIELD_TARGET_DISTANCE,1600+BlzGetLocalUnitZ(u)-GetCamOffset(GetUnitX(u),GetUnitY(u)),0)end end)
Code:
do
    local cameramapLoc
    local mapMinX, mapMinY
    local offsets = {}
    local GetCamOffsetInitGrid
    local function GetCamOffsetAt(x, y)
        local idx = y*yfact+x
        local res = rawget(offsets, idx)
        if res then return res end
        res = GetCamOffsetInitGrid(mapMinX+256+512*x, mapMinY+256+512*y)
        rawset(offsets, idx, res)
        return res
    end
    local function GetGridCamOffset(ix, iy, offx, offy)
        local r
        local ixl = ix-1
        local ixr = ix+1
        local iyd = iy-1
        local iyu = iy+1
        if ixl<0 then
            ixl = 0
        end
        if iyd<0 then
            iyd = 0
        end
        if ixr>256 then
            ixr=256
        end
        if iyu>256 then
            iyu=256
        end
        if offx>0 then
            if offy>0 then
                r =   .089696*GetCamOffsetAt(ixl,iyu)+ .139657*GetCamOffsetAt(ix,iyu)+ .097349*GetCamOffsetAt(ixr,iyu)
                r = r+.130989*GetCamOffsetAt(ixl,iy) + .099380*GetCamOffsetAt(ix,iy) + .139657*GetCamOffsetAt(ixr,iy)
                r = r+.082587*GetCamOffsetAt(ixl,iyd)+ .130989*GetCamOffsetAt(ix,iyd)+ .089696*GetCamOffsetAt(ixr,iyd)
            elseif offy<0 then
                r =   .082587*GetCamOffsetAt(ixl,iyu)+ .130989*GetCamOffsetAt(ix,iyu)+ .089696*GetCamOffsetAt(ixr,iyu)
                r = r+.130989*GetCamOffsetAt(ixl,iy) + .099380*GetCamOffsetAt(ix,iy) + .139657*GetCamOffsetAt(ixr,iy)
                r = r+.089696*GetCamOffsetAt(ixl,iyd)+ .139657*GetCamOffsetAt(ix,iyd)+ .097349*GetCamOffsetAt(ixr,iyd)
            else
                r =   .084604*GetCamOffsetAt(ixl,iyu)+ .134226*GetCamOffsetAt(ix,iyu)+ .091913*GetCamOffsetAt(ixr,iyu)
                r = r+.134017*GetCamOffsetAt(ixl,iy) + .101594*GetCamOffsetAt(ix,iy) + .142877*GetCamOffsetAt(ixr,iy)
                r = r+.084604*GetCamOffsetAt(ixl,iyd)+ .134226*GetCamOffsetAt(ix,iyd)+ .091913*GetCamOffsetAt(ixr,iyd)
            end
        elseif offx<0 then
            if offy>0 then
                r =   .097349*GetCamOffsetAt(ixl,iyu)+ .139657*GetCamOffsetAt(ix,iyu)+ .089696*GetCamOffsetAt(ixr,iyu)
                r = r+.139657*GetCamOffsetAt(ixl,iy) + .099380*GetCamOffsetAt(ix,iy) + .130989*GetCamOffsetAt(ixr,iy)
                r = r+.089696*GetCamOffsetAt(ixl,iyd)+ .130989*GetCamOffsetAt(ix,iyd)+ .082587*GetCamOffsetAt(ixr,iyd)
            elseif offy<0 then
                r =   .089696*GetCamOffsetAt(ixl,iyu)+ .130989*GetCamOffsetAt(ix,iyu)+ .082587*GetCamOffsetAt(ixr,iyu)
                r = r+.139657*GetCamOffsetAt(ixl,iy) + .099380*GetCamOffsetAt(ix,iy) + .130989*GetCamOffsetAt(ixr,iy)
                r = r+.097349*GetCamOffsetAt(ixl,iyd)+ .139657*GetCamOffsetAt(ix,iyd)+ .089696*GetCamOffsetAt(ixr,iyd)
            else
                r =   .091913*GetCamOffsetAt(ixl,iyu)+ .134226*GetCamOffsetAt(ix,iyu)+ .084604*GetCamOffsetAt(ixr,iyu)
                r = r+.142877*GetCamOffsetAt(ixl,iy) + .101594*GetCamOffsetAt(ix,iy) + .134017*GetCamOffsetAt(ixr,iy)
                r = r+.091913*GetCamOffsetAt(ixl,iyd)+ .134226*GetCamOffsetAt(ix,iyd)+ .084604*GetCamOffsetAt(ixr,iyd)
            end
        else
            if offy>0 then
                r =   .091913*GetCamOffsetAt(ixl,iyu)+ .142877*GetCamOffsetAt(ix,iyu)+ .091913*GetCamOffsetAt(ixr,iyu)
                r = r+.134226*GetCamOffsetAt(ixl,iy) + .101594*GetCamOffsetAt(ix,iy) + .134226*GetCamOffsetAt(ixr,iy)
                r = r+.084604*GetCamOffsetAt(ixl,iyd)+ .134017*GetCamOffsetAt(ix,iyd)+ .084604*GetCamOffsetAt(ixr,iyd)
            elseif offy<0 then
                r =   .084604*GetCamOffsetAt(ixl,iyu)+ .134017*GetCamOffsetAt(ix,iyu)+ .084604*GetCamOffsetAt(ixr,iyu)
                r = r+.134226*GetCamOffsetAt(ixl,iy) + .101594*GetCamOffsetAt(ix,iy) + .134226*GetCamOffsetAt(ixr,iy)             
                r = r+.091913*GetCamOffsetAt(ixl,iyd)+ .142877*GetCamOffsetAt(ix,iyd)+ .091913*GetCamOffsetAt(ixr,iyd)
            else
                r =   .086125*GetCamOffsetAt(ixl,iyu)+ .136429*GetCamOffsetAt(ix,iyu)+ .086125*GetCamOffsetAt(ixr,iyu)
                r = r+.136429*GetCamOffsetAt(ixl,iy) + .109784*GetCamOffsetAt(ix,iy) + .136429*GetCamOffsetAt(ixr,iy)
                r = r+.086125*GetCamOffsetAt(ixl,iyd)+ .136429*GetCamOffsetAt(ix,iyd)+ .086125*GetCamOffsetAt(ixr,iyd)
            end
        end
        return r
    end
    function GetCamOffset(x, y)
        local ok,res = pcall(function()
            local iXLo = R2I((x-mapMinX)/512.+.5)
            local iYLo = R2I((y-mapMinY)/512.+.5)
            local iXHi = iXLo+1
            local iYHi = iYLo+1
            local iChkXLo
            local iChkXLoOff
            local iChkXHi
            local iChkXHiOff
            local iChkYLo
            local iChkYLoOff
            local iChkYHi
            local iChkYHiOff
            local XLo
            local YLo
            local XHi
            local YHi
            local rX
            local rY
            local r
            local LoDX = (x-mapMinX)-(iXLo*512.-256.)
            local LoDY = (y-mapMinY)-(iYLo*512.-256.)
            if LoDX<=12 then
                iChkXLo = iXLo
                iChkXLoOff = 0
                iChkXHi = iXLo
                iChkXHiOff = 1
            elseif LoDX<500 then
                iChkXLo = iXLo
                iChkXLoOff = 1
                iChkXHi = iXHi
                iChkXHiOff =-1
            else
                iChkXLo = iXHi
                iChkXLoOff =-1
                iChkXHi = iXHi
                iChkXHiOff = 0
            end
            if LoDY<=12 then
                iChkYLo = iYLo
                iChkYLoOff = 0
                iChkYHi = iYLo
                iChkYHiOff = 1
            elseif LoDY<500 then
                iChkYLo = iYLo
                iChkYLoOff = 1
                iChkYHi = iYHi
                iChkYHiOff =-1
            else
                iChkYLo = iYHi
                iChkYLoOff =-1
                iChkYHi = iYHi
                iChkYHiOff = 0
            end
            XLo = iChkXLo*512.+iChkXLoOff*12.-256.
            XHi = iChkXHi*512.+iChkXHiOff*12.-256.
            YLo = iChkYLo*512.+iChkYLoOff*12.-256.
            YHi = iChkYHi*512.+iChkYHiOff*12.-256.
            rX = ((x-mapMinX)-XLo)/(XHi-XLo)
            rY = ((y-mapMinY)-YLo)/(YHi-YLo)
            r =   GetGridCamOffset(iChkXHi,iChkYHi,iChkXHiOff,iChkYHiOff)*rX*rY
            r = r+GetGridCamOffset(iChkXLo,iChkYHi,iChkXLoOff,iChkYHiOff)*(1-rX)*rY
            r = r+GetGridCamOffset(iChkXHi,iChkYLo,iChkXHiOff,iChkYLoOff)*rX*(1-rY)
            r = r+GetGridCamOffset(iChkXLo,iChkYLo,iChkXLoOff,iChkYLoOff)*(1-rX)*(1-rY)
            return r
        end)
        if not ok then print('|cffff0000GetCamOffset: '..res) end
        return res
    end
    function GetCamOffsetInitGrid(x,y)
        local index
        local iX = -6
        local iY
        local z
        local r
        local i = 64 --9*4+12*2+4
        MoveLocation(cameramapLoc,x,y)
        z = GetLocationZ(cameramapLoc)
        r = 0.
        MoveLocation(cameramapLoc,x-128.,y)
        r = r+GetLocationZ(cameramapLoc)*4./i
        MoveLocation(cameramapLoc,x,y)
        r = r+GetLocationZ(cameramapLoc)*4./i
        MoveLocation(cameramapLoc,x+128.,y)
        r = r+GetLocationZ(cameramapLoc)*4./i
        MoveLocation(cameramapLoc,x-128.,y+128.)
        r = r+GetLocationZ(cameramapLoc)*4./i
        MoveLocation(cameramapLoc,x,y+128.)
        r = r+GetLocationZ(cameramapLoc)*4./i
        MoveLocation(cameramapLoc,x+128.,y+128.)
        r = r+GetLocationZ(cameramapLoc)*4./i
        MoveLocation(cameramapLoc,x-128.,y-128.)
        r = r+GetLocationZ(cameramapLoc)*4./i
        MoveLocation(cameramapLoc,x,y-128.)
        r = r+GetLocationZ(cameramapLoc)*4./i
        MoveLocation(cameramapLoc,x+128.,y-128.)
        r = r+GetLocationZ(cameramapLoc)*4./i
        MoveLocation(cameramapLoc,x-256.,y-128.)
        r = r+GetLocationZ(cameramapLoc)*2./i
        MoveLocation(cameramapLoc,x-256.,y)
        r = r+GetLocationZ(cameramapLoc)*2./i
        MoveLocation(cameramapLoc,x-256.,y+128.)
        r = r+GetLocationZ(cameramapLoc)*2./i
        MoveLocation(cameramapLoc,x+256.,y-128.)
        r = r+GetLocationZ(cameramapLoc)*2./i
        MoveLocation(cameramapLoc,x+256.,y)
        r = r+GetLocationZ(cameramapLoc)*2./i
        MoveLocation(cameramapLoc,x+256.,y+128.)
        r = r+GetLocationZ(cameramapLoc)*2./i
        MoveLocation(cameramapLoc,x-128.,y-256.)
        r = r+GetLocationZ(cameramapLoc)*2./i
        MoveLocation(cameramapLoc,x,y-256.)
        r = r+GetLocationZ(cameramapLoc)*2./i
        MoveLocation(cameramapLoc,x+128.,y-256.)
        r = r+GetLocationZ(cameramapLoc)*2./i
        MoveLocation(cameramapLoc,x-128.,y+256.)
        r = r+GetLocationZ(cameramapLoc)*2./i
        MoveLocation(cameramapLoc,x,y+256.)
        r = r+GetLocationZ(cameramapLoc)*2./i
        MoveLocation(cameramapLoc,x+128.,y+256.)
        r = r+GetLocationZ(cameramapLoc)*2./i
        MoveLocation(cameramapLoc,x+256.,y+256.)
        r = r+GetLocationZ(cameramapLoc)*1./i
        MoveLocation(cameramapLoc,x+256.,y-256.)
        r = r+GetLocationZ(cameramapLoc)*1./i
        MoveLocation(cameramapLoc,x-256.,y+256.)
        r = r+GetLocationZ(cameramapLoc)*1./i
        MoveLocation(cameramapLoc,x-256.,y-256.)
        r = r+GetLocationZ(cameramapLoc)*1./i
        return r
    end
    local function GetCamOffsetInit()
        local map = GetWorldBounds()
        mapMinX = GetRectMinX(map)
        mapMinY = GetRectMinY(map)
        local mapMaxX = GetRectMaxX(map)
        local mapW = mapMaxX - mapMinX
        yfact = math.floor(mapW / 512 + 0.5)
        RemoveRect(map)
        cameramapLoc = Location(0,0)
    end
    local OldInitBlizzard = InitBlizzard
    function InitBlizzard()
        if OldInitBlizzard then
            OldInitBlizzard()
        end
        GetCamOffsetInit()
    end
end
 

Attachments

  • Test Campaign 1.w3n
    51.3 KB · Views: 11
  • Test Campaign 2.w3n
    51.2 KB · Views: 14
Status
Not open for further replies.
Top