HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Player-specific weather

05-15-2009, 01:57 PM#1
Opossum
I'm having a weird problem with a recent script that's is supposed to let a player change his local weather.
The problem is though that whenever Player(0) changes his weather, Player(1)'s weather will be removed (or vice verca, probably occurs with multiple players too).
Expand JASS:

Now what I'm wondering about is: How can Player(1)'s weather effect (that is WeatherEffect[1]) be destroyed if Player(0) changes his weather (that is WeatherEffect[0])?
I know about that "One Effect Rule" but I can't see how that applies here as player specific weather effects are created across a null rect and shouldn't interfere with the other players' effects.
05-15-2009, 02:54 PM#2
rain9441
Not sure if this relates 100% but it might.

The first weather effect you create will have an identification of 0. The second weather you create will have an identification of 1.

If you call RemoveWeatherEffect() on an array of weathereffects whos index has never been set, you will be removing the first weather effect you've ever added to the map.

EG, RemoveWeatherEffect(null) does infact remove a weather effect, and that weather effect is weather effect #0.

Are you following me?

Your culprit lies here:
Collapse JASS:
set Weather[p] = CappedInt(Weather[p]+i, 0, MAX_WEATHER-1) //makes sure the returned value is between 0 and MAX_WEATHER-1
    call RemoveWeatherEffect(WeatherEffect[p])

It's just a weathereffect gotcha
05-15-2009, 02:56 PM#3
Opossum
Hmm didn't know that. So basically I have to check if that weather effect equals null before removing it?
Gonna try that. +rep if it works :)
05-15-2009, 03:00 PM#4
rain9441
Quote:
Originally Posted by Opossum
Hmm didn't know that. So basically I have to check if that weather effect equals null before removing it?

Nope, a null weather effect actually probably is a weather effect. There is no valid test to find whether a weathereffect is "null" or even exists in the game, you have to make those validity tests yourself.

null is going to be an actual weathereffect almost every time.

I think what I did was create one single weather effect in a corner of the map that didn't do anything, left that at index 0, and made all my bounds checks start at 1. Thus you never remove weathereffect 0, nor do you see it.
05-15-2009, 03:13 PM#5
Opossum
I just tried the null check before you posted and it pretty much proves your point.
The weather effects of different players didn't interfere anymore but I could never remove the first created weather effect as that one probably is null.
So I guess that null check will be ok if the first created weather effect is one that will never be seen by the players like you said or will other effects than the very first return null too? If yes then... wow that's pretty much screwed up.
05-15-2009, 03:22 PM#6
rain9441
It isn't quite screwed up, you just have to think about it in a different way. weathereffects are actually integers, not handles.

The best way is probably to do something like this.

Have an array of weathereffects like you do

Collapse JASS:
  if (WeatherEffectIsValid[index] == true) then
    call DestroyWeatherEffect(WeatherEffect[index])
    set WeatherEffectIsValid[index] = false
  endif

  set WeatherEffect[index] = AddWeatherEffect(...)
  set WeatherEffectIsValid[index] = true

That would part of an approach of creating your own validity check. Then you don't have to deal with the (0|null) weather effect being destroyed accidently because you only ever destroy weather effects you know you've created.

Cheers!
05-15-2009, 04:10 PM#7
Opossum
Well actually if a handle exists but returns null that feels pretty screwed up to me.

Anyway... that valid method won't quite work for me. I'm creating weather effects for all players but they are null for all players that are not supposed to see that effect because these effects are added to a null region.
Expand JASS:
I just tested that and it turned out that once again players remove each other's weather effects. I guess because all players except for the player who actually sees the weather effect have a null weather effect. So when removing that effect the effect #0 will be removed again. It's just pretty weird that this doesn't cause a desync though.
05-15-2009, 04:42 PM#8
rain9441
I'm fairly certain weather effects are async. They have no impact on gameplay what so ever as long as you don't use them in your scripts as a test. Can you create weather effects for all players and only Enable the weather effect for a certain LocalPlayer? It seems right now that the way you are doing it you are only creating weather effects for one player, so all players will have a different weather effect at index #0.
05-15-2009, 04:52 PM#9
Opossum
Creating weather effects and thus creating handles locally is causing desyncs.
Quote:
Can you create weather effects for all players and only Enable the weather effect for a certain LocalPlayer?
It works kinda and I wish I could use that but two players couldn't have the same type of effect (rain, fog, shield) at a time.
Currently I'm actually creating the effect for all players but only in a valid rect for the local player. And it seems weather effects that are created on a null rect are actually null themselves which complicates the whole issue pretty much.
I guess I'll have to include the validity variable into the local code as it seems that removing effects locally doesn't desync.
Edit: Ok removing effects locally DOES desync.
05-15-2009, 05:15 PM#10
rain9441
What if you were to create one rain effect for all players and only enable it for the players who should see rain? Same for snow, etc.

It sounds to me like making the call to AddWeatherEffect with a null rect is equivalent to not making the call at all, so you may want to veer away from that solution entirely.
05-15-2009, 05:27 PM#11
Opossum
Then I could only make one out of four rain effects etc. available to the players.
AddWeatherEffect with a null rect is not the same as not making the call at all because the creation of this handle is executed for all players and thus not causing a desync.

What I'm working on is a script called "AtmoUtils". It's a keyboard-controlled multiboard that can be activated for any player(s). You can change sky model, weather, fog settings and water color in real-time. Basically it's a testing tool to get the best out of one's terrain without having to save the map hundres of time to see how the settings work out ingame.
If I really can't get this to work then I guess I'll just let all players share the same weather.

What's weird is that besides having a strange nulling behavior is that the first ever created weather effect will be removed if the removed weather effect is null for ANY player without even causing a desync.
I mean this could be a great way to sync some values maybe but it's not useful here at all.
05-16-2009, 06:54 AM#12
Viikuna-
Why dont you just create weather effect for everyone normally, and then use GetLocalPlayer to diable/enable it?

If you need same effect for more than 1 guy, you could always create some force for and add those players who can see effect to it and do IsPlayerInForce(GetLocalPlayer(),force) or something.
05-16-2009, 11:39 AM#13
Opossum
Because like I already said that "One Effect Rule" doesn't allow this kind of method.
You can only have one rain/shield/fog/ray/wind/snow effect per 512x512. So when the weather effect "ashenvale rain (heavy)" is created, you won't be able to create a different rain effect on the same region. That includes "ashenvale rain (light)", "lordaeron rain (heavy)" etc...
05-16-2009, 01:45 PM#14
rain9441
I know this is possible to do, as DOTA does it. If DOTA does it, you can do it. There must be a way!

I'm thinking the only thing kickin' your ass right now is the fact that a null rect passed to add weather returns "null" which you don't know is null, and after everyone decides to add a weather effect, everyone has a null weather effect which isn't really null.

Have you checked the dota source maybe to see what they do? Its obfuscated but you can still probably make out whats going on around the AddWeather call(s)
05-16-2009, 01:59 PM#15
Opossum
Does DotA make ALL weather effects available to all players or just one per type?

Also yeah that null rect really fucks it up. I'd need some sort of null weather effect id but effectID == 0 causes a crit error (nice to keep in mind if you need a crit error in the future though).