Advertisement
Treedestroyed

Untitled

Nov 12th, 2020
2,256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. private function bool ParseSquadElement( const out String ElemDef, out AISquadElement SquadElement )
  2. {
  3.     local int i, ElemStrLen, UnicodePoint, ElemCount, ModifierCharIndex;
  4.     local string ElemType, MaybeModifierChar;
  5.     local array<string> CustomElemType;
  6.     local bool IsSpecial, IsRagedOnSpawn;
  7.     local class<KFPawn_Monster> CustomElem${1}< ${3} >
  8.     local ECDZedNameResolv ZedNameResolv;
  9.    
  10.     IsSpecial = false;
  11.     IsRagedOnSpawn = false;
  12.     ElemStrLen = Len( ElemDef );
  13.  
  14.     if ( 0 == ElemStrLen )
  15.     {
  16.         return PrintElemParseError("Spawn elements must not be empty.");
  17.     }
  18.  
  19.     // Locate the first index into ElemDef where the count
  20.     // of zeds in the element ends and the type of zed should begin
  21.     for ( i = 0; i < ElemStrLen; i++ )
  22.     {
  23.         // Get unicode codepoint (as int) for char at index i
  24.         UnicodePoint = Asc( Mid( ElemDef, i, 1 ) );
  25.  
  26.         // Check for low ascii numerals [0-9]
  27.         if ( !( 48 <= UnicodePoint && UnicodePoint <= 57 ) )
  28.         {
  29.             break; // not a numeral
  30.         }
  31.     }
  32.  
  33.     // The index must not be at the very beginning or end of the string.
  34.     // If that's true, then we can assume it was malformed.
  35.     if ( i <= 0 || i >= ElemStrLen )
  36.     {
  37.         return PrintElemParseError("Spawn element \""$ ElemDef $"\" could not be parsed.");
  38.     }
  39.  
  40.     // Check whether the element string ends with a *.  The
  41.     // asterisk suffix denotes special/albino zeds.  It is only
  42.     // valid on crawlers and alphas (when this comment was written,
  43.     // at least).  We will have to check that constraint later so
  44.     // that we correctly reject requests for nonexistent specials,
  45.     // e.g. albino scrake.
  46.     for ( ModifierCharIndex = ElemStrLen - 1; 0 <= ModifierCharIndex; ModifierCharIndex-- )
  47.     {
  48.         MaybeModifierChar = Mid( ElemDef, ModifierCharIndex, 1 );
  49.  
  50.         if ( "*" == MaybeModifierChar )
  51.         {
  52.             IsSpecial = true;
  53.  
  54.             // Check that the zed name is not empty
  55.             if ( ModifierCharIndex <= i )
  56.             {
  57.                 return PrintElemParseError("Spawn element \""$ ElemDef $"\" could not be parsed.");
  58.             }
  59.  
  60.             continue;
  61.         }
  62.  
  63.         if ( "!" == MaybeModifierChar )
  64.         {
  65.             IsRagedOnSpawn = true;
  66.  
  67.             // Check that the zed name is not empty
  68.             if ( ModifierCharIndex <= i )
  69.             {
  70.                 return PrintElemParseError("Spawn element \""$ ElemDef $"\" could not be parsed.");
  71.             }
  72.  
  73.             continue;
  74.         }
  75.  
  76.         // This char did not match any known modifiers chars.  We've started cutting into the zed name.
  77.         break;
  78.     }
  79.  
  80.     // Cut string into two parts.
  81.     //
  82.     // Left is the count as a stringified int.  We know it is a
  83.     // parseable int because of the preceding unicode check loop.
  84.     //
  85.     // Right is possibly the name of a zed as a string, but it is
  86.     // totally unverified at this stage.  We exclude the * suffix
  87.     // (if it was detected above).
  88.     ElemCount = int( Mid( ElemDef, 0, i ) );
  89.     ElemType  = Mid( ElemDef, i, ElemStrLen - i - ( IsSpecial ? 1 : 0 ) - ( IsRagedOnSpawn ? 1 : 0 ) );
  90.  
  91.     SquadElement.Num = ElemCount;
  92.  
  93.     // Check value range for ElemCount
  94.     if ( ElemCount < MinZedsInElement )
  95.     {
  96.         return PrintElemParseError("Element count "$ ElemCount $" is not positive.  "$
  97.                    "Must be between "$ MinZedsInElement $" to "$ MaxZedsInElement $" (inclusive).");
  98.     }
  99.     if ( ElemCount > MaxZedsInElement )
  100.     {
  101.         return PrintElemParseError("Element count "$ ElemCount $" is too large.  "$
  102.                    "Must be between "$ MinZedsInElement $" to "$ MaxZedsInElement $" (inclusive).");
  103.     }
  104.  
  105.     // Set custom element
  106.     for ( i = 0; i < ExternalCustomZed.Length; i++ )
  107.     {
  108.         CustomElemType.AddItem( ExternalCustomZed[i].ZedName );
  109.        
  110.         if ( ElemType ~= CustomElemType[i] )
  111.         {
  112.             CustomElemClass = class<KFPawn_Monster>( DynamicLoadObject( ExternalCustomZed[i].ZedClassPath, class'Class' ) );
  113.         }
  114.     }
  115.  
  116.     // Convert user-provided zed info into a EAIType enum and possibly custom class
  117.     ZedNameResolv = class'CD_ZedNameUtils'.static.GetZedType(
  118.         /* const input params */
  119.         ElemType, CustomElemType, IsSpecial, IsRagedOnSpawn,
  120.         /* mutable output params */
  121.         SquadElement.Type, SquadElement.CustomClass, CustomElemClass );
  122.  
  123.     // Was it a valid zed type name?
  124.     if ( ZedNameResolv == ZNR_INVALID_NAME )
  125.     {
  126.         return PrintElemParseError("\""$ ElemType $"\" does not appear to be a zed name."$
  127.                       "  Must be a zed name or abbreviation like cyst, fp, etc.");
  128.     }
  129.  
  130.     // If the ElemDef requested a special zed, then we need to
  131.     // check that the zed described by ElemType actually has a
  132.     // special/albino variant.
  133.     if ( ZedNameResolv == ZNR_INVALID_SPECIAL )
  134.     {
  135.         return PrintElemParseError("\""$ ElemType $"\" does not have a special variant."$
  136.               "  Remove the asterisk from \""$ ElemDef $"\" for a non-special equivalent.");
  137.     }
  138.  
  139.     if ( ZedNameResolv == ZNR_INVALID_RAGE )
  140.     {
  141.         return PrintElemParseError("\""$ ElemType $"\" does not have a raged-on-spawn variant."$
  142.               "  Remove the exclamation point from \""$ ElemDef $"\" for a non raged-on-spawn equivalent.");
  143.     }
  144.  
  145.     // Should have ZNR_OK == ZedNameResolve by process of elimination here,
  146.     // but check just in case we add a new ZNR enum entry and forget to
  147.     // update this function.
  148.     if ( ZedNameResolv != ZNR_OK )
  149.     {
  150.         return PrintElemParseError("\""$ ElemDef $"\" could not be parsed: " $ ZedNameResolv);
  151.     }
  152.    
  153.     return true;
  154. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement