Another light solution

Development assistance and tutorials here.
Post Reply
Nelsona
Posts: 410
Joined: Sat Sep 30, 2017 5:03 am

Another light solution

Post by Nelsona » Wed May 02, 2018 7:24 pm

If you did not see so far, in these fascinating MH Levels everything would be a charm if UT would not render coronas through monsters and generally through meshes so to speak Colliding Pawns and such.
These are bugging visibility as long as more far you go, more bigger any annoying they are. Because I was interested to find a solution, today I've done some light in purpose to come LATER, in run-time and not mapped/build with Level.
I see a clear advantage at using this method, so tracing visibility for Level's owner is not needed as long as it won't go through Pawns as I could see so far and neither through other colliding decorations making game more closer to reality.
Speaking about distance vs DrawScale it do works in a desired range without to go smaller when is very close and huge at far away distances having a decent visibility - I guess. It stays between some values and I wrote that formula today - first time was not that accurate. Due to render specifications this corona light has a bigger drawscale than mapped ones because this way do looks normal.
In order to to not spam useless sentences, here is the class spawning at Lanterns location which because are not colliding are leaving this light to pass through. Yeah this is a dynamic things entirely handled by client working fine on my rigs.

Code: Select all

class Crn_Light expands Light;

var PlayerPawn P;
var int MinDist;
var int MaxDist;
var float MaxScale;
var float MinScale;
var bool bHideMe;

#exec obj load file=..\Textures\GenFX.utx Package=GenFX

event PreBeginPlay()
{
	InitialState = 'Lightning';
}

final function GetOwner()
{
	local PlayerPawn P1;

	foreach Level.AllActors(class'PlayerPawn',P1)
	{
		if (P1.Player != None && P1.Player.Console != None)
		{
			P = P1;
			break;
		}
	}
}

/*
final function bool NotVisible(PlayerPawn MyPlayer)
{
	local bool bResult;
	local actor HitActor;
	local vector HitLocation, HitNormal;

	bResult = True;
	if ( MyPlayer == None )
	{
		bResult = True;
		GoTo Result;
	}
	HitActor = Trace(HitLocation, HitNormal, Location, MyPlayer.Location+vect(0,0,40), True);
	if ( HitActor == None )
		bResult = False;
Result:
//	log (Self.Name@"Not Visible ="@bResult);
	return bResult;
}
*/

final function SetDrawScale()
{
	local float CurrentScale;
	local int ViewDist;

	if ( P == None ) goto NothingDoable;
	ViewDist = VSize( (P.Location+vect(0,0,38))-Location );
	if ( ViewDist <= MinDist )
	{
		CurrentScale = MinScale;
		GoTo Result;
	}
	if ( ViewDist >= MaxDist )
	{
		CurrentScale = MaxScale;
		GoTo Result;
	}
//	CurrentScale = MinScale + (ViewDist/((MaxDist - MinDist)/(MaxScale - MinScale)));
	CurrentScale = MinScale + (((MaxScale - MinScale)/(MaxDist - MinDist)) * ( ViewDist - MinDist ));
Result:
	DrawScale = CurrentScale;
//	log(Self.Name@"has DrawScale"@DrawScale@"at"@ViewDist);
NothingDoable:

}

State() Lightning
{
Begin:
//	log(Self.Name@"working...");
	Sleep(0.2);
	MinScale = DrawScale;
	MaxScale = MinScale + 4.000000;
	MinDist = 400;
	MaxDist = 4000;
NoneYet:
	Sleep(2.00);
	if ( P == None )
	{
		GetOwner();
		GoTo('NoneYet');
	}
LoopAndDraw:
	Sleep(0.33);
	SetDrawScale();
//	bHidden = NotVisible(P);
	Goto('LoopAndDraw');
}

defaultproperties
{
	bNoDelete=False
	bStatic=False
	bMovable=True
	bCorona=True
	bHidden=False
	bCollideWorld=False
	bCollideWhenPlacing=False
	DrawScale=1.500000
	Style=STY_Translucent
	ScaleGlow=1.600000
	Texture=Texture'Flare7'
	RemoteRole=ROLE_None
}
As you see doesn't need any RemoteRole so it's not part of Networking. If more players are connected, each of them has own deal with these without having nothing each-other, each copy of Levels from clients has its own deal with their Owner. Oh yes, this actor is VISIBLE.
The deal with client happens in a Spawn Notification actor.

Code: Select all

class ThingsNotify expands SpawnNotify;

function prebeginplay(); //don't check for relevance

simulated function PostBeginPlay()
{
	local actor other;

	//Don't add to notifylist if server, but keep available, so it's existence is replicated to clients
	if (Level.NetMode == NM_DedicatedServer) //mutator works on server. We keep moving in client
		GoTo Done;
	Super.PostBeginPlay();
	log ("Deco Notify Initialized...",'TempleOfTheGods');
	ForEach Allactors(class'actor',other)
	{
		if (Other.IsA('Lantern2'))
		{
			Other.ScaleGlow = 240;
			Other.bUnlit = True;
			Spawn(class'Crn_Light',,,Other.Location);
			continue;
		}
		if (Other.IsA('Lantern'))
		{
			Other.ScaleGlow = 240;
			Other.bUnlit = True;
			Spawn(class'Crn_Light',,,Other.Location);
			continue;
		}
	}
	SpawnOtherStuff();
Done:
}

final simulated function SpawnOtherStuff()
{
	local Rotator NewRot;
	local Actor A;

	Level.AmbientBrightness = 72; //A bit more Bright
	NewRot.Yaw=16384;
	Spawn(class'NavAdderGen',,,vect(1276,-576,-376),NewRot);
}

defaultproperties
{
}
That's the deal, server won't mess with them.

EDIT:
Another type of dynamic coronas I set in another map which will react in clients, actor being latent in servers and these do work only for clients connected to server. You might now the primary version of it, I used such actors in their primary format for map MH-Sk_BattlingLottery. Now code is different optimized.
When stuff will be added to XC MH HOF server you will know and then you can check directly for figuring if you do like these things.
Not often maintained
My UT Mapping works...
Learn the rules like a pro, so you can break them like an artist.
- Pablo Picasso -

Post Reply