Page 1 of 1

Useful Functions

PostPosted: Sat Apr 07, 07 8:50 am
by Alex
Ever created or found useful UnrealScript functions? (So stand-alone functions!) Post them here, so others can use them aswell!

PostPosted: Sat Apr 07, 07 9:27 am
by Alex
Ok, I created a function, just for this topic. I only just finished it, but I tested it, and it should work just fine.

I remade this function:
http://nl2.php.net/manual/en/function.substr.php

I also used the examples of that page to test my function.

Code: Select all
static final function string substr(coerce string string, coerce int start , optional coerce int length)
{
  local string    tmpString;
  local int   tmpInt;

  if(start >= 0)
    tmpInt = len(string)-start;
  else
    tmpInt = start*-1;

  tmpString = right(string, tmpInt);

  if(length > 0)
    tmpString = left(tmpString, length);
  else if(length < 0)
    tmpString = left(tmpString, len(tmpString)+length);

  return tmpString;
}


If you want to test out the function:
Code: Select all
//================================================================================
// SubStr. Made by Alex ~ http://www.dxalpha.com/
//================================================================================
class SubStr extends Actor;

function PostBeginPlay()
{
  local string testString;
  Super.PostBeginPlay();
  testString = "abcdef";
  log(substr(testString, 1));     // bcdef
  log(substr(testString, 1, 3));  // bcd
  log(substr(testString, 0, 4));  // abcd
  log(substr(testString, 0, 8));  // abcdef
  log(substr(testString, -1, 1)); // f
  log(substr(testString, -1));    // f
  log(substr(testString, -2));    // ef
  log(substr(testString, -3, 1)); // d
  log(substr(testString, 0, -1));  // abcde
  log(substr(testString, 2, -1));  // cde
  log(substr(testString, 4, -4));  // empty
  log(substr(testString, -3, -1)); // de
}

static final function string substr(coerce string string, coerce int start , optional coerce int length)
{
  local string    tmpString;
  local int   tmpInt;

  if(start >= 0)
    tmpInt = len(string)-start;
  else
    tmpInt = start*-1;

  tmpString = right(string, tmpInt);

  if(length > 0)
    tmpString = left(tmpString, length);
  else if(length < 0)
    tmpString = left(tmpString, len(tmpString)+length);

  return tmpString;
}

defaultproperties
{
  bHidden=true
}


Just compile that actor, and add it to your ServerActors.
It will log the results in your server-console as soon as you start your server :)
Any questions? Go ahead & ask. For the use of this function or other explanation:
http://nl2.php.net/manual/en/function.substr.php

PostPosted: Sat Apr 07, 07 9:49 am
by MainMan
Wow, looks nice...


A function that exists in the DeusEx version of Object.uc, but not many people know about (as it is unique to DX)

Code: Select all
native static final function string GetConfig( string ConfigSection, string ConfigKey);  // DEUS_EX CAC

Yes, it natively, dynamically retrieves information from the DeusEx.ini file. Normally, config files can only be written to, but when you "read" them, you are in fact just reading from the class (which has loaded the config file once during the server launch). This function actually enables you to read from the file. Nice.

An example of use would be:

Code: Select all
str = "TestArray["$testIndex$"]";
return Class'IniTest'.Static.GetConfig("PackageName.IniTest", str);


Where "PackageName.IniTest" is the header in the .ini file, and TestArray is the variable.

E.g. the ini file would be like:
Code: Select all
[PackageName.IniTest]
TestArray[1]=aaa
TestArray[2]=qqq
TestArray[3]=ggggg
TestArray[4]=fff
TestArray[5]=ccc


So if you were to enter testIndex as 4 on the example above, it would return "fff" in that code.


The only disadvantage is, that it can only read from the DeusEx.ini package, and not any others - so your info must be in there.

PostPosted: Sat Apr 07, 07 9:54 am
by Alex
I made the following function a while ago. I thought it returns the amount of occurances of a certain string in an other string.

Code: Select all
static final function int strfind(coerce string Haystack, coerce string Needle)
{
  local int StringIndex;

  while(instr(Haystack,Needle) != -1)
  {
    Haystack = Right(Haystack,(Len(Haystack)-instr(Haystack,Needle))-1);
    StringIndex++;
  }
  return StringIndex;
}


So it would be like:
Code: Select all
someInt = strfind("applepie", "p");

That would return 3. Not sure though, will test it some other time today.

It returns an int, so don't try to place it into a string ;)

PostPosted: Fri May 25, 07 5:43 pm
by Alex
If you want functions that are in other language's, such as JavaScript or PHP or whatsoever and they are not in UnrealScript: Just post here. I can hopefully/probably write them in UC format.

PostPosted: Wed Jan 09, 08 5:46 am
by Batchy
Does UScript have a function like strlen?

If not, Could you whip one up :D

PostPosted: Wed Jan 09, 08 10:46 am
by Dae
Batchy wrote:Does UScript have a function like strlen?

len("batch"); would return 5 :)

PostPosted: Thu Jan 10, 08 5:39 am
by Batchy
Ahh ok, I should of gone through his code more thoroughly and i would of seen it xD

Re: Useful Functions

PostPosted: Mon Sep 22, 14 7:10 pm
by han
Set/GetPropertyText() are quite handy for ducktype copying variables especially enums, which would require checks for each case. e.g.
Code: Select all
ReplacementInv.SetPropertyText("SkinColor", OtherInv.GetPropertyText("SkinColor"));


Maybe a fixed TraceTexture() version is sth. you might like (a whole new feeling with right footstep sounds).
Code: Select all
// Find the FBspNode for Point.
INT FindNode( UModel* Model, INT iPlane, FVector Point )
{
   guard(FindNode);
   check(Model);

   INT Index = iPlane;

   while ( Index != INDEX_NONE )
   {
      FBspNode& Node = Model->Nodes(Index);

      if ( Node.iSurf != INDEX_NONE )
      {
         FBspSurf& Surf = Model->Surfs(Node.iSurf);

         //debugf( TEXT("FindNode: Testing: FBspNode(%i) with FBspSurf(%i).Texture %s."), Index, Node.iSurf, Surf.Texture ? Surf.Texture->GetName() : TEXT("None") );

         UBOOL Valid = 1;
         FLOAT OldPlaneDot = 0.0f;

         // Check for NumVertices == 0
         if ( Node.NumVertices )
         {
            for ( INT i = 0; i < Node.NumVertices && Valid; i++ )
            {
               // Get Points.
               FVector& A = Model->Points(Model->Verts(Node.iVertPool + i).pVertex);
               FVector& B = Model->Points(Model->Verts(Node.iVertPool + ((i+1) % Node.NumVertices)).pVertex);

               // Now build a plane.
               FPlane Plane( A, (B-A)^FVector( Node.Plane.X, Node.Plane.Y, Node.Plane.Z ) );

               // Now check Point against this plane.
               FLOAT PlaneDot = Plane.PlaneDot( Point );
               
                  // Sign changed, check next FBspNode.
               if ( OldPlaneDot * PlaneDot < 0.0f )
               {
                  Valid = 0;
               }
               // Sign stayed the same, everything fine.
               else
               {
                  OldPlaneDot = PlaneDot;
               }
            }

            // Passed check.
            if ( Valid )
            {
               //debugf( TEXT("FindNode: Passed.") );
               return Index;
            }
            //else
            //{
               //debugf( TEXT("FindNode: Failed.") );               
            //}
         }
         //else
         //{
            //debugf( TEXT("FindNode: Skipping: Node.NumVertices == 0.") );
         //}
      }
      //else
      //{
         //debugf( TEXT("FindNode: Skipping: Node.iSurf == INDEX_NONE.") );
      //}

      Index = Node.iPlane;
   }
   
   return INDEX_NONE;
   unguard;
}

//native(3220) final iterator function TraceTextureHan( class<Actor> BaseClass, out actor Actor, out name TexName, out name TexGroup, out int Flags, out vector HitLoc, out vector HitNorm, vector End, optional vector Start, optional vector Extent )
void AHXPlayerPawn::execTraceTextureHan(FFrame& Stack, RESULT_DECL)
{
   guard(AHXPlayerPawn::execTraceTextureHan);
   
   P_GET_OBJECT( UClass, BaseClass );
   P_GET_OBJECT_REF( AActor, Actor );
   P_GET_NAME_REF( TexName );
   P_GET_NAME_REF( TexGroup );
   P_GET_INT_REF( Flags );
   P_GET_VECTOR_REF( HitLoc );
   P_GET_VECTOR_REF( HitNorm );
   P_GET_VECTOR( End );
   P_GET_VECTOR_OPTX( Start, Location );
   P_GET_VECTOR_OPTX( Extent, FVector( 0.0f, 0.0f, 0.0f ) );
   P_FINISH;

   FMemMark MemMark( GMem );

   if ( !BaseClass )
      BaseClass = AActor::StaticClass();

   FCheckResult* Res = XLevel->MultiLineCheck( GMem, End, Start, Extent, 1, Level, 0 );

   PRE_ITERATOR

      if ( Res )
      {
         *Actor      = Res->Actor;
         *HitLoc      = Res->Location;
         *HitNorm   = Res->Normal;

         *TexName   = NAME_None;
         *TexGroup   = NAME_None;
         *Flags      = 0;

         if ( Res->Actor == Level )
         {
            Res->Item = FindNode( XLevel->Model, Res->Item, Res->Location );

            if ( Res->Item != INDEX_NONE )
            {
               FBspNode& Node = XLevel->Model->Nodes(Res->Item);

               if ( Node.iSurf != INDEX_NONE )
               {
                  FBspSurf& Surf = XLevel->Model->Surfs(Node.iSurf);

                  if ( Surf.Texture )
                  {
                     *TexName   = Surf.Texture->GetFName();

                     if ( Surf.Texture->GetOuter() )
                     {
                        *TexGroup   = Surf.Texture->GetOuter()->GetFName();
                     }
                  }

                  *Flags = Surf.PolyFlags;
               }
            }
         }

         Res = (FCheckResult *)Res->Next;
      }
      else
      {
         Stack.Code = &Stack.Node->Script( wEndOffset + 1 );

         *Actor = NULL;
         break;
      }

   POST_ITERATOR

   MemMark.Pop();

   unguardexec;
}

Problem of old DX TraceTexture() was that that Surf.Texture's properties were used.
Code: Select all
FBspNode& Node = XLevel->Model->Nodes(Res->Item);
FBspSurf& Surf = XLevel->Model->Surfs(Node.iSurf);

Although Res->Item an index to the first coplanar FBspNode (linked over FBspNode.iPlane), so the clipping stuf was missing to find the correct FBspNode.

Re: Useful Functions

PostPosted: Tue Sep 23, 14 10:11 pm
by Allan
han wrote:Maybe a fixed TraceTexture() version is sth. you might like (a whole new feeling with right footstep sounds).
Code: Select all
// Find the FBspNode for Point.
INT FindNode( UModel* Model, INT iPlane, FVector Point )
{
   guard(FindNode);
   check(Model);

   INT Index = iPlane;

   while ( Index != INDEX_NONE )
   {
      FBspNode& Node = Model->Nodes(Index);

      if ( Node.iSurf != INDEX_NONE )
      {
         FBspSurf& Surf = Model->Surfs(Node.iSurf);

         //debugf( TEXT("FindNode: Testing: FBspNode(%i) with FBspSurf(%i).Texture %s."), Index, Node.iSurf, Surf.Texture ? Surf.Texture->GetName() : TEXT("None") );

         UBOOL Valid = 1;
         FLOAT OldPlaneDot = 0.0f;

         // Check for NumVertices == 0
         if ( Node.NumVertices )
         {
            for ( INT i = 0; i < Node.NumVertices && Valid; i++ )
            {
               // Get Points.
               FVector& A = Model->Points(Model->Verts(Node.iVertPool + i).pVertex);
               FVector& B = Model->Points(Model->Verts(Node.iVertPool + ((i+1) % Node.NumVertices)).pVertex);

               // Now build a plane.
               FPlane Plane( A, (B-A)^FVector( Node.Plane.X, Node.Plane.Y, Node.Plane.Z ) );

               // Now check Point against this plane.
               FLOAT PlaneDot = Plane.PlaneDot( Point );
               
                  // Sign changed, check next FBspNode.
               if ( OldPlaneDot * PlaneDot < 0.0f )
               {
                  Valid = 0;
               }
               // Sign stayed the same, everything fine.
               else
               {
                  OldPlaneDot = PlaneDot;
               }
            }

            // Passed check.
            if ( Valid )
            {
               //debugf( TEXT("FindNode: Passed.") );
               return Index;
            }
            //else
            //{
               //debugf( TEXT("FindNode: Failed.") );               
            //}
         }
         //else
         //{
            //debugf( TEXT("FindNode: Skipping: Node.NumVertices == 0.") );
         //}
      }
      //else
      //{
         //debugf( TEXT("FindNode: Skipping: Node.iSurf == INDEX_NONE.") );
      //}

      Index = Node.iPlane;
   }
   
   return INDEX_NONE;
   unguard;
}

//native(3220) final iterator function TraceTextureHan( class<Actor> BaseClass, out actor Actor, out name TexName, out name TexGroup, out int Flags, out vector HitLoc, out vector HitNorm, vector End, optional vector Start, optional vector Extent )
void AHXPlayerPawn::execTraceTextureHan(FFrame& Stack, RESULT_DECL)
{
   guard(AHXPlayerPawn::execTraceTextureHan);
   
   P_GET_OBJECT( UClass, BaseClass );
   P_GET_OBJECT_REF( AActor, Actor );
   P_GET_NAME_REF( TexName );
   P_GET_NAME_REF( TexGroup );
   P_GET_INT_REF( Flags );
   P_GET_VECTOR_REF( HitLoc );
   P_GET_VECTOR_REF( HitNorm );
   P_GET_VECTOR( End );
   P_GET_VECTOR_OPTX( Start, Location );
   P_GET_VECTOR_OPTX( Extent, FVector( 0.0f, 0.0f, 0.0f ) );
   P_FINISH;

   FMemMark MemMark( GMem );

   if ( !BaseClass )
      BaseClass = AActor::StaticClass();

   FCheckResult* Res = XLevel->MultiLineCheck( GMem, End, Start, Extent, 1, Level, 0 );

   PRE_ITERATOR

      if ( Res )
      {
         *Actor      = Res->Actor;
         *HitLoc      = Res->Location;
         *HitNorm   = Res->Normal;

         *TexName   = NAME_None;
         *TexGroup   = NAME_None;
         *Flags      = 0;

         if ( Res->Actor == Level )
         {
            Res->Item = FindNode( XLevel->Model, Res->Item, Res->Location );

            if ( Res->Item != INDEX_NONE )
            {
               FBspNode& Node = XLevel->Model->Nodes(Res->Item);

               if ( Node.iSurf != INDEX_NONE )
               {
                  FBspSurf& Surf = XLevel->Model->Surfs(Node.iSurf);

                  if ( Surf.Texture )
                  {
                     *TexName   = Surf.Texture->GetFName();

                     if ( Surf.Texture->GetOuter() )
                     {
                        *TexGroup   = Surf.Texture->GetOuter()->GetFName();
                     }
                  }

                  *Flags = Surf.PolyFlags;
               }
            }
         }

         Res = (FCheckResult *)Res->Next;
      }
      else
      {
         Stack.Code = &Stack.Node->Script( wEndOffset + 1 );

         *Actor = NULL;
         break;
      }

   POST_ITERATOR

   MemMark.Pop();

   unguardexec;
}


Got to admit, this would be a lot of use to me to find out if this would help my fireballs grab the correct textures to set on fire, and tracehits get the right textures to apply the right decals to. Does this require any additional DLLs or can I just dump this verbatim into a .uc?

I'm sounding all nub because outside of UScript, I'm a bit of a coding dunce. xD

Re: Useful Functions

PostPosted: Tue Sep 23, 14 10:37 pm
by han
You need to put it in your own dll. Didn't see the uc functions in the first post. XD
However, i put a package together with some stuff ripped out of my main project and slightly modified it, although the package is untested, it has a static version of the modified TraceTexture in it, so it could be called from somewhere else (Documentation is in the *.uc file).
Coolbits-20140923.zip
(30.51 KiB) Downloaded 668 times