Accessing an Actor without a loop

Discussions about Coding and Scripting
User avatar
Barbie
Godlike
Posts: 1716
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Accessing an Actor without a loop

Post by Barbie » Thu Dec 24, 2015 11:31 pm

The time I was implementing the map specific fixes I thought: "What a mess - data embedding in code. A mutator is needed for this." That kind of coding reminds me to the early days of PHP :barf:
If I find the time I'll convert this into a mutator; also I have made first thoughts of the corresponding INI file:

Code: Select all

[MH-TheBorder]
FixCTFFlags=true

[MH-TowerOfdeath2]
FixCreatureFactories=true

[MH-HTD+Experimental-Facilty]
spawn=spawn1

[spawn1]
class=SuperShockRifle
Location=5360, 12480, -240
RespawnTime = 1

[MH-Infiltrationv2]
logging=true
SetActorProperty=CreatureFactory0,capacity,"12"
SetActorProperty=CreatureFactory0,bFalling,"false"
...

[MH-Salmagundi]
PlayerWeapons=BotPack.SniperRifle,(random)

[MH-LandsOfNapali\x5BEG\x5D]
Comment="Example of a map with illegal chars in name: 'MH-LandsOfNapali[EG]'"

[MH-UnderwaterAssaultV2]
MonsterSkill=0
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett

Higor
Godlike
Posts: 1769
Joined: Sun Mar 04, 2012 6:47 pm

Re: Accessing an Actor without a loop

Post by Higor » Fri Dec 25, 2015 1:59 am

Chris wrote:
Wormbo wrote: Or just use Outer.Name directly to skip the string conversion altogether.
Correct me if I'm wrong, but since the Outer.Name is an FName type, wouldn't it eventually have to do the same conversion as string(outer) as soon as it's treated as a string?
As far as I know the string(outer) in turn just converts the Outer->GetFName() to an FString.
As long as the Outer.Name is treated as a Name type it would make sense.
Nope, he is correct.
UnrealScript serializes names as NameTable+NameID, the string operation occurs during package loading and once done the FName is hashed with the other FNames, FName as used in native code is an 32 bit signed integer type, basically, an index to the general name table. So... when in code you do:

Code: Select all

Outer.Name == 'ThisLevel'
You get these opcodes:

Code: Select all

EqualEqual_NameName (opcode 252)
EX_Context (opcode 0x19)... 0x00... UProperty(Outer) ref... skip to if fail (word)
0x00... UProperty(Name) ref
EX_NameConst (opcode 0x21)... FName index (INT)
... EX_EndFunctionParams doesn't get compiled for operators, only for functions (0x16)
Yes, checking names is faster on unrealscript at execution time, but should be used sparingly.
You don't want a single package creating a million names for one-time-checks, strings should be used there to avoid populating the name hash for no reason.
ImageImage
Image unreal://23.111.157.138:7777
Image unreal://46.228.199.205:7788

JackGriffin
Godlike
Posts: 3766
Joined: Fri Jan 14, 2011 1:53 pm
Personal rank: -Retired-

Re: Accessing an Actor without a loop

Post by JackGriffin » Fri Dec 25, 2015 5:16 am

@Barbie:
I can't find my code for the teleporter fix. You can make your own though using this bit of code. It comes from the Andromeda MH maps. For some reason teleporters will cause the remaining players in an MH server to crash if you try to use them. Instead send players to other places using a trigger like so:

Code: Select all

//=============================================================================
// andromhend.
//=============================================================================
class andromhend expands Trigger;

var () string MapName;  //Map to travel the server to

function Touch( actor Other )
{
	local actor A;
	if( IsRelevant( Other ) )
	{
		if ( ReTriggerDelay > 0 )
		{
			if ( Level.TimeSeconds - TriggerTime < ReTriggerDelay )
				return;
			TriggerTime = Level.TimeSeconds;
		}

		if( Event != '' )
			foreach AllActors( class 'Actor', A, Event )
				A.Trigger( Other, Other.Instigator );

		if ( Other.IsA('Pawn') && (Pawn(Other).SpecialGoal == self) )
			Pawn(Other).SpecialGoal = None;

		if( Message != "" )
			Other.Instigator.ClientMessage( Message );

		TriggerObjective();

		if( bTriggerOnceOnly )
			SetCollision(False);
		else if ( RepeatTriggerTime > 0 )
			SetTimer(RepeatTriggerTime, false);
	}
}

function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, 
						Vector momentum, name damageType)
{
	local actor A;

	if ( bInitiallyActive && (TriggerType == TT_Shoot) && (Damage >= DamageThreshold) && (instigatedBy != None) )
	{
		if ( ReTriggerDelay > 0 )
		{
			if ( Level.TimeSeconds - TriggerTime < ReTriggerDelay )
				return;
			TriggerTime = Level.TimeSeconds;
		}

		if( Event != '' )
			foreach AllActors( class 'Actor', A, Event )
				A.Trigger( instigatedBy, instigatedBy );

		if( Message != "" )
			instigatedBy.Instigator.ClientMessage( Message );

		if( bTriggerOnceOnly )
			SetCollision(False);

		TriggerObjective();
	
	}
}

function TriggerObjective()
{
	/*if (Level.Game.IsA('MonsterHunt'))
		Level.Game.EndGame("Hunt Successfull!");*/
		Level.ServerTravel( MapName, false);
}

defaultproperties
{
}
So long, and thanks for all the fish

User avatar
sektor2111
Godlike
Posts: 4116
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Accessing an Actor without a loop

Post by sektor2111 » Fri Dec 25, 2015 7:42 am

Barbie wrote:The time I was implementing the map specific fixes I thought: "What a mess - data embedding in code. A mutator is needed for this." That kind of coding reminds me to the early days of PHP :barf:
If I find the time I'll convert this into a mutator; also I have made first thoughts of the corresponding INI file:

Code: Select all

[MH-TheBorder]
FixCTFFlags=true

[MH-TowerOfdeath2]
FixCreatureFactories=true

[MH-HTD+Experimental-Facilty]
spawn=spawn1

[spawn1]
class=SuperShockRifle
Location=5360, 12480, -240
RespawnTime = 1

[MH-Infiltrationv2]
logging=true
SetActorProperty=CreatureFactory0,capacity,"12"
SetActorProperty=CreatureFactory0,bFalling,"false"
...

[MH-Salmagundi]
PlayerWeapons=BotPack.SniperRifle,(random)

[MH-LandsOfNapali\x5BEG\x5D]
Comment="Example of a map with illegal chars in name: 'MH-LandsOfNapali[EG]'"

[MH-UnderwaterAssaultV2]
MonsterSkill=0
Wheew, Jessus and you wanna build a list with all particular fixes ?

As for No fix Via UScript - LandOfNapali needs a pathing revision + adding paths in empty areas + fixing that Super-Duper-Flak. Pathing injection for this case somehow is doable by Botz mutator... which I would like to see extended in options.

User avatar
Barbie
Godlike
Posts: 1716
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Accessing an Actor without a loop

Post by Barbie » Fri Dec 25, 2015 3:05 pm

sektor2111 wrote:Wheew, Jessus and you wanna build a list with all particular fixes ?
From the view of what comes out in the end it does not make a difference whether I do this in code or in a Mutators INI file (for the maps I host). If other server maintainer want to apply patches to maps they could do that then without touching the code - just installing that Mutator and then changing the INI only.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett

User avatar
Barbie
Godlike
Posts: 1716
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Accessing an Actor without a loop

Post by Barbie » Fri Dec 25, 2015 3:20 pm

JackGriffin wrote:I can't find my code for the teleporter fix.
Thanks for investigation, but I'm afraid you misunderstood my intention: I just want to get rid of these travelling Teleporters and put a MonsterEnd there instead. So spawning a MHEnd at that location and disabling Teleporters "Touch" should do that work. (Although my code sets also Teleporters URL to an empty string and its collision flags to (False, False, False). Just to make things sure :lol: )
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett

Post Reply