I've sussed out replication so that the snow continues if you leave the zone and if you "kill" the source of the snow (in this case the Ice Dragon). However the flakes that lose falling velocity remain there. I've tested this thing to death and I cannot see any reason for this behavior. I know it's a bit of code but can someone peek at this and tell me if an issue jumps out at you? Once this is fixed I'll post the mod/source so everyone can use fully working snow effects tied to actors (like moving clouds in the sky, etc). I'm really close but I just can't close the deal.
Here is a very short vid of the issue. This is online play:
See the flakes that linger in the sky? They are being affected by the "wind" part of the code but do not fall and do not destroy when the spawning actor is destroyed.
The flake code:
Code: Select all
class SnowDrop expands Effects;
var bool bIgnoreZoneChange;
var SnowActor Snowy;
var float am;
var bool bInitialized;
simulated function SetupSnow(float StartZ)
{
local vector NewLoc, v;
bInitialized = true;
bIgnoreZoneChange = true;
if (Snowy==None || Snowy.bDeleteMe)
{
Snowy=SnowActor(Owner);
if (Snowy==None || Snowy.bDeleteMe)
{
destroy();
bIgnoreZoneChange = false;
return;
}
}
NewLoc.X = Snowy.Location.X + FRand()*2*Snowy.Radius-Snowy.Radius;
NewLoc.Y = Snowy.Location.Y + FRand()*2*Snowy.Radius-Snowy.Radius;
NewLoc.Z = Snowy.Location.Z - StartZ;
am = (frand() * 16)+16;
v = Snowy.WindEffect;
v.Z = (Snowy.FallSpeedMinimum + (frand() * (Snowy.FallSpeedMaximum-Snowy.FallSpeedMinimum))) * -1;
if (!SetLocation(NewLoc))
{
SetupSnow(StartZ);
bIgnoreZoneChange = false;
return;
}
Velocity = v;
GotoState('Fall');
bIgnoreZoneChange = false;
}
simulated function HitWall(vector HitNormal, actor HitWall)
{
GotoState('Melting');
}
simulated function Landed(vector HitNormal)
{
SetupSnow(0);
}
simulated function Touch(actor Other)
{
SetupSnow(0);
}
simulated event ZoneChange(ZoneInfo NewZone)
{
if ((bInitialized) && (!bIgnoreZoneChange))
SetupSnow(0);
}
auto State Fall
{
simulated function Timer()
{
local vector v;
if (Snowy != none)
{
V = Velocity;
v.X = Snowy.WindEffect.X + (am * sin(location.z));
v.Y = Snowy.WindEffect.X + (am * sin(location.z));
Velocity = V;
}
}
begin:
SetTimer(0.5,true);
}
State Melting
{
simulated function Timer()
{
SetupSnow(0);
}
begin:
SetTimer(1.0,false);
}
defaultproperties
{
Physics=PHYS_Projectile
RemoteRole=ROLE_None
DrawType=DT_Sprite
Style=STY_Translucent
Texture=Texture'Snow1'
DrawScale=0.20
CollisionRadius=1.00
CollisionHeight=1.00
bCollideActors=True
bCollideWorld=True
}
Code: Select all
class SnowActor expands Effects;
var float Radius;
var float MaxDrops;
var float FallSpeedMaximum;
var float FallSpeedMinimum;
var int SpawnHeight;
var vector WindEffect;
var int SnowCount;
replication
{
reliable if (Role==ROLE_Authority)
Radius, MaxDrops, FallSpeedMaximum, FallSpeedMinimum, WindEffect, SpawnHeight;
}
simulated function Tick(float deltatime)
{
local int i;
local float MaxZ;
local Vector T,V,N;
local Actor A;
local SnowDrop Flake;
if (Owner == None)
{
if (Role == ROLE_Authority)
Destroy();
return;
}
else if (Level.Netmode == NM_DedicatedServer)
return;
if(FastTrace(location + vect(0, 0, +1) * SpawnHeight))
SetLocation(Owner.Location + vect(0, 0, +1) * SpawnHeight);
else if(FastTrace(location + vect(0, 0, +1) * (SpawnHeight/2)))
SetLocation(Owner.Location + vect(0, 0, +1) * (SpawnHeight/2));
else SetLocation(Owner.Location);
if (SnowCount