Skip to content

Instantly share code, notes, and snippets.

@wallabra
Last active February 26, 2021 03:15
Show Gist options
  • Save wallabra/43a4c1a26e7f51688141c939daf55105 to your computer and use it in GitHub Desktop.
Save wallabra/43a4c1a26e7f51688141c939daf55105 to your computer and use it in GitHub Desktop.
UT99 air/gravity vortex source code
//=============================================================================
// StrategicalVortex.
//=============================================================================
class StrategicalVortex expands Effects;
// Physics variables
var(Vortex) float CyclesPerSecond;
var(Vortex) float ActionRadius;
var(Vortex) float ActionStrenght;
var(Vortex) float ActionMassIgnorance; /* This variable dictates how much is mass ignored during
* physics calculations.
*/
var(Vortex) float ActionVisibilityFactor; /* The pull strenght is modified by this variable if
* a FastTrace to the pulled actor returns False.
*/
var(Vortex) float ActionCycleDensity;
var(Vortex) float DamageCycleDensity;
var(Vortex) float DamageRadius;
var(Vortex) float DamagePerCycle;
var(Vortex) bool bActive; /* If False, the pull won't happen;
* can be set at runtime as well.
*
* Use VortexSwitch to use!
*/
var(Vortex) float VortexLifespan; // Set to 0 to deactivate lifespan.
var bool bLifespanActive;
/*
* || Percentage functions
*
* They act on numbers to either:
*
* - Modify their value using a percentage;
*
* - Return a random boolean depending on a percentage
* which acts as a chance.
*/
function float PercentModify(float Percent, out float Number)
{
Number *= Percent / 100;
return Number;
}
function bool PercentChance(float Percent)
{
return FRand() * 100 <= Percent && Percent > 0;
}
/*
* || Mathematical functions
*
* They act on actors to determine the distances
* and other similiar relative mathematical values
* applicable between actors.
*
* These are used on e.g. GetActorPull to
* get the distance.
*/
function float DistanceTo(Actor OtherActor)
{
return VSize(OtherActor.Location - Location);
}
function float ModifyIf(float A, float B, bool C)
{
if ( C ) return A * B;
else return A;
}
/*
* || Physical functions
*
* They act on any Actors with
* enabled physics around in
* order to:
*
* - Pull them towards the vortex changing the velocity
* as the distance between both decreases, allowing
* for orbiting.
*
* - Deal damage as these actors reach the DamageRadius
* from the vortex.
*
* - Use Cycle Density algorithms to determine the
* Real Damage and Pulling Rates (RDR and RPR,
* terms used officialy by this actor).
*/
// Calculates pull force.
function float GetActorPull(Actor ThisActor)
{
return Max(
0,
ModifyIf(
(ActionRadius - DistanceTo(ThisActor)) * ActionStrenght / (ThisActor.Mass / ActionMassIgnorance / 100),
ActionVisibilityFactor,
!FastTrace(ThisActor.Location)
)
);
}
// Calculates damage force.
function float CalculateDamage(Actor ThisActor)
{
return Max(
0,
ModifyIf(
(DamageRadius - DistanceTo(ThisActor)) * DamagePerCycle,
ActionVisibilityFactor,
!FastTrace(ThisActor.Location)
)
);
}
// Converts pull force into a vector.
function Vector ConvertPull(Actor ThisActor)
{
return (ThisActor.Location - Location) * GetActorPull(ThisActor);
}
// Vortex functions.
function PreBeginPlay()
{
bLifespanActive = VortexLifespan > 0;
}
function PostBeginPlay()
{
SetTimer(1.0 / CyclesPerSecond, true);
}
function Tick(float TimeDelta)
{
local VortexDestruction vg;
if ( bLifespanActive )
{
VortexLifespan -= TimeDelta;
if ( VortexLifespan <= 0 )
{
vg = Spawn(class'VortexDestruction'); // Fun Fact: "vg" stands for Vortex Gibs.
vg.SetParams(ActionRadius, ActionStrenght);
Destroy();
}
}
}
function Timer()
{
local Actor A;
foreach AllActors(class'Actor', A)
{
if ( A.Physics == PHYS_None || DistanceTo(A) > ActionRadius ) continue;
if ( PercentChance(DamageCycleDensity) )
{
A.TakeDamage(CalculateDamage(A), Pawn(Owner), Location, vect(0, 0, 0), 'vortex_damage');
if ( Pawn(A) != None && Pawn(A).Health <= 0 ) A.KilledBy(Pawn(Owner));
}
if ( PercentChance(ActionCycleDensity) ) A.Velocity += ConvertPull(A);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment