Always snap to grid
User:Wormbo/SelectableSkyZoneInfo
A ZoneInfo that allows the mapper to select a specific sky box by matching Tag. Keep in mind that only sky box can be visible at a time, so make sure it's not possible to see the fake backdrop surfaces of zones with a different sky box than the current zone. Also make sure you use a SelectableSkyZoneInfo in zones that don't have fake backdrop surfaces if you can see such surfaces of another zone from there.
Unlike other implementations on the Wiki, this one also takes detail level into account. In other words, for each zone you can have different versions of the sky box for low, high and super-high detail mode.
Properties
SkyZoneTag
Type: name
The Tag of the SkyZoneInfo to use. Multiple SkyZoneInfos may have the same Tag, but should have different detail settings.
The implementation below attempts to find a sky box with a matching Tag, but will fall back to a sky box with a non-matching Tag if no matching sky box is found. In addition, like the regular sky box linking code, the sky box with the best-matching detail level is selected.
Implementation
The following code will work in UT2003 and UT2004 without any modifications. This should also apply to other Unreal Engine 2 games, but smaller modifications may be needed. To use this class, create a new subclass of ZoneInfo with the following code:
/****************************************************************************** Allows the mapper to assign specific sky boxes to this zone. Copyright (c) 2009, Wormbo ******************************************************************************/ class SelectableSkyZoneInfo extends ZoneInfo; /** The Tag name of the SkyZoneInfo(s) to use. Multiple SkyZoneInfos may have the same Tag, but should have different detail settings. */ var() name SkyZoneTag; /** Called from PreBeginPlay() to link a SkyZoneInfo actor as this zone's sky box. Finds a SkyZoneInfo with a matching Tag and best-fitting detail level. */ simulated function LinkToSkybox() { local SkyZoneInfo thisSkyZone; foreach AllActors(class'SkyZoneInfo', thisSkyZone) { if (BetterThanCurrentSkyZone(thisSkyZone)) SkyZone = thisSkyZone; } } /** Rates a SkyZoneInfo against the currently linked sky zone. Zones are first rated by Tag match, then by their target detail level. */ function bool BetterThanCurrentSkyZone(SkyZoneInfo OtherSkyZone) { if (SkyZone == None) return true; // no current sky zone, everything is better than that // check matching Tag first if (SkyZone.Tag != SkyZoneTag && OtherSkyZone.Tag == SkyZoneTag) return true; if (SkyZone.Tag == SkyZoneTag && OtherSkyZone.Tag != SkyZoneTag) return false; // here either both match or both don't match, now check detail level // super high detail? if (SkyZone.bSuperHighDetail && !OtherSkyZone.bSuperHighDetail) return Level.DetailMode < DM_SuperHigh; if (OtherSkyZone.bSuperHighDetail) return Level.DetailMode == DM_SuperHigh; // high detail? if (SkyZone.bHighDetail && !OtherSkyZone.bHighDetail) return Level.DetailMode < DM_High; if (OtherSkyZone.bHighDetail) return Level.DetailMode == DM_High; // both have low detail, doesn't matter which one to use return true; }
UE1 Implementation
To make the above code work in UT or other Unreal Engine 1 games, you need to replace the BetterThanCurrentSkyZone() function as follows:
function bool BetterThanCurrentSkyZone(SkyZoneInfo OtherSkyZone) { if (SkyZone == None) return true; // no current sky zone, everything is better than that // check matching Tag first if (SkyZone.Tag != SkyZoneTag && OtherSkyZone.Tag == SkyZoneTag) return true; if (SkyZone.Tag == SkyZoneTag && OtherSkyZone.Tag != SkyZoneTag) return false; // here either both match or both don't match, now check detail level // high detail? if (SkyZone.bHighDetail && !OtherSkyZone.bHighDetail) return !Level.bHighDetailMode; if (OtherSkyZone.bHighDetail) return Level.bHighDetailMode; // both have low detail, doesn't matter which one to use return true; }