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

Map explosions

Status
Not open for further replies.
Level 5
Joined
Aug 27, 2007
Messages
138
Continual Fatal Errors

Okay, so... my map has developed a bit of a problem recently.

First, a little background info. The map in question is in arena and has been around forever, and I've worked on it at various stages of development. There is a big gap in coding efficiency between when I first started developing it and where I current am--it s with this map that I made the shift from GUI to vJass.

Pre-.24, a lot of spells still used HandleVars, but I've rewritten all of them to use TimerAttach(), and they seem to work fine. There used to be several of my libraries stacked in the map header, but I've gotten rid of all of them trying to fix the problem. I have a lot of imported stuff, though mostly spell effects.

The problem is that the map fatals. Not when anything in particular is done, though. It fatals for someone when he finishes downloading the map. One of my main testers also uses a mac, and it usually desyncs him at the start now.

Pre-.24, this wasn't a problem. All I've done is rewrite spells to use TimerAttach() and tweak a few minor things. Anyone know what the problem could be?
 
Last edited:
Level 5
Joined
Aug 27, 2007
Messages
138
I don't feel comfortable posting an unprotected version, and posting a protected version would do little good. I'll post it once I get back on my main computer, though... it'll probably be tomorrow.

Since posting, I've been thinking a bit and I think it may have something to do with a corrupted model import. Anyone know the symptoms of that?

Edit: just an FYI, the model I'm thinking of isn't actually used yet, but it was imported a while back and removed not too long ago.
 
Level 5
Joined
Aug 27, 2007
Messages
138
Bumpage.

Still a no-go; my corruption hypothesis was wrong. It seems like I had one version that worked when I removed a few disabled triggers, but now it's having the same problems again. It could possibly be save issue... but I'm not sure. I'm running the latest version of NewGen WE, if that means anything, and prior to 1.24 the map worked fine.

Some more information: the first time I save the map, Warcraft always gives me a gamenotfound. If I play anything else before hosting this map, when I host it, I immediately fatal. The only way to play it is to restart Warcraft and host this map, then repeat for every rehost.

Some assistance would be appreciated. This map has lain dormant for a long time, and when I finally do spend some time on it, it breaks. ;(
 
Level 5
Joined
Aug 27, 2007
Messages
138
The script is 223 pages in word. o_O

And NewGen troubles? Sounds like that could be the problem. They working on a new version or something?
 
Level 9
Joined
May 28, 2007
Messages
365
You can get the newest JassHelper here:

http://www.wc3c.net/showthread.php?t=88142

I think NewGen packs are on that page as well.

If it's crashing on load, then find out everything that happens on map Init. Do you have any event - "Map Initialization" because that should be where you look first. Post that code if you have it.
(This is only if it crashes right on start (0.0 seconds in the game))
 
Level 5
Joined
Aug 27, 2007
Messages
138
I've already updated the JASSHelper, and I've been using the latest NewGen for a while.

I was thinking it could be RtC, but I don't have the RtC menu anywhere so I'm assuming it's disabled by default.

It's not on the map init--it fatals when someone downloads it, or when I host it after playing something else. I tried removing certain parts of the map and testing to see if the issue still persists, but the crashes are so unpredictable that doing that has led to a lot of false positives.

The things I've been thinking of so far that might cause the issue are faulty imports (but those would cause crash on placement or observation), accidental return bug (but that would make it unhostable), or illegalities in the script (which probably aren't the culprit). Most of the spells have been rewritten and look something like this (though not all of them use private constants and the newer ones that do use globals):

(Also, pasting screwed up my tabs. Tried to fix them, but ehhhhh.)

JASS:
scope sr initializer initsr

        private constant function i takes nothing returns integer
            return 'A002'
        endfunction

        private constant function e takes nothing returns string
            return "war3mapImported\\DarkNova.mdx" 
        endfunction

        private constant function l takes nothing returns real
            return 85.
        endfunction
    
        private constant function r takes nothing returns real
            return 425.
        endfunction
    
        private constant function f takes nothing returns string
            return "war3mapImported\\DispersePurple.mdx"
        endfunction
    
	private struct datasr
            real x
            real y
            unit c
            group g
            real f
            unit t
            real d
        
            method onDestroy takes nothing returns nothing
                call DestroyGroup(.g)
                set .g = null
                set .t = null
                set .c = null
            endmethod
        
	endstruct

        function csr takes nothing returns boolean
            return GetSpellAbilityId() == i()
        endfunction

	private function M takes nothing returns nothing
            local timer t = GetExpiredTimer()
            local datasr d = GetTimerInt(t)
            local real x = GetUnitX(d.c)
      	     local real y = GetUnitY(d.c)
            local real x2 = d.x - x
            local real y2 = d.y - y
            call SetUnitX(d.c, x + l() * Cos(d.f))
            call SetUnitY(d.c, y + l() * Sin(d.f))
            if SquareRoot(x2 * x2 + y2 * y2) < 70 or GetTerrainCliffLevel(GetUnitX(d.c), GetUnitY(d.c)) > 3 then
                call DestroyEffect(AddSpecialEffect(e(), d.x, d.y))
                call SetUnitX(d.c, x)
                call SetUnitY(d.c, y)
                call PauseUnit(d.c, false)
                call SetUnitInvulnerable(d.c, false)
                set d.g = CreateGroup()
                call GroupEnumUnitsInRange(d.g, d.x, d.y, r(), udg_f)
                loop
                    set d.t = FirstOfGroup(d.g)
                    exitwhen d.t == null
                    if (IsUnitEnemy(d.t, GetOwningPlayer(d.c)) == true) and (IsUnitType(d.c, UNIT_TYPE_MECHANICAL) == false)  then
                        call UnitDamageTarget(d.c, d.t, d.d, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
                        call DestroyEffect(AddSpecialEffect(f(), d.x, d.y))
                    endif
                    call GroupRemoveUnit(d.g, d.t)
                    set d.t = null
                endloop
                call SetUnitPathing(d.c, true)
                call DestroyTimer(t)
                call SetUnitTimeScale(d.c, 1)
                call datasr.destroy(d)
                set t = null
                return
            endif
            call TimerAttach(t, .02, d, function M)
            set t=null
        endfunction

	function sr takes nothing returns nothing
            local datasr d = datasr.create()
            local timer t = CreateTimer()
            set d.c = GetTriggerUnit()
            set d.x = GetLocationX(GetSpellTargetLoc())
            set d.y = GetLocationY(GetSpellTargetLoc())
            set d.f = Atan2(d.y - GetUnitY(d.c), d.x - GetUnitX(d.c))
            set d.d = 100.00 * I2R(GetUnitAbilityLevel(d.c, i()))
            call SetUnitPathing(d.c, false)
            call SetUnitTimeScale(d.c, 0)
            call PauseUnit(d.c, false)
            call SetUnitInvulnerable(d.c, true)
            call TimerAttach(t, .02, d, function M)
            set t=null
	endfunction

    function initsr takes nothing returns nothing
        local trigger t = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function csr))
        call TriggerAddAction( t, function sr)
        call Preload(e())
        call Preload(f())
    endfunction

endscope

I did have a version a while back that seemed like it worked, but now I'm thinking that I just got lucky and didn't see any crashes (if I remember correctly, though, I didn't crash when hosting it). There was nothing special about that version, though. I need to rule out the possibility that it's a save issue, so I guess I need to play around with some other maps sometime.

Edit:

Also, this is what's left of my map script. TimerAttach() is by C_G and CSSafety by Vexorian, but everything else mine:

JASS:
library TimerHacks

    globals
        private timer array T
        private integer N = 0
    endglobals

    function NewTimer takes nothing returns timer
        if (N==0) then
            return CreateTimer()
        endif
        set N=N-1
        return T[N]
    endfunction

    function ReleaseTimer takes timer t returns nothing
        call PauseTimer(t)
        if (N==8191) then
            call DestroyTimer(t)
        else
            set T[N]=t
            set N=N+1
        endif    
    endfunction


    function TimerAttach takes timer t, real time, real value, code fun returns nothing
        call TimerStart(t, value, false, null)
        call PauseTimer(t)
        call TimerStart(t, time, false, fun)
    endfunction

    function GetTimerInt takes timer t returns integer
        return R2I(TimerGetRemaining(t) + 0.5)
    endfunction

endlibrary

library BasicFuncs requires TimerHacks

    globals
        boolexpr udg_f
    endglobals

    function nullexpr takes nothing returns boolean
        return true
    endfunction

    function endpause takes nothing returns nothing
        local group g = CreateGroup()
        local unit u
        call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, udg_f)
        loop
            set u = FirstOfGroup(g)
            exitwhen u == null
            call PauseUnit(u, true)
            call GroupRemoveUnit(g, u)
            set u = null
        endloop    
        call DestroyGroup(g)
        set g = null
    endfunction

    function isally takes nothing returns boolean
        return IsUnitAlly(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) 
    endfunction

    function isenemy takes nothing returns boolean
        return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) 
    endfunction

endlibrary

library SpellAccessories requires TimerHacks

    function CreateSpellDamageTextTag takes real r, real x, real y returns nothing
        local texttag t = CreateTextTag()
        call SetTextTagText(t, I2S(R2I((r))), .02)
        call SetTextTagPos(t, x, y, 0)
        call SetTextTagColor(t, 255, 127, 127, 255)
        call SetTextTagPermanent(t, false)
        call SetTextTagVelocity(t, 0, .0355  ) 
        call SetTextTagFadepoint(t, .75)
        call SetTextTagLifespan(t, 2)   
        call SetTextTagVisibility(t, false)
        if IsPlayerInForce(GetLocalPlayer(), bj_FORCE_ALL_PLAYERS) then
            call SetTextTagVisibility(t, true)
        endif
        call TriggerSleepAction(2.00)
        call DestroyTextTag(t)
        set t = null
    endfunction

    function CreateSpellHealTextTag takes real r, real x, real y returns nothing
        local texttag t = CreateTextTag()
        call SetTextTagText(t, I2S(R2I((r))), .02)
        call SetTextTagPos(t, x, y, 0)
        call SetTextTagColor(t, 127, 255, 127, 255)
        call SetTextTagPermanent(t, false)
        call SetTextTagVelocity(t, 0, .0355  ) 
        call SetTextTagFadepoint(t, .75)
        call SetTextTagLifespan(t, 2)   
        call SetTextTagVisibility(t, false)
        if IsPlayerInForce(GetLocalPlayer(), bj_FORCE_ALL_PLAYERS) then
            call SetTextTagVisibility(t, true)
        endif
        call TriggerSleepAction(2.00)
        call DestroyTextTag(t)
        set t = null
    endfunction


    scope lightningfadeout

        private struct lfdata
            lightning l
            real x1
            real y1
            real x2
            real y2
            real interval
            integer count = 0
        
            method onDestroy takes nothing returns nothing
                call DestroyLightning(.l)
                set .l = null
            endmethod
        
        endstruct

        private function FadeLightningChild takes nothing returns nothing
            local timer t = GetExpiredTimer()
            local lfdata d = GetTimerInt(t)
            set d.count = d.count + 1
            if d.count == 99 then
                call lfdata.destroy(d)
                call ReleaseTimer(t)
            else 
                call SetLightningColor(d.l, GetLightningColorR(d.l), GetLightningColorG(d.l), GetLightningColorR(d.l), GetLightningColorA(d.l) + 1)
                call TimerAttach(t, d.interval, I2R(d), function FadeLightningChild)
            endif
        endfunction

        function CreateLightningAndFade takes string codeName, real x1, real y1, real x2, real y2, real fadeDuration, real fadeDelay returns lightning
            local timer t = NewTimer()
            local lfdata d = lfdata.create()
            set d.x1 = x1
            set d.y1 = y1
            set d.x2 = x2
            set d.y2 = y2
            set d.l = AddLightning(codeName, true, x1, y1, x2, y2)
            set d.interval = fadeDuration/100
            call TimerAttach(t, fadeDelay, I2R(d), function FadeLightningChild)
            return d.l
        endfunction

    endscope

endlibrary

There are zero instances of the return bug.
 
Status
Not open for further replies.
Top