I love the smell of UnrealEd crashing in the morning. – tarquin

User:Wormbo/SelectableSkyZoneInfo

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search
UE2 Object >> Actor >> Info >> ZoneInfo >> SelectableSkyZoneInfo (custom)

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

UE1 Object >> Actor >> Info >> ZoneInfo >> SelectableSkyZoneInfo (custom)

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;
}