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

weathereffect always equal to null???

Status
Not open for further replies.
Level 15
Joined
Aug 7, 2013
Messages
1,337
Hi,

I have this code below, which didn't behave as expected.

JASS:
		if e != 0 then and e.weather != null then //this never returns as true
			call EnableWeatherEffect(e.weather, false)

So "e" is some struct, and it has a field "weather" which is of type weathereffect.

The "if" statement above never returns as true, and thus the body doesn't get called. However, I know for a fact that "e.weather" is actually not null. as this code ran correctly before it.

JASS:
    static method create takes integer effectID returns thistype
        local thistype this = thistype.allocate()
		set this.weather = AddWeatherEffect(r, effectID)
        return this
    endmethod

So the weather exists (rays of light over a rect), but for some reason I can only remove the weather when I remove my null safety check.

JASS:
		if e != 0 then//and e.weather != null then this works and doesn't crash
			call EnableWeatherEffect(e.weather, false


The above code works, and removes the weather correctly--no crashes either. But that's a contradiction, because it means the weather effect is somehow still null and removing a null handle = crash?
 
Level 15
Joined
Aug 7, 2013
Messages
1,337
Damn I was really hoping I was wrong and it's not some bug with weathereffect.

From your link:
Well, weather is an odd thing. You can only have one weather effect inside a 512x512 square. The first weather effect's handle slot is null. Destroying null actually removes the first weather effect.

What does this mean? A map can't have multiple weather effects in disjoint rects? Or having more than one weather in the same/overlapping area has undefined behavior/results?
 
If what Azlier said is true, then try creating a weather effect on init just to take up the null slot. And see if the other weather effects properly evaluate to != null.

That is just a guess though. I haven't dealt with weather effects myself. If that fails, then you may need to keep some boolean of whether the weather effect is actually there. Whenever you set the weather effect, you would set that boolean to true. When you destroy the weather effect, you would set that boolean to false.
 
Level 26
Joined
Mar 19, 2008
Messages
3,140
You might want to use one of my systems, tho this one wasn't released.

JASS:
library WeatherEffect uses Table

globals
    private Table table
endglobals

struct WeatherType extends array
    static constant integer Rain = 0
    static constant integer Shield = 1
    static constant integer DungeonFog = 2
    static constant integer Snow = 3
    static constant integer Wind = 4
    static constant integer Ray = 5
endstruct

struct WeatherStyle extends array
    private static integer count = 0
    readonly integer effectId
    readonly integer type

    readonly static thistype	AshenvaleRainHeavy
    readonly static thistype	AshenvaleRainLight
    readonly static thistype	DalaranShield
    readonly static thistype	DungeonBlueFogHeavy
    readonly static thistype	DungeonBlueFogLight
    readonly static thistype	DungeonGreenFogHeavy
    readonly static thistype	DungeonGreenFogLight
    readonly static thistype	DungeonRedFogHeavy
    readonly static thistype	DungeonRedFogLight
    readonly static thistype	DungeonWhiteFogHeavy
    readonly static thistype	DungeonWhiteFogLight
    readonly static thistype	LordaeronRainHeavy
    readonly static thistype	LordaeronRainLight
    readonly static thistype	NorthrendBlizzard
    readonly static thistype	NorthrendSnowHeavy
    readonly static thistype	NorthrendSnowLight
    readonly static thistype	OutlandWindHeavy
    readonly static thistype	OutlandWindLight
    readonly static thistype	RaysOfLight
    readonly static thistype	RaysOfMoonlight
    readonly static thistype	WindHeavy

    private static method create takes integer id, WeatherType t returns thistype
        local thistype this = count

        set this.effectId = id
        set this.type = t
        set count = count + 1

        return this
    endmethod

    private static method onInit takes nothing returns nothing
        set table = Table.create()

        set AshenvaleRainHeavy = thistype.create('RAhr', WeatherType.Rain)
        set AshenvaleRainLight = thistype.create('RAlr', WeatherType.Rain)
        set DalaranShield = thistype.create('MEds', WeatherType.Shield)
        set DungeonBlueFogHeavy = thistype.create('FDbh', WeatherType.DungeonFog)
        set DungeonBlueFogLight = thistype.create('FDbl', WeatherType.DungeonFog)
        set DungeonGreenFogHeavy = thistype.create('FDgh', WeatherType.DungeonFog)
        set DungeonGreenFogLight = thistype.create('FDgl', WeatherType.DungeonFog)
        set DungeonRedFogHeavy = thistype.create('FDrh', WeatherType.DungeonFog)
        set DungeonRedFogLight = thistype.create('FDrl', WeatherType.DungeonFog)
        set DungeonWhiteFogHeavy = thistype.create('FDwh', WeatherType.DungeonFog)
        set DungeonWhiteFogLight = thistype.create('FDwl', WeatherType.DungeonFog)
        set LordaeronRainHeavy = thistype.create('RLhr', WeatherType.Rain)
        set LordaeronRainLight = thistype.create('RLlr', WeatherType.Rain)
        set NorthrendBlizzard = thistype.create('SNbs', WeatherType.Snow)
        set NorthrendSnowHeavy = thistype.create('SNhs', WeatherType.Snow)
        set NorthrendSnowLight = thistype.create('SNls', WeatherType.Snow)
        set OutlandWindHeavy = thistype.create('WOcw', WeatherType.Wind)
        set OutlandWindLight = thistype.create('WOlw', WeatherType.Wind)
        set RaysOfLight = thistype.create('LRaa', WeatherType.Ray)
        set RaysOfMoonlight = thistype.create('LRma', WeatherType.Ray)
        set WindHeavy = thistype.create('WNcw', WeatherType.Wind)
    endmethod
endstruct

struct WeatherEffect extends array
    readonly weathereffect weather
    readonly rect where
    readonly WeatherStyle style

    implement Alloc

    static method create takes rect r, WeatherStyle ws returns thistype
        local thistype this = table[GetHandleId(r)]

        if ( this == 0 or this.style.type != ws.type ) then
            set this = thistype.allocate()
            set this.where = r
            set table[GetHandleId(r)] = this
        else
            call RemoveWeatherEffect(this.weather)
        endif

        set this.weather = AddWeatherEffect(r, ws.effectId)
        set this.style = ws

        return this
    endmethod

    method destroy takes nothing returns nothing
        if ( weather != null ) then
            call RemoveWeatherEffect(weather)
        endif

        call table.remove(GetHandleId(where))
        set where = null
        set style = 0

        call deallocate()
    endmethod

    method enable takes nothing returns nothing
        if ( this != 0 ) then
            call EnableWeatherEffect(weather, true)
        endif
    endmethod

    method disable takes nothing returns nothing
        if ( this != 0 ) then
            call EnableWeatherEffect(weather, false)
        endif
    endmethod
endstruct

function GetRectWeather takes rect r returns WeatherEffect
    return table[GetHandleId(r)]
endfunction

endlibrary
Wasn't using this for some time now, must admit that I'm unsure if there are any bugs here. It stores weather via rect handle, so the same rect can not have 2 instances of weather with given type t running at the same time. Instead, old one will be replaced.

I might just add description block and paste this into jass section.
 
Status
Not open for further replies.
Top