Nothing in particular

Discussions about Coding and Scripting
Post Reply
User avatar
ANUBITEK
Adept
Posts: 261
Joined: Sun Dec 28, 2014 1:10 am
Location: Anubitek

Nothing in particular

Post by ANUBITEK »

Asking anyone who wants to throw in, what are some advanced topics I can start getting into with UnrealScript? I have a general feel for how coding in this language works now, but I feel like I may be missing some information. Cross posted from OldUnreal, I'll leave answers where they lie. This thread is so I can improve my coding.

Code: Select all

//=============================================================================
// Test
//	Declare class and subclass, followed by modifiers below.
//=============================================================================
class Test extends Actor
	abstract;
	
/* #exec commands go here */
	
// () Allows for editable variables!
var() [modifiers] [insert variable type here] [variable tag here];
var int LannFyre;

// @Override
event prebeginplay()
{
	super.prebeginplay();
}

// @Override
event beginplay()
{
	super.beginplay();
}

// @Override
event postbeginplay()
{
	super.postbeginplay();
}

state BigBoy
{
	local [insert variable type here] [variable tag here];
	
Begin:
	log("Good god, we get it, you can code at a basic level now, gg" @ self.location)
	sleep(1.0);
	goto('Begin');
}

defaultproperties
{
	LannFyre=1
}
<<| http://uncodex.ut-files.com/ |>>

Code reference for UGold, UT99, Unreal2, UT2k3, UT3
Additional Beyond Unreal Wiki Links
wiki.beyondunreal.com/Legacy:Console_Bar
wiki.beyondunreal.com/Exec_commands#Load
wiki.beyondunreal.com/Legacy:Exec_Directive#Loading_Other_Packages
wiki.beyondunreal.com/Legacy:Config_Vars_And_.Ini_Files
wiki.beyondunreal.com/Legacy:INT_File
User avatar
sektor2111
Godlike
Posts: 6411
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Nothing in particular

Post by sektor2111 »

Okay I'm on it, listening and/or chatting. Gonna quote some of "my rules" taken from defaults
Mutator.uc said

Code: Select all

event PreBeginPlay()
{
	//Don't call Actor PreBeginPlay()
}
Actor.uc >> PostBeginPlay

Code: Select all

//
// Called immediately after gameplay begins.
//
event PostBeginPlay();

//
// Called after PostBeginPlay.
//
PostBeginPlay parent has nothing, makes no sense to call it
Always look in parent where you do "Super". See if has a meaning that call, else Override won't Override nothing.
What ever you want to spawn in Prebegin somewhere it has to be bGameRelevant or using a null PreBeginPlay() for preventing relevance check and destruction.
Actor.uc

Code: Select all

event PreBeginPlay()
{
	// Handle autodestruction if desired.
	if( !bGameRelevant && (Level.NetMode != NM_Client) && !Level.Game.IsRelevant(Self) )
		Destroy();
}
If this thing is called and conditions are accomplished, said sub-actor might go in destruction before starting to live.
That state. It might be automated triggered if is declared <Auto State Whatever> or if you write a line in (Pre)PostBeginPlay

Code: Select all

InitialState='Whatever';
or using <"> double quote I don't recall at this moment but you can go for a try. I prefer to delay things. Why ? Because if something goes wrong let other mutators to get the job faster or allow a string that can be screwed using state-name, for being changed if it needs to.
Just my thoughts...
User avatar
Barbie
Godlike
Posts: 2808
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Nothing in particular

Post by Barbie »

LannFyre wrote:

Code: Select all

class Test extends Actor abstract;
If you are new to object oriented programming I guess that you won't need abstract in the first years. It is useful if you want to concentrate several functions and properties for sub classed objects (at least two) where you don't want the parent object to be instantiated because final properties are missing.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
sektor2111
Godlike
Posts: 6411
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Nothing in particular

Post by sektor2111 »

I gotta admit that I was using abstracts... in none cases but in latest XCGE tweaks I was using them because that stuff is not for spawning or such, it is simple a kind of root like a virtual parent overriding real parent class with another things.
There I have rewritten by example function <SpawnRocks> if I well recall into an abstract Titan only for getting called from there and spawning Rocks with Net Code (rotating ones). For such a reason this mutator-tool has to be a package else rocks are going to be invisible.
For the rest I'm thinking to replace default function "ReplaceWith" but I'm not sure if I need that (my stuff already uses other one), else I would create a mutator abstract for that.
User avatar
ANUBITEK
Adept
Posts: 261
Joined: Sun Dec 28, 2014 1:10 am
Location: Anubitek

Re: Nothing in particular

Post by ANUBITEK »

The idea for Abstract in the test code was just to fill the modifier slot, same with all three functions calls though. The state was just to throw in a state for the hell of it. However I do use Abstract for a couple of my classes: my custom PlayerPawn, which presents either RPG_PlatformPawn or RPG_TestPawn. Those two classes abstract all the way down to whatever I want the player to play with, those classes just contains animation code.
<<| http://uncodex.ut-files.com/ |>>

Code reference for UGold, UT99, Unreal2, UT2k3, UT3
Additional Beyond Unreal Wiki Links
wiki.beyondunreal.com/Legacy:Console_Bar
wiki.beyondunreal.com/Exec_commands#Load
wiki.beyondunreal.com/Legacy:Exec_Directive#Loading_Other_Packages
wiki.beyondunreal.com/Legacy:Config_Vars_And_.Ini_Files
wiki.beyondunreal.com/Legacy:INT_File
User avatar
sektor2111
Godlike
Posts: 6411
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Nothing in particular

Post by sektor2111 »

Keep going here.
I think what I wanna say is matching Title. I don't want to keep some of my thoughts only for me. For some default matches which are not using heavy modifiers I think I'm gonna change default PlayerReplicationInfo just for testing and... new options that can be used (later about these).
I was looking over PlayerReplicationInfo and was interested to change timer code with state code for figuring effects. Let's say that timer is not interesting for me - also Bot it is included in stage with some useless checks removed.
Default PlayerReplicationInfo is root for Player's one and Bot's one. Yes root code has a timer updating location and checking Net info using a double PlayerPawn check (a single one has problems ?). Else I removed that random < 0.65 because I don't like this way.
Old code
PlayerReplicationInfo wrote:

Code: Select all

...
function PostBeginPlay()
{
	StartTime = Level.TimeSeconds;
	Timer();
	SetTimer(2.0, true);
	bIsFemale = Pawn(Owner).bIsFemale;
}
 					
function Timer()
{
	local float MinDist, Dist;
	local LocationID L;

	MinDist = 1000000;
	PlayerLocation = None;
	if ( PlayerZone != None )
		for ( L=PlayerZone.LocationID; L!=None; L=L.NextLocation )
		{
			Dist = VSize(Owner.Location - L.Location);
			if ( (Dist < L.Radius) && (Dist < MinDist) )
			{
				PlayerLocation = L;
				MinDist = Dist;
			}
		}
	if ( FRand() < 0.65 )
		return;

	if (PlayerPawn(Owner) != None)
		Ping = int(PlayerPawn(Owner).ConsoleCommand("GETPING"));
	if (PlayerPawn(Owner) != None)
		PacketLoss = int(PlayerPawn(Owner).ConsoleCommand("GETLOSS"));
}
I'm currently testing with no issues timer-free code of a sort of replication for "players".
E_PlayerReplicationInfo wrote:

Code: Select all

class E_PlayerReplicationInfo expands PlayerReplicationInfo;

var int TimeNet; //This is for interval net check related

function PostBeginPlay()
{
	StartTime = Level.TimeSeconds;
/*
Removed these friends of mine
	Timer();
	SetTimer(2.0, true);
*/
	if ( Pawn(Owner) != None ) //added a check because it doesn't hurt
		bIsFemale = Pawn(Owner).bIsFemale;
}

function Timeing() //A sort of timer
{
	local float MinDist, Dist;
	local LocationID L;

//	log (Self.Name@"working..."); //Tested
	MinDist = 1000000;
	PlayerLocation = None;
	if ( PlayerZone != None )
		for ( L=PlayerZone.LocationID; L!=None; L=L.NextLocation )
		{
			Dist = VSize(Owner.Location - L.Location);
			if ( (Dist < L.Radius) && (Dist < MinDist) )
			{
				PlayerLocation = L;
				MinDist = Dist;
			}
		}

	TimeNet++;
	if ( TimeNet < 2 ) //It's not time to get ping ?
		GoTo NoThingToDo;
	else
	{
		if (PlayerPawn(Owner) != None) //A Single check for 2 things
		{
			Ping = int(PlayerPawn(Owner).ConsoleCommand("GETPING"));
			PacketLoss = int(PlayerPawn(Owner).ConsoleCommand("GETLOSS"));
		}
	TimeNet = 0; //And reset
	}
NothingToDo: //Nothing bellow this label
}

Auto State TickingTime
{
Begin:
	Sleep(0.00);
Looping:
	if ( Pawn(Owner) == None ) //Self guard
		GoTo ('End');
	Timeing();
	Sleep(1.99); //little fun
	GoTo ('Looping'); //repeat - like timer
End:
	Destroy(); //Destroy internally if it needs to
}
The Bot Has a similar one but without checking any PlayerPawn(Owner) because doesn't make sense. I'm gonna quit timers as long as in a doc I was reading that Unreal Engine can guide even 100 Actors each of them being in a state, else I did not see anywhere a doc recommending 100 Mutators with Timer, after figuring some random rare issues at this problem I will keep removing timers letting "State Machine" to take place.

What else it's doable ? Let's say if that if we have laggers we can get rid of them right here - no other mutators loaded. If we have nasty people also we can do checks here and removing them.

Implementation ? I think this is an answer due to chronology of executions:
NsUTw - Mutator wrote:

Code: Select all

...
function bool AlwaysKeep(Actor Other)
{
	if ( PlayerPawn(Other) != None )
	{
		PlayerPawn(Other).PlayerReplicationInfoClass = class'E_PlayerReplicationInfo';
		return True;
	}
	if ( Bot(Other) != None )
	{
		Bot(Other).PlayerReplicationInfoClass = class'E_BotReplicationInfo';
		return True;
	}

	if ( NextMutator != None )
		return ( NextMutator.AlwaysKeep(Other) );
	return false;
}
...
Technically we need Pawn spawned and quickly hook before to execute any code. By doing other way you might not see logs as expected because it doesn't work else "LOGS ARE ALWAYS SHOWN" if code has a logic of timing.
Also we might insert Country, Host, bIsJerk, etc. Even we might have some INI with a small database... eh.
Post Reply