I don't need to test my programs. I have an error-correcting modem.

User:Wormbo/SlowVacuumZone

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search
UT Object >> Actor >> Info >> ZoneInfo >> VacuumZone >> SlowVacuumZone (custom)
Package: 
SlowVacuumZone

I created this class per request by R3plicant, who wanted a VacuumZone with a long kill time to give players a chance to get out again. The problem with the standard VacuumZone is, it uses the Fatness value to track its progress. That's a byte property though, and its lack of precision causes the zone to "hang" if the kill time is too high.

SlowVacuumZone

The SlowVacuumZone is a special implementation that tracks depressurization progress separately to ensure it never "hangs" and that players have the full KillTime to get out of the zone again. To achieve this for an arbitrary number of players I used a helper class to build a linked list. (See below)

/******************************************************************************
SlowVacuumZone
 
Creation date: 2008-11-29 18:05
Last change: $Id$
Copyright (c) 2008, Wormbo
******************************************************************************/
 
class SlowVacuumZone extends VacuumZone;
 
 
var SlowVacuumZoneListItem Active, Pool;
 
 
/**
Adds a Pawn to the active list, it it isn't already in the list.
*/
function AddPawn(Pawn Other)
{
	local SlowVacuumZoneListItem Item;
 
	for (Item = Active; Item != None; Item = Item.Next) {
		if (Item.Pawn == Other)
			return; // pawn already is in the list
	}
 
	if (Pool != None) {
		Item = Pool;
		Pool = Item.Next;
	}
	else {
		Item = new class'SlowVacuumZoneListItem';
	}
	Item.Init(Other, Active);
	Active = Item;
}
 
 
/**
Adds an unused item to the item pool.
*/
function FreeItem(SlowVacuumZoneListItem Item)
{
	Item.Init(None, Pool);
	Pool = Item;
}
 
 
/**
When a living player enters this zone, start Tick() to death.
*/
event ActorEntered(Actor Other)
{
	local Pawn P;
 
	Super(ZoneInfo).ActorEntered(Other);
 
	P = Pawn(Other);
	if (P != None && P.Health > 0) {
		// Maybe scream?
		if (P.bIsPlayer) {
			// Scream now
			P.PlaySound(P.Die, SLOT_Talk);
		}
		AddPawn(P);
		Enable('Tick');
	}
}
 
 
/**
Continuously update players getting depressurized in this zone.
*/
function Tick(float DeltaTime)
{
	local float curScale;
	local vector curFog;
	local PlayerPawn pPawn;
	local SlowVacuumZoneListItem Item, Prev;
 
	// first, clear all invalid entries from the beginning of the list
	while (Active != None && (Active.Pawn == None || Active.Pawn.Region.Zone != Self || Active.Pawn.Health <= 0)) {
		Item = Active;
		Active = Active.Next;
		FreeItem(Item);
	}
	Item = Active;
	Prev = Item;
	while (Item != None) {
		// previous while loop ensures that the following condition will never be true during the first loop:
		if (Item.Pawn == None || Item.Pawn.Region.Zone != Self || Item.Pawn.Health <= 0) {
			Prev.Next = Item.Next;
			FreeItem(Item);
			Item = Prev.Next;
			continue;
		}
 
		// player is alive and in this zone
		Item.Ratio += DeltaTime / KillTime;
		if (Item.Ratio > 1.0)
			Item.Ratio = 1.0;
 
		// Fatness (not actually linear interpolation, but might look interesting nonetheless)
		Item.Pawn.Fatness = Lerp(Item.Ratio, Item.Pawn.Fatness, 255.0);
 
		// Fog & Field of view
		pPawn = PlayerPawn(Item.Pawn);
		if (pPawn != None) {
			curScale = (EndFlashScale-StartFlashScale) * Item.Ratio + StartFlashScale;
			curFog   = (EndFlashFog  -StartFlashFog  ) * Item.Ratio + StartFlashFog;
			pPawn.ClientFlash(curScale, 1000 * curFog);
 
			pPawn.SetFOVAngle((DieFOV - pPawn.default.FOVAngle) * Item.Ratio + pPawn.default.FOVAngle);
		}
		if (Item.Ratio == 1.0) {
			Level.Game.SpecialDamageString = DamageString;
			Item.Pawn.TakeDamage(10000, Item.Pawn, Item.Pawn.Location, vect(0,0,0), DamageType);
			MakeNormal(Item.Pawn);
			// item will be removed in next tick
		}
 
		// next item
		Prev = Item;
		Item = Item.Next;
	}	
 
	if (Active == None)
		Disable('Tick');
}

SlowVacuumZoneListItem

UT Object >> SlowVacuumZoneListItem (custom)
Package: 
SlowVacuumZone

This is the helper class for building the linked list of affected players.

/******************************************************************************
SlowVacuumZoneListItem
 
Creation date: 2008-11-29 18:51
Last change: $Id$
Copyright (c) 2008, Wormbo
******************************************************************************/
 
class SlowVacuumZoneListItem extends Object;
 
/**
Next item in linked list.
*/
var SlowVacuumZoneListItem Next;
 
/**
Pawn marked by this list item.
*/
var Pawn Pawn;
 
/**
Progress of vaccuum death for the marked Pawn.
*/
var float Ratio;
 
 
function Init(Pawn NewPawn, SlowVacuumZoneListItem NewNext)
{
	Pawn = NewPawn;
	Ratio = 0.0;
	Next = NewNext;
}