Update pb-to-cpp.uc

Update pb-to-cpp.uc

Relational and logical operators.
Makes distinction between logical (short-circuit) and bitwise operators based on context.

# pb-to-cpp.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.0 on 12/23/2013 4:50:59 PM
# Comment: Converts PB source code to C++; modified by Daniel Corbier

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: Converts PB source code to C++; modified by Daniel Corbier
Selected: False
Highlight: True
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Find:
Replace: {@Define:
            Var: Array As String
            Var: ArrayNames As Table
            Var: CleanUp As String
         }

Criteria: 2
Comment: Processes some operators
Pass: 1

Criteria: 3
Comment: Bitwise AND and OR
Find: ({expr%})
Replace: ({@Eval: Replace(Replace(Replace("{expr}", "And", "&"), "Or", "|"), "=", "==")})

Criteria: 4
Comment: Logical (short-circuit) AND
Find: And
Replace: &&

Criteria: 5
Comment: Logical (short-circuit) OR
Find: Or
Replace: ||

Criteria: 6
Find: Xor
Replace: ^

Criteria: 7
Find: Not
Replace: ~

Criteria: 8
Find: IsFalse
Replace: !

Criteria: 9
Find: <>
Replace: !=

Criteria: 10
Find: =
Replace: ==

Criteria: 11
SkipOver: True
Find: { {nl}[%]|Then|Else|For|: } {var:" *[a-z\@\.]+"}[({index})] =
Replace: [Skip over]

Criteria: 12
Selected: True
SkipOver: True
Find: { #If | #ElseIf } Not
Replace: [Skip over]

Criteria: 13
Comment:
Pass: 2

Criteria: 14
SkipOver: True
Find: // {comment~}
Replace: [Skip over]

Criteria: 15
Find: ' {comment~}
Replace: // {comment}

Criteria: 16
BackColor: Green
PassOnce: False
Find: {nl}%{equate} = {value}
Replace: {nl}const int {equate} = {value};

Criteria: 17
BackColor: Green
Find: %{equate}
Replace: {equate}

Criteria: 18
BackColor: SandyBrown
Find: {"&h"}
Replace: 0x

Criteria: 19
BackColor: Green
PassOnce: False
Find: If {cond} Then {statement} [Else {else}]{nl}
Replace: if ({cond}) { {statement} }{else: else {{else}}}{nl}

Criteria: 20
PassOnce: False
Find: If {cond} Then {nl}
         {code+}
      End If
Replace: if ({cond}) {
            {code}
         }

Criteria: 21
BackColor: DarkKhaki
PassOnce: False
Find: Function {name} ([{args}]) As {type}{nl}
         {code+}
      End Function
Replace: {type} {name}({args}) {
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 22
PassOnce: False
Find: Sub {name} ([{args}]){nl}
         {code+}
      End Sub
Replace: void {name}({args}) {
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 23
PassOnce: False
Find: For {x} = {start} To {stop} [Step {inc=1}]{nl}
         {code+}
      Next
Replace: for ({x}={start}; {x}{@Eval: IIF(sgn({inc})>0, '<', '>')}={stop}; {x} += {inc}) {
            {code}
         }

Criteria: 24
PassOnce: False
Find: While {cond} {nl}
         {code+}
      Wend
Replace: while ({cond}) {
            {code}
         }

Criteria: 25
Find: !!ReleaseDynamicArrays!!
Replace: {@Eval:
            CleanUp = ""
            Array = ReadKey(ArrayNames, x)
            uc_For(x, 1, Count(ArrayNames), 1,
               CleanUp=CleanUp+"delete[] "+Array+";{nl}"
               Delete(ArrayNames, Array)
            )
            CleanUp
         }

Criteria: 26
BackColor: Orange
PassOnce: False
Find: { Dim | {member: {nl}}} {var:1} As {type} [{ptr: Ptr}]
Replace: {member: {nl}}{type} {ptr:*}{var};

Criteria: 27
PassOnce: False
Find: Dim {array}({subscript}) As {type}
Replace: {type} *{array} = new {type} [{subscript}+1];{@Eval:
            Insert(ArrayNames, "{array}")
         }{@Define:: Syntax: {array}({index}) ::= {array}[{index}]}

Criteria: 28
BackColor: SandyBrown
PassOnce: False
Find: Dim {var1}, {more}
Replace: Dim {var1}
         Dim {more}

Criteria: 29
BackColor: Gold
PassOnce: False
Find: { Local | Global | Register }
Replace: Dim

Criteria: 30
Find: @
Replace: *

Criteria: 31
BackColor: Silver
Find: VarPtr({var})
Replace: &{var}

Criteria: 32
BackColor: DeepSkyBlue
PassOnce: False
Find: Function = {value}
Replace: return {value};

Criteria: 33
BackColor: Lime
Find: Long
Replace: long

Criteria: 34
BackColor: Red
Find: Single
Replace: float

Criteria: 35
Find: Double
Replace: double

Criteria: 36
BackColor: SlateBlue
PassOnce: False
Find: ByRef {arg} As {type:1}
Replace: {type}& {arg}

Criteria: 37
BackColor: Pink
PassOnce: False
Find: ByVal {arg} As {type:1}
Replace: {type} {arg}

Criteria: 38
PassOnce: False
Find: Type {name:1}
         {members+}
      End Type
Replace: struct {name} {
            {members}
         }

Criteria: 39
Find: #If
Replace: #if

Criteria: 40
Find: #Else
Replace: #else

Criteria: 41
Find: #ElseIf
Replace: #elif

Criteria: 42
Find: #EndIf
Replace: #endif

Criteria: 43
PassOnce: False
Find: [{NOT: Not }] %Def({const})
Replace: {NOT:!}defined {const}

Criteria: 44
Comment: Adds semi-colons to statements
Pass: 3

Criteria: 45
SkipOver: True
Find: { "{" | "}" | ; | //{".*"} | #{".*"} } {nl} [{"[ \n]+"}]
Replace: [Skip over]

Criteria: 46
Find: :
Replace: ;

Criteria: 47
PassOnce: False
Find: {nl}
Replace: ;{nl}

# End Search

# convert.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.0 on 12/18/2013 2:36:02 PM
# Comment: Converts PB source code to C++; modified by Daniel Corbier

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: Converts PB source code to C++; modified by Daniel Corbier
Selected: False
Highlight: True
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Comment:
Pass: 1

Criteria: 2
Find:
Replace: {@Define:
            Var: Array As String
            Var: ArrayNames As Table
            Var: CleanUp As String
         }

Criteria: 3
SkipOver: True
Find: // {comment~}
Replace: [Skip over]

Criteria: 4
Find: ' {comment~}
Replace: // {comment}

Criteria: 5
BackColor: Green
PassOnce: False
Find: {nl}%{equate} = {value}
Replace: {nl}const int {equate} = {value};

Criteria: 6
BackColor: Green
Find: %{equate}
Replace: {equate}

Criteria: 7
BackColor: SandyBrown
Find: {"&h"}
Replace: 0x

Criteria: 8
BackColor: Green
PassOnce: False
Find: If {cond} Then {statement}{nl}
Replace: if ({cond}) { {statement} }{nl}

Criteria: 9
PassOnce: False
Find: If {cond} Then {nl}
         {code+}
      End If
Replace: if ({cond}) {
            {code}
         }

Criteria: 10
BackColor: DarkKhaki
PassOnce: False
Find: Function {name} ([{args}]) As {type}{nl}
         {code+}
      End Function
Replace: {type} {name}({args}) {
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 11
PassOnce: False
Find: Sub {name} ([{args}]){nl}
         {code+}
      End Sub
Replace: void {name}({args}) {
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 12
Selected: True
PassOnce: False
Find: For {x} = {start} To {stop} [Step {inc=1}]{nl}
         {code+}
      Next
Replace: for ({x}={start}; {x}{@Eval: IIF(sgn({inc})>0, '<', '>')}={stop}; {x} += {inc}) {
            {code}
         }

Criteria: 13
PassOnce: False
Find: While {cond} {nl}
         {code+}
      Wend
Replace: while ({cond}) {
            {code}
         }

Criteria: 14
Find: !!ReleaseDynamicArrays!!
Replace: {@Eval:
            CleanUp = ""
            Array = ReadKey(ArrayNames, x)
            uc_For(x, 1, Count(ArrayNames), 1,
               CleanUp=CleanUp+"delete[] "+Array+";{nl}"
               Delete(ArrayNames, Array)
            )
            CleanUp
         }

Criteria: 15
BackColor: Orange
PassOnce: False
Find: { Dim | {member: {nl}}} {var:1} As {type} [{ptr: Ptr}]
Replace: {member: {nl}}{type} {ptr:*}{var};

Criteria: 16
PassOnce: False
Find: Dim {array}({subscript}) As {type}
Replace: {type} *{array} = new {type} [{subscript}+1];{@Eval:
            Insert(ArrayNames, "{array}")
         }{@Define:: Syntax: {array}({index}) ::= {array}[{index}]}

Criteria: 17
BackColor: SandyBrown
PassOnce: False
Find: Dim {var1}, {more}
Replace: Dim {var1}
         Dim {more}

Criteria: 18
BackColor: Gold
PassOnce: False
Find: { Local | Global | Register }
Replace: Dim

Criteria: 19
Find: @
Replace: *

Criteria: 20
BackColor: Silver
Find: VarPtr({var})
Replace: &{var}

Criteria: 21
BackColor: DeepSkyBlue
PassOnce: False
Find: Function = {value}
Replace: return {value};

Criteria: 22
BackColor: Lime
Find: Long
Replace: long

Criteria: 23
BackColor: Red
Find: Single
Replace: float

Criteria: 24
Find: Double
Replace: double

Criteria: 25
BackColor: SlateBlue
PassOnce: False
Find: ByRef {arg} As {type:1}
Replace: {type}& {arg}

Criteria: 26
BackColor: Pink
PassOnce: False
Find: ByVal {arg} As {type:1}
Replace: {type} {arg}

Criteria: 27
PassOnce: False
Find: Type {name:1}
         {members+}
      End Type
Replace: struct {name} {
            {members}
         }

Criteria: 28
Find: #If
Replace: #if

Criteria: 29
Find: #Else
Replace: #else

Criteria: 30
Find: #ElseIf
Replace: #elif

Criteria: 31
Find: #EndIf
Replace: #endif

Criteria: 32
PassOnce: False
Find: [{NOT: Not }] %Def({const})
Replace: {NOT:!}defined {const}

Criteria: 33
Comment: Adds semi-colons to statements
Pass: 2

Criteria: 34
SkipOver: True
Find: { "{" | "}" | ; | //{".*"} | #{".*"} } {nl} [{"[ \n]+"}]
Replace: [Skip over]

Criteria: 35
Find: :
Replace: ;

Criteria: 36
PassOnce: False
Find: {nl}
Replace: ;{nl}

# End Search


Create print.uc

Create print.uc

Handles PRINT (cout)

# print.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.95 on 4/8/2014 6:29:17 PM
# Comment:

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, InputFile, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique, FilterTally

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: False
Exclude: False
Comment:
Selected: False
Highlight: False
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
FilterTally: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
InputFile:
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Enabled: True
Highlight: True
BackColor: Yellow
Find:
Replace: {@Token:: : ~~ Properties: ucStatementSep }

Criteria: 2
Comment:
Pass: 1

Criteria: 3
Enabled: True
BackColor: Purple
Find: Print
Replace: cout <<

Criteria: 4
Comment: Add ENDL to lines that need it
Pass: 2

Criteria: 5
Enabled: True
Highlight: True
BackColor: DarkKhaki
Find: cout << [{data}]
Replace: cout << {data} << endl

Criteria: 6
Enabled: True
Highlight: True
BackColor: DeepSkyBlue
Find: cout << [{data}] {punc: ; | , }{end: {nl} | : }
Replace: cout << {data} {punc}{end}

Criteria: 7
Comment:
Pass: 3

Criteria: 8
Enabled: True
Highlight: True
BackColor: Lime
PassOnce: False
Find: cout << {data}, [{more}]
Replace: cout << PZONE << {data}{more: : cout << {more}}

Criteria: 9
Enabled: True
Selected: True
BackColor: SlateBlue
PassOnce: False
Find: cout << {data}; [{more}]
Replace: cout << {data}{more: : cout << {more}}

Criteria: 10
Comment: Clean up
Pass: 4

Criteria: 11
Enabled: True
Highlight: True
BackColor: RoyalBlue
PassOnce: False
Find: << <<
Replace: <<

Criteria: 12
Enabled: True
BackColor: SlateBlue
PassOnce: False
Find: cout << {data} : cout <<
Replace: cout << {data} <<

# End Search

error: pathspec 'convert/print.uc' did not match any file(s) known to git


Update precompile.uc

Update precompile.uc

# precompile.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.96 on 6/4/2014 5:07:40 PM
# Comment: Inserts include files, handles directives, expands macros etc

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, InputFile, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique, FilterTally

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: Inserts include files, handles directives, expands macros etc
Selected: False
Highlight: False
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: False
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
FilterTally: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
InputFile:
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
PassOnce: False
Find: {@Note:
         This file is still under construction.
         It does not work just yet.
      }
Replace: {@Define:
            Syntax: { % | & | ? } ::= {Nothing}
            Syntax: Def([%]{equate}) ::= (Index(Equates, "{equate}") <> 0)
            Syntax: &{base:"[hbo]"} ::= #{base}
            Var: Equates As Table
            Var: MetaIF = True
            Var: NestedIF As Stack
            Var: IsInclude
         }
         {@Define:: Token: _.*\n ~~ Properties: ucWhiteSpace}

Criteria: 2
Comment:
Pass: 1

Criteria: 3
Selected: True
PassOnce: False
Find: {@Start}
Replace: ' These equates may need to be adjusted manually
         ' depending on the compiler version used
         %PB_REVISION = &H501
         %PB_REVLETTER = &H20
         %PB_EXE = -1
         %PB_CC32 = -1
         %PB_DLL32 = 0
         %PB_WIN32 = 0
         %USEMACROS = -1

Criteria: 4
BackColor: Purple
Find: { [{nl}]{comment:"'.*"} | {"_[^\n]*\n"} }
      {@If: IsInclude}
Replace: {Nothing}

Criteria: 5
PassOnce: False
Find: {nl}#Include {q}{file}{q}
Replace: #IncludeStart {file}
         {@Eval: FileText("{file}")}
         #IncludeEnd {file}
         {@Exec: IsInclude = True}

Criteria: 6
Find: {nl}#IncludeEnd
Replace: {Self}{@Exec: IsInclude = False}

Criteria: 7
Comment:
Pass: 2

Criteria: 8
BackColor: DarkKhaki
Find: {nl}%{equate} = {value} [{"[?%&]+"}] [']

Replace: {Self}{@Exec:
            Dim {equate} = ~Eval(Replace(Replace({Q}{value}{Q}, "&", "#"), "{'_.*\n'}", ""))
            Insert(Equates, "{equate}")
         }

Criteria: 9
BackColor: Yellow
Find: {nl}{line:".*"} {@If: MetaIF == False}
Replace: {nl}'{line}

Criteria: 10
BackColor: Yellow
Find: {nl}{" *#If"} {expr}
Replace: {Self}{@Exec:
            Push(NestedIF, MetaIF)
            IIf({expr}, MetaIF=True, MetaIF=False)
         }

Criteria: 11
BackColor: Brown
Find: {nl}{" *#Else"}
Replace: {Self}{@Execute: MetaIF = -(MetaIF+1)}

Criteria: 12
BackColor: RoyalBlue
Find: {nl}{" *#ElseIf"} {expr}
Replace: {Self}{@Exec:
            IIf(MetaIF==False And {expr}, MetaIF=True, MetaIF=False)
         }

Criteria: 13
Find: {nl}{" *#EndIf"}
Replace: {Self}{@Execute: MetaIF = PopNum(NestedIF)}

Criteria: 14
Find:
Replace:

# End Search

# precompile.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.96 on 6/3/2014 6:17:36 PM
# Comment: Inserts include files, handles directives, expands macros etc

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, InputFile, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique, FilterTally

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: False
Exclude: False
Comment: Inserts include files, handles directives, expands macros etc
Selected: False
Highlight: False
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: False
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
FilterTally: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
InputFile:
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Enabled: True
PassOnce: False
Find: {@Note:
         This file is still under construction.
         It does not work just yet.
      }
Replace: {@Define:
            Syntax: { % | & | ? } ::= {Nothing}
            Syntax: Def([%]{equate}) ::= (Index(Equates, "{equate}") <> 0)
            Syntax: &{base:"[hbo]"} ::= #{base}
            Var: Equates As Table
            Var: MetaIF = True
            Var: NestedIF As Stack
            Var: IsInclude
         }
         {@Define:: Token: _.*\n ~~ Properties: ucWhiteSpace}

Criteria: 2
Comment:
Pass: 1

Criteria: 3
Enabled: True
Selected: True
PassOnce: False
Find: {@Start}
Replace: ' These equates may need to be adjusted manually
         ' depending on the compiler version used
         %PB_REVISION = &H501
         %PB_REVLETTER = &H20
         %PB_EXE = -1
         %PB_CC32 = -1
         %PB_DLL32 = 0
         %PB_WIN32 = 0
         %USEMACROS = -1

Criteria: 4
Enabled: True
BackColor: Purple
Find: { [{nl}]{comment:"'.*"} | {"_[^\n]*\n"} }
      {@If: IsInclude}
Replace: {Nothing}

Criteria: 5
Enabled: False
PassOnce: False
Find: {nl}#Include {q}{file}{q}
Replace: #IncludeStart {file}
         {@Eval: FileText("{file}")}
         #IncludeEnd {file}
         {@Exec: IsInclude = True}

Criteria: 6
Enabled: True
Find: {nl}#IncludeEnd
Replace: {Self}{@Exec: IsInclude = False}

Criteria: 7
Comment:
Pass: 2

Criteria: 8
Enabled: True
BackColor: DarkKhaki
Find: {nl}%{equate} = {value} [{"[?%&]+"}] [']

Replace: {Self}{@Exec:
            Dim {equate} = ~Eval(Replace(Replace({Q}{value}{Q}, "&", "#"), "{'_.*\n'}", ""))
            Insert(Equates, "{equate}")
         }

Criteria: 9
Enabled: True
BackColor: Yellow
Find: {nl}{line:".*"} {@If: MetaIF == False}
Replace: {nl}'{line}

Criteria: 10
Enabled: True
BackColor: Yellow
Find: {nl}{" *#If"} {expr}
Replace: {Self}{@Exec:
            Push(NestedIF, MetaIF)
            IIf({expr}, MetaIF=True, MetaIF=False)
         }

Criteria: 11
Enabled: True
BackColor: Brown
Find: {nl}{" *#Else"}
Replace: {Self}{@Execute: MetaIF = -(MetaIF+1)}

Criteria: 12
Enabled: True
BackColor: RoyalBlue
Find: {nl}{" *#ElseIf"} {expr}
Replace: {Self}{@Exec:
            IIf(MetaIF==False And {expr}, MetaIF=True, MetaIF=False)
         }

Criteria: 13
Enabled: True
Find: {nl}{" *#EndIf"}
Replace: {Self}{@Execute: MetaIF = PopNum(NestedIF)}

# End Search


fixed scroll area for extra controls

fixed scroll area for extra controls

// MutatH0r.CRZMutator_SuperStingray
// ----------------
// Dynamically configurable weapon, which allows changing weapon and projectile settings on the fly
//
// ----------------
// by PredatH0r
//================================================================

class CRZMutator_SuperStingray extends CRZMutator config (MutatH0r);

struct TaggedPawnInfo
{
  var Pawn Pawn;
  var float ExpirationTime;
  var float ComboExtraDamage;
};

const OPT_DrawDamageRadius = "DrawDamageRadius";
const OPT_Preset = "SuperRayPreset";
const OPT_Mutate = "SuperRayMutate";

var float DamagePlasma, DamageBeam, DamageCombo;
var float KnockbackPlasma, KnockbackBeam, DamageRadius;
var float TagDuration;
var float DamageFactorSelf, DamageFactorSplash, LevitationSelf, LevitationOthers;
var float FireIntervalPlasma, FireIntervalBeam;
var bool receivedWelcomeMessage;
var LinearColor TagColor;
var bool DrawDamageRadius;
var bool AllowMutate;
var int ShotCostPlasma, ShotCostBeam;
var bool SwapButtons;

var repnotify byte SettingsChanged;

var bool bConfigWidgets;
var bool bAllowDisableTick;

// server only
var array<TaggedPawnInfo> TaggedPawns;

replication
{
  if (Role == ENetRole.ROLE_Authority && (bNetInitial || bNetDirty))
    DamagePlasma, DamageRadius, KnockbackPlasma, FireIntervalPlasma, FireIntervalBeam, DamageBeam, DrawDamageRadius, AllowMutate, ShotCostPlasma, ShotCostBeam, SwapButtons,
      SettingsChanged;
}

simulated event PostBeginPlay()
{
  super.PostBeginPlay();
  SetTickGroup(ETickingGroup.TG_PreAsyncWork);

  if (Role == ROLE_Authority)
    SetTimer(1.0, true, 'CleanupTaggedPawns');
}

function InitMutator(string options, out string error)
{
  local string val;

  super.InitMutator(options, error);

  ApplyPresetName(class'GameInfo'.static.ParseOption(options, OPT_Preset));
  val = class'GameInfo'.static.ParseOption(options, OPT_DrawDamageRadius);
  if (val != "")
    DrawDamageRadius = bool(val);

  val = class'GameInfo'.static.ParseOption(options, OPT_Mutate);
  AllowMutate = val != "" ? bool(val) : (WorldInfo.NetMode == NM_Standalone);
}

function ApplyPresetName(string presetName)
{
  local SuperStingrayConfig preset;

  if (presetName == "")
    presetName = "Preset1";
  preset = new(none, presetName) class'SuperStingrayConfig';
  preset.SetDefaults();
  ApplyPreset(preset);
}

function ApplyPreset(SuperStingrayConfig preset)
{
  DamagePlasma = preset.DamagePlasma;
  DamageBeam = preset.DamageBeam;
  DamageCombo = preset.DamageCombo;
  DamageRadius = preset.DamageRadius;
  DrawDamageRadius = preset.DrawDamageRadius;
  DamageFactorSelf = preset.DamageFactorSelf;
  DamageFactorSplash = preset.DamageFactorSplash;
  KnockbackPlasma = preset.KnockbackPlasma;
  KnockbackBeam = preset.KnockbackBeam;
  LevitationSelf = preset.LevitationSelf;
  LevitationOthers = preset.LevitationOthers;
  FireIntervalPlasma = preset.FireIntervalPlasma;
  FireIntervalBeam = preset.FireIntervalBeam;
  TagColor = preset.TagColor;
  TagDuration = preset.TagDuration;
  SwapButtons = preset.SwapButtons;
  ShotCostPlasma = preset.ShotCost[0];
  ShotCostBeam = preset.ShotCost[1];

  ApplySettings();
  ++SettingsChanged;
}

function bool CheckReplacement(Actor other)
{
  local CRZWeap_ScionRifle w;
  local H0Weap_ScionRifle r;
  w = CRZWeap_ScionRifle(other);
  r = H0Weap_ScionRifle(other);

  if (w != none && r == none)
  {
    ReplaceWith(other, "MutatH0r.H0Weap_ScionRifle");
    //return false;
  }
  if (CRZWeaponPickupFactory(other) != none && CRZWeaponPickupFactory(other).WeaponPickupClass == class'Cruzade.CRZWeap_ScionRifle')
  {
    CRZWeaponPickupFactory(other).WeaponPickupClass = class'MutatH0r.H0Weap_ScionRifle';
    CRZWeaponPickupFactory(other).InventoryType = class'MutatH0r.H0Weap_ScionRifle';
  }
  return true;
}

function CleanupTaggedPawns()
{
  local int i;

  // clean up list of pawns tagged for combo-damage
  for (i=0; i<TaggedPawns.Length; i++)
  {
    if (TaggedPawns[i].ExpirationTime < WorldInfo.TimeSeconds)
    {
      TaggedPawns.Remove(i, 1);
      --i;
    }
  }
}

simulated function Tick(float DeltaTime)
{
  local UTPawn p;
  local Vector v;

  // draw splash radius
  if (DrawDamageRadius && WorldInfo.NetMode != NM_DedicatedServer)
  {
    foreach WorldInfo.DynamicActors(class'UTPawn', P)
    {
      v = P.CylinderComponent.GetPosition() + vect(0,0,-1) * P.CylinderComponent.CollisionHeight;
      P.DrawDebugCylinder(v, v, P.CylinderComponent.CollisionRadius + DamageRadius, 16, 0, 255, 255, false);
    }
  }
}

simulated function ApplySettings()
{
  local H0Weap_ScionRifle w;
  local H0Proj_ScionRifle p;

  foreach WorldInfo.DynamicActors(class'H0Weap_ScionRifle', w)
    w.ApplySettings();
  foreach WorldInfo.DynamicActors(class'H0Proj_ScionRifle', p)
    p.ApplySettings();

  if (DrawDamageRadius && WorldInfo.NetMode != NM_DedicatedServer)
    Enable('Tick');
  else if (bAllowDisableTick)
    Disable('Tick');
}

function NetDamage(int OriginalDamage, out int Damage, Pawn Injured, Controller InstigatedBy, vector HitLocation, out vector Momentum, class<DamageType> DamageType, Actor DamageCauser)
{
  local UTPawn victim;
  local bool isSelfDamage;
  local int tagInfoIndex;
  local TaggedPawnInfo tagInfo;

  Super.NetDamage(OriginalDamage, Damage, Injured, InstigatedBy, HitLocation, Momentum, DamageType, DamageCauser);

  if (instr(string(DamageType), "CRZDmgType_Scion") >=0)
  {
    victim = UTPawn(Injured);
    isSelfDamage = Injured == InstigatedBy.Pawn;

    // combo handling
    if (!isSelfDamage && DamageCombo != 0 && TagDuration != 0)
    {
      tagInfoIndex = GetTaggedPawnInfoIndex(victim);
      //`log("Target was" $ (tagInfoIndex < 0 ? " NOT " : "") $ " tagged before");
      if (tagInfoIndex >= 0)
      {
        tagInfo = TaggedPawns[tagInfoIndex];
        if (tagInfo.ExpirationTime < WorldInfo.TimeSeconds)
          tagInfo.ComboExtraDamage = 0;
      }
      else
      {
        tagInfo.Pawn = Injured;
        TaggedPawns.Add(1);
        tagInfoIndex = TaggedPawns.Length - 1;
      }
      tagInfo.ExpirationTime = WorldInfo.TimeSeconds + TagDuration;

      if (string(DamageType) == "CRZDmgType_Scion_Plasma")
      {
        tagInfo.ComboExtraDamage += DamageCombo;
        if (Damage != DamagePlasma)
          Damage *= DamageFactorSplash;
      }
      else if (string(DamageType) == "CRZDmgType_ScionRifle" || string(DamageType) == "CRZDmgType_ScionRifle_Headshot")
      {
        //`log("Added bonus damage: " $ tagInfo.ComboExtraDamage);
        Damage += tagInfo.ComboExtraDamage;
        tagInfo.ComboExtraDamage = 0;
      }

      TaggedPawns[tagInfoIndex] = tagInfo;
      //victim.SetBodyMatColor(TagColor, TagDuration);
    }

    // modify self damage (plasma splash)
    if (isSelfDamage)
      Damage *= DamageFactorSelf;

    // add knockback
    if (string(DamageType) == "CRZDmgType_Scion_Plasma")
      Momentum.Z += isSelfDamage ? LevitationSelf : LevitationOthers;
  }
}

function int GetTaggedPawnInfoIndex(Pawn pawn)
{
  local int i;
  for (i=0; i<TaggedPawns.Length; i++)
  {
    if (TaggedPawns[i].Pawn == pawn)
      return i;
  }
  return -1;
}

function Mutate(string MutateString, PlayerController Sender)
{
  local PlayerController pc;
  local string cmd;
  local string arg;
  local int i;

  if (!AllowMutate)
  {
    super.Mutate(MutateString, Sender);
    return;
  }

  if (MutateString == "info") // dump info for all mutators
  {
    super.Mutate(MutateString, Sender);
    ShowInfo(sender);
    return;
  }

  if (left(MutateString, 3) != "sr ")
  {
    super.Mutate(MutateString, Sender);
    return;
  }

  cmd = mid(MutateString, 3);
  i = instr(cmd, " ");
  if (i >= 0)
  {
    arg = mid(cmd, i+1);
    cmd = left(cmd, i);
  }

  if (cmd == "help")
  {
    ShowHelp(Sender);
    return;
  }
  if (cmd == "info")
  {
    ShowInfo(Sender);
    return;
  }

  if (arg == "")
    return;

  if (!AllowMutate)
  {
    sender.ClientMessage("sr: modifications are disabled");
    return;
  }

  if (cmd == "preset")
    ApplyPresetName("preset" $ arg);
  else if (cmd ~= "DamagePlasma")
    DamagePlasma = float(arg);
  else if (cmd ~= "DamageRadius")
    DamageRadius = float(arg);
  else if (cmd ~= "DamageFactorSplash")
    DamageFactorSplash = float(arg);
  else if (cmd ~= "DamageFactorSelf")
    DamageFactorSelf = float(arg);
  else if (cmd ~= "KnockbackPlasma")
    KnockbackPlasma = float(arg);
  else if (cmd ~= "KnockbackBeam")
    KnockbackBeam = float(arg);
  else if (cmd ~= "DamageBeam")
    DamageBeam = float(arg);
  else if (cmd ~= "DamageCombo")
    DamageCombo = float(arg);
  else if (cmd ~= "TagDuration")
    TagDuration = float(arg);
  else if (cmd ~= "LevitationSelf")
    LevitationSelf = float(arg);
  else if (cmd ~= "LevitationOthers")
    LevitationOthers = float(arg);
  else if (cmd ~= "FireIntervalPlasma")
    FireIntervalPlasma = float(arg);
  else if (cmd ~= "FireIntervalBeam")
    FireIntervalBeam = float(arg);
  else if (cmd ~= "DrawDamageRadius")
    DrawDamageRadius = bool(arg);
  else
  {
    sender.ClientMessage("SuperStingray: unknown command: " $ cmd @ arg);
    return;
  }

  `log("SuperStingray mutated:" @ cmd @ arg);

  ApplySettings();
  ++SettingsChanged;

  if (sender == none)
    return;

  // tell everyone that a setting was changed
  foreach WorldInfo.AllControllers(class'PlayerController', pc)
  {
    pc.ClientMessage("Use mutate sr info to show the current settings.");
    pc.ClientMessage(sender.PlayerReplicationInfo.PlayerName $ " modified SuperStingray setting: " $ cmd @ arg);
  }
}

function ShowHelp(PlayerController pc)
{
  // reverse order for chat log
  pc.ClientMessage("mutate sr DrawDamageRadius 0/1", 'Info');
  pc.ClientMessage("mutate sr [setting] [value]: change [setting] to [value] (see 'mutate sr info')", 'Info');
  pc.ClientMessage("mutate sr info: show current Stingray settings", 'Info');
  pc.ClientMessage("mutate sr preset 2: plasma=17, combo bonus=13, beam=30 with faster reload", 'Info');
  pc.ClientMessage("mutate sr preset 1: plasma=17, combo bonus=8, beam=45", 'Info');
  pc.ClientMessage("mutate sr preset 0: TOXIKK defaults", 'Info');
  pc.ClientMessage("_____ SuperStingray help _____");
}

function ShowInfo(PlayerController pc)
{
  // reverse order for chat log
  pc.ClientMessage("LevitationOthers=" $ LevitationOthers $ ", LevitationSelf=" $ LevitationSelf, 'Info');
  pc.ClientMessage("DamageBeam=" $ DamageBeam $ ", FireIntervalBeam=" $ FireIntervalBeam $ ", KnockbackBeam=" $ KnockbackBeam, 'Info');
  pc.ClientMessage("DamageCombo=" $ DamageCombo $ ", TagDuration=" $ TagDuration, 'Info');
  pc.ClientMessage("DamageFactorSplash=" $ DamageFactorSplash $ ", DamageFactorSelf=" $ DamageFactorSelf $ ", KnockbackPlasma=" $ KnockbackPlasma, 'Info');
  pc.ClientMessage("DamagePlasma=" $ DamagePlasma $ ", FireIntervalPlasma=" $ FireIntervalPlasma $ ", DamageRadius=" $ DamageRadius, 'Info');
  pc.ClientMessage("_____ SuperStingray settings _____");
}

simulated event ReplicatedEvent(name varName)
{
  if (varName == 'SettingsChanged')
    ApplySettings();
}

static function PopulateConfigView(GFxCRZFrontEnd_ModularView ConfigView, optional CRZUIDataProvider_Mutator MutatorDataProvider)
{
  local SuperStingrayConfig preset;

  super.PopulateConfigView(ConfigView, MutatorDataProvider);

  if (!default.bConfigWidgets)
    return;

  ConfigView.SetMaskBounds(ConfigView.ListObject1, 400, 975, true);

  preset = new(none, "Preset1") class'SuperStingrayConfig';
  class'MutConfigHelper'.static.NotifyPopulated(class'CRZMutator_SuperStingray');

  class'MutConfigHelper'.static.AddCheckBox(ConfigView, "Swap Buttons", "Swap primary and secondary fire", preset.SwapButtons, OnCheckboxClick);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Damage Ball", "Damage dealt by a direct plasma ball hit [17]", 0, 100, 1, preset.DamagePlasma, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Damage Beam", "Damage dealt by a beam hit [45]", 0, 100, 1, preset.DamageBeam, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Damage Combo", "Extra damage per ball when following up with a beam [8]", 0, 100, 1, preset.DamageCombo, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Fire Rate Ball", "Time between firing 2 plasma balls [167 millisec]", 0, 2000, 10, preset.FireIntervalPlasma * 1000, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Fire Rate Beam", "Time between firing 2 beams [770 millisec]", 0, 2000, 10, preset.FireIntervalBeam * 1000, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Knockback Ball", "Force pushing player away from point of impact [200]", 0, 350, 10, preset.KnockbackPlasma / 100, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Knockback Beam", "Force pushing player away [200]", 0, 350, 10, preset.KnockbackBeam / 100, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Lift yourself", "Lifting yourself up with splash damage [50]", 0, 200, 5, preset.LevitationSelf, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Lift others", "Lifting other players up with splash damage [100]", 0, 200, 5, preset.LevitationOthers, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Self Damage %", "Splash damage you do to yourself [100]", 0, 200, 5, preset.DamageFactorSelf*100, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Splash Radius", "Radius around ball impact for splash damage [120]", 0, 200, 10, preset.DamageRadius, OnSliderChanged);
  class'MutConfigHelper'.static.AddCheckBox(ConfigView, "Draw Splash Rad.", "Draw a circle indicating the splash damage area", preset.DrawDamageRadius, OnCheckboxClick);
}

function static OnSliderChanged(string label, float value, GFxClikWidget.EventData ev)
{
  local SuperStingrayConfig preset;

  preset = new(none, "Preset1") class'SuperStingrayConfig';

  switch(label)
  {
    case "Damage Ball": preset.DamagePlasma = value; break;
    case "Damage Beam": preset.DamageBeam = value; break;
    case "Damage Combo": preset.DamageCombo = value; break;
    case "Fire Rate Ball": preset.FireIntervalPlasma = value / 1000; break;
    case "Fire Rate Beam": preset.FireIntervalBeam = value / 1000; break;
    case "Knockback Ball": preset.KnockbackPlasma = value * 100; break;
    case "Knockback Beam": preset.KnockbackBeam = value * 100; break;
    case "Lift yourself": preset.LevitationSelf = value; break;
    case "Lift others": preset.LevitationOthers = value; break;
    case "Splash Radius": preset.DamageRadius = value; break;
    case "Self Damage %": preset.DamageFactorSelf = value/100; break;
  }

  preset.SaveConfig();
}

static function OnCheckboxClick(string label, bool value, GFxClikWidget.EventData ev)
{
  local SuperStingrayConfig preset;
  preset = new(none, "Preset1") class'SuperStingrayConfig';
  if (label == "Swap Buttons")
    preset.SwapButtons = value;
  else if (label == "Draw Splash Rad.")
    preset.DrawDamageRadius = value;
  preset.SaveConfig();
}

defaultproperties
{
  RemoteRole=ROLE_SimulatedProxy
  bAlwaysRelevant=true

  bConfigWidgets=true
  bAllowDisableTick=true

  //TagDuration=1.0
  TagColor=(A=255.0, R=0.0, G=128.0, B=0.0)
  //DamagePlasma=17
  //DamageRadius=120
  //DamageBeam=50
  //DamageCombo=50
  //KnockbackPlasma=20000
  //LevitationSelf=50
  //LevitationOthers=100
  //SelfDamageFactor=0
  GroupNames[0]="STINGRAY"
}

// MutatH0r.CRZMutator_SuperStingray
// ----------------
// Dynamically configurable weapon, which allows changing weapon and projectile settings on the fly
//
// ----------------
// by PredatH0r
//================================================================

class CRZMutator_SuperStingray extends CRZMutator config (MutatH0r);

struct TaggedPawnInfo
{
  var Pawn Pawn;
  var float ExpirationTime;
  var float ComboExtraDamage;
};

const OPT_DrawDamageRadius = "DrawDamageRadius";
const OPT_Preset = "SuperRayPreset";
const OPT_Mutate = "SuperRayMutate";

var float DamagePlasma, DamageBeam, DamageCombo;
var float KnockbackPlasma, KnockbackBeam, DamageRadius;
var float TagDuration;
var float DamageFactorSelf, DamageFactorSplash, LevitationSelf, LevitationOthers;
var float FireIntervalPlasma, FireIntervalBeam;
var bool receivedWelcomeMessage;
var LinearColor TagColor;
var bool DrawDamageRadius;
var bool AllowMutate;
var int ShotCostPlasma, ShotCostBeam;
var bool SwapButtons;

var repnotify byte SettingsChanged;

var bool bConfigWidgets;
var bool bAllowDisableTick;

// server only
var array<TaggedPawnInfo> TaggedPawns;

replication
{
  if (Role == ENetRole.ROLE_Authority && (bNetInitial || bNetDirty))
    DamagePlasma, DamageRadius, KnockbackPlasma, FireIntervalPlasma, FireIntervalBeam, DamageBeam, DrawDamageRadius, AllowMutate, ShotCostPlasma, ShotCostBeam, SwapButtons,
      SettingsChanged;
}

simulated event PostBeginPlay()
{
  super.PostBeginPlay();
  SetTickGroup(ETickingGroup.TG_PreAsyncWork);

  if (Role == ROLE_Authority)
    SetTimer(1.0, true, 'CleanupTaggedPawns');
}

function InitMutator(string options, out string error)
{
  local string val;

  super.InitMutator(options, error);

  ApplyPresetName(class'GameInfo'.static.ParseOption(options, OPT_Preset));
  val = class'GameInfo'.static.ParseOption(options, OPT_DrawDamageRadius);
  if (val != "")
    DrawDamageRadius = bool(val);

  val = class'GameInfo'.static.ParseOption(options, OPT_Mutate);
  AllowMutate = val != "" ? bool(val) : (WorldInfo.NetMode == NM_Standalone);
}

function ApplyPresetName(string presetName)
{
  local SuperStingrayConfig preset;

  if (presetName == "")
    presetName = "Preset1";
  preset = new(none, presetName) class'SuperStingrayConfig';
  preset.SetDefaults();
  ApplyPreset(preset);
}

function ApplyPreset(SuperStingrayConfig preset)
{
  DamagePlasma = preset.DamagePlasma;
  DamageBeam = preset.DamageBeam;
  DamageCombo = preset.DamageCombo;
  DamageRadius = preset.DamageRadius;
  DrawDamageRadius = preset.DrawDamageRadius;
  DamageFactorSelf = preset.DamageFactorSelf;
  DamageFactorSplash = preset.DamageFactorSplash;
  KnockbackPlasma = preset.KnockbackPlasma;
  KnockbackBeam = preset.KnockbackBeam;
  LevitationSelf = preset.LevitationSelf;
  LevitationOthers = preset.LevitationOthers;
  FireIntervalPlasma = preset.FireIntervalPlasma;
  FireIntervalBeam = preset.FireIntervalBeam;
  TagColor = preset.TagColor;
  TagDuration = preset.TagDuration;
  SwapButtons = preset.SwapButtons;
  ShotCostPlasma = preset.ShotCost[0];
  ShotCostBeam = preset.ShotCost[1];

  ApplySettings();
  ++SettingsChanged;
}

function bool CheckReplacement(Actor other)
{
  local CRZWeap_ScionRifle w;
  local H0Weap_ScionRifle r;
  w = CRZWeap_ScionRifle(other);
  r = H0Weap_ScionRifle(other);

  if (w != none && r == none)
  {
    ReplaceWith(other, "MutatH0r.H0Weap_ScionRifle");
    //return false;
  }
  if (CRZWeaponPickupFactory(other) != none && CRZWeaponPickupFactory(other).WeaponPickupClass == class'Cruzade.CRZWeap_ScionRifle')
  {
    CRZWeaponPickupFactory(other).WeaponPickupClass = class'MutatH0r.H0Weap_ScionRifle';
    CRZWeaponPickupFactory(other).InventoryType = class'MutatH0r.H0Weap_ScionRifle';
  }
  return true;
}

function CleanupTaggedPawns()
{
  local int i;

  // clean up list of pawns tagged for combo-damage
  for (i=0; i<TaggedPawns.Length; i++)
  {
    if (TaggedPawns[i].ExpirationTime < WorldInfo.TimeSeconds)
    {
      TaggedPawns.Remove(i, 1);
      --i;
    }
  }
}

simulated function Tick(float DeltaTime)
{
  local UTPawn p;
  local Vector v;

  // draw splash radius
  if (DrawDamageRadius && WorldInfo.NetMode != NM_DedicatedServer)
  {
    foreach WorldInfo.DynamicActors(class'UTPawn', P)
    {
      v = P.CylinderComponent.GetPosition() + vect(0,0,-1) * P.CylinderComponent.CollisionHeight;
      P.DrawDebugCylinder(v, v, P.CylinderComponent.CollisionRadius + DamageRadius, 16, 0, 255, 255, false);
    }
  }
}

simulated function ApplySettings()
{
  local H0Weap_ScionRifle w;
  local H0Proj_ScionRifle p;

  foreach WorldInfo.DynamicActors(class'H0Weap_ScionRifle', w)
    w.ApplySettings();
  foreach WorldInfo.DynamicActors(class'H0Proj_ScionRifle', p)
    p.ApplySettings();

  if (DrawDamageRadius && WorldInfo.NetMode != NM_DedicatedServer)
    Enable('Tick');
  else if (bAllowDisableTick)
    Disable('Tick');
}

function NetDamage(int OriginalDamage, out int Damage, Pawn Injured, Controller InstigatedBy, vector HitLocation, out vector Momentum, class<DamageType> DamageType, Actor DamageCauser)
{
  local UTPawn victim;
  local bool isSelfDamage;
  local int tagInfoIndex;
  local TaggedPawnInfo tagInfo;

  Super.NetDamage(OriginalDamage, Damage, Injured, InstigatedBy, HitLocation, Momentum, DamageType, DamageCauser);

  if (instr(string(DamageType), "CRZDmgType_Scion") >=0)
  {
    victim = UTPawn(Injured);
    isSelfDamage = Injured == InstigatedBy.Pawn;

    // combo handling
    if (!isSelfDamage && DamageCombo != 0 && TagDuration != 0)
    {
      tagInfoIndex = GetTaggedPawnInfoIndex(victim);
      //`log("Target was" $ (tagInfoIndex < 0 ? " NOT " : "") $ " tagged before");
      if (tagInfoIndex >= 0)
      {
        tagInfo = TaggedPawns[tagInfoIndex];
        if (tagInfo.ExpirationTime < WorldInfo.TimeSeconds)
          tagInfo.ComboExtraDamage = 0;
      }
      else
      {
        tagInfo.Pawn = Injured;
        TaggedPawns.Add(1);
        tagInfoIndex = TaggedPawns.Length - 1;
      }
      tagInfo.ExpirationTime = WorldInfo.TimeSeconds + TagDuration;

      if (string(DamageType) == "CRZDmgType_Scion_Plasma")
      {
        tagInfo.ComboExtraDamage += DamageCombo;
        if (Damage != DamagePlasma)
          Damage *= DamageFactorSplash;
      }
      else if (string(DamageType) == "CRZDmgType_ScionRifle" || string(DamageType) == "CRZDmgType_ScionRifle_Headshot")
      {
        //`log("Added bonus damage: " $ tagInfo.ComboExtraDamage);
        Damage += tagInfo.ComboExtraDamage;
        tagInfo.ComboExtraDamage = 0;
      }

      TaggedPawns[tagInfoIndex] = tagInfo;
      //victim.SetBodyMatColor(TagColor, TagDuration);
    }

    // modify self damage (plasma splash)
    if (isSelfDamage)
      Damage *= DamageFactorSelf;

    // add knockback
    if (string(DamageType) == "CRZDmgType_Scion_Plasma")
      Momentum.Z += isSelfDamage ? LevitationSelf : LevitationOthers;
  }
}

function int GetTaggedPawnInfoIndex(Pawn pawn)
{
  local int i;
  for (i=0; i<TaggedPawns.Length; i++)
  {
    if (TaggedPawns[i].Pawn == pawn)
      return i;
  }
  return -1;
}

function Mutate(string MutateString, PlayerController Sender)
{
  local PlayerController pc;
  local string cmd;
  local string arg;
  local int i;

  if (!AllowMutate)
  {
    super.Mutate(MutateString, Sender);
    return;
  }

  if (MutateString == "info") // dump info for all mutators
  {
    super.Mutate(MutateString, Sender);
    ShowInfo(sender);
    return;
  }

  if (left(MutateString, 3) != "sr ")
  {
    super.Mutate(MutateString, Sender);
    return;
  }

  cmd = mid(MutateString, 3);
  i = instr(cmd, " ");
  if (i >= 0)
  {
    arg = mid(cmd, i+1);
    cmd = left(cmd, i);
  }

  if (cmd == "help")
  {
    ShowHelp(Sender);
    return;
  }
  if (cmd == "info")
  {
    ShowInfo(Sender);
    return;
  }

  if (arg == "")
    return;

  if (!AllowMutate)
  {
    sender.ClientMessage("sr: modifications are disabled");
    return;
  }

  if (cmd == "preset")
    ApplyPresetName("preset" $ arg);
  else if (cmd ~= "DamagePlasma")
    DamagePlasma = float(arg);
  else if (cmd ~= "DamageRadius")
    DamageRadius = float(arg);
  else if (cmd ~= "DamageFactorSplash")
    DamageFactorSplash = float(arg);
  else if (cmd ~= "DamageFactorSelf")
    DamageFactorSelf = float(arg);
  else if (cmd ~= "KnockbackPlasma")
    KnockbackPlasma = float(arg);
  else if (cmd ~= "KnockbackBeam")
    KnockbackBeam = float(arg);
  else if (cmd ~= "DamageBeam")
    DamageBeam = float(arg);
  else if (cmd ~= "DamageCombo")
    DamageCombo = float(arg);
  else if (cmd ~= "TagDuration")
    TagDuration = float(arg);
  else if (cmd ~= "LevitationSelf")
    LevitationSelf = float(arg);
  else if (cmd ~= "LevitationOthers")
    LevitationOthers = float(arg);
  else if (cmd ~= "FireIntervalPlasma")
    FireIntervalPlasma = float(arg);
  else if (cmd ~= "FireIntervalBeam")
    FireIntervalBeam = float(arg);
  else if (cmd ~= "DrawDamageRadius")
    DrawDamageRadius = bool(arg);
  else
  {
    sender.ClientMessage("SuperStingray: unknown command: " $ cmd @ arg);
    return;
  }

  `log("SuperStingray mutated:" @ cmd @ arg);

  ApplySettings();
  ++SettingsChanged;

  if (sender == none)
    return;

  // tell everyone that a setting was changed
  foreach WorldInfo.AllControllers(class'PlayerController', pc)
  {
    pc.ClientMessage("Use mutate sr info to show the current settings.");
    pc.ClientMessage(sender.PlayerReplicationInfo.PlayerName $ " modified SuperStingray setting: " $ cmd @ arg);
  }
}

function ShowHelp(PlayerController pc)
{
  // reverse order for chat log
  pc.ClientMessage("mutate sr DrawDamageRadius 0/1", 'Info');
  pc.ClientMessage("mutate sr [setting] [value]: change [setting] to [value] (see 'mutate sr info')", 'Info');
  pc.ClientMessage("mutate sr info: show current Stingray settings", 'Info');
  pc.ClientMessage("mutate sr preset 2: plasma=17, combo bonus=13, beam=30 with faster reload", 'Info');
  pc.ClientMessage("mutate sr preset 1: plasma=17, combo bonus=8, beam=45", 'Info');
  pc.ClientMessage("mutate sr preset 0: TOXIKK defaults", 'Info');
  pc.ClientMessage("_____ SuperStingray help _____");
}

function ShowInfo(PlayerController pc)
{
  // reverse order for chat log
  pc.ClientMessage("LevitationOthers=" $ LevitationOthers $ ", LevitationSelf=" $ LevitationSelf, 'Info');
  pc.ClientMessage("DamageBeam=" $ DamageBeam $ ", FireIntervalBeam=" $ FireIntervalBeam $ ", KnockbackBeam=" $ KnockbackBeam, 'Info');
  pc.ClientMessage("DamageCombo=" $ DamageCombo $ ", TagDuration=" $ TagDuration, 'Info');
  pc.ClientMessage("DamageFactorSplash=" $ DamageFactorSplash $ ", DamageFactorSelf=" $ DamageFactorSelf $ ", KnockbackPlasma=" $ KnockbackPlasma, 'Info');
  pc.ClientMessage("DamagePlasma=" $ DamagePlasma $ ", FireIntervalPlasma=" $ FireIntervalPlasma $ ", DamageRadius=" $ DamageRadius, 'Info');
  pc.ClientMessage("_____ SuperStingray settings _____");
}

simulated event ReplicatedEvent(name varName)
{
  if (varName == 'SettingsChanged')
    ApplySettings();
}

static function PopulateConfigView(GFxCRZFrontEnd_ModularView ConfigView, optional CRZUIDataProvider_Mutator MutatorDataProvider)
{
  local SuperStingrayConfig preset;

  super.PopulateConfigView(ConfigView, MutatorDataProvider);

  if (!default.bConfigWidgets)
    return;

  preset = new(none, "Preset1") class'SuperStingrayConfig';
  class'MutConfigHelper'.static.NotifyPopulated(class'CRZMutator_SuperStingray');

  class'MutConfigHelper'.static.AddCheckBox(ConfigView, "Swap Buttons", "Swap primary and secondary fire", preset.SwapButtons, OnCheckboxClick);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Damage Ball", "Damage dealt by a direct plasma ball hit [17]", 0, 100, 1, preset.DamagePlasma, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Damage Beam", "Damage dealt by a beam hit [45]", 0, 100, 1, preset.DamageBeam, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Damage Combo", "Extra damage per ball when following up with a beam [8]", 0, 100, 1, preset.DamageCombo, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Fire Rate Ball", "Time between firing 2 plasma balls [167 millisec]", 0, 2000, 10, preset.FireIntervalPlasma * 1000, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Fire Rate Beam", "Time between firing 2 beams [770 millisec]", 0, 2000, 10, preset.FireIntervalBeam * 1000, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Knockback Ball", "Force pushing player away from point of impact [200]", 0, 350, 10, preset.KnockbackPlasma / 100, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Knockback Beam", "Force pushing player away [200]", 0, 350, 10, preset.KnockbackBeam / 100, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Lift yourself", "Lifting yourself up with splash damage [50]", 0, 200, 5, preset.LevitationSelf, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Lift others", "Lifting other players up with splash damage [100]", 0, 200, 5, preset.LevitationOthers, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Self Damage %", "Splash damage you do to yourself [100]", 0, 200, 5, preset.DamageFactorSelf*100, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Splash Radius", "Radius around ball impact for splash damage [120]", 0, 200, 10, preset.DamageRadius, OnSliderChanged);
  class'MutConfigHelper'.static.AddCheckBox(ConfigView, "Draw Splash Rad.", "Draw a circle indicating the splash damage area", preset.DrawDamageRadius, OnCheckboxClick);
}

function static OnSliderChanged(string label, float value, GFxClikWidget.EventData ev)
{
  local SuperStingrayConfig preset;

  preset = new(none, "Preset1") class'SuperStingrayConfig';

  switch(label)
  {
    case "Damage Ball": preset.DamagePlasma = value; break;
    case "Damage Beam": preset.DamageBeam = value; break;
    case "Damage Combo": preset.DamageCombo = value; break;
    case "Fire Rate Ball": preset.FireIntervalPlasma = value / 1000; break;
    case "Fire Rate Beam": preset.FireIntervalBeam = value / 1000; break;
    case "Knockback Ball": preset.KnockbackPlasma = value * 100; break;
    case "Knockback Beam": preset.KnockbackBeam = value * 100; break;
    case "Lift yourself": preset.LevitationSelf = value; break;
    case "Lift others": preset.LevitationOthers = value; break;
    case "Splash Radius": preset.DamageRadius = value; break;
    case "Self Damage %": preset.DamageFactorSelf = value/100; break;
  }

  preset.SaveConfig();
}

static function OnCheckboxClick(string label, bool value, GFxClikWidget.EventData ev)
{
  local SuperStingrayConfig preset;
  preset = new(none, "Preset1") class'SuperStingrayConfig';
  if (label == "Swap Buttons")
    preset.SwapButtons = value;
  else if (label == "Draw Splash Rad.")
    preset.DrawDamageRadius = value;
  preset.SaveConfig();
}

defaultproperties
{
  RemoteRole=ROLE_SimulatedProxy
  bAlwaysRelevant=true

  bConfigWidgets=true
  bAllowDisableTick=true

  //TagDuration=1.0
  TagColor=(A=255.0, R=0.0, G=128.0, B=0.0)
  //DamagePlasma=17
  //DamageRadius=120
  //DamageBeam=50
  //DamageCombo=50
  //KnockbackPlasma=20000
  //LevitationSelf=50
  //LevitationOthers=100
  //SelfDamageFactor=0
  GroupNames[0]="STINGRAY"
}


Update filehandler.uc

Update filehandler.uc

Added Exe.Extn$, Exe.Full$, Exe.Name$, Exe.Namex, Exe.Path$

# filehandler.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.5 on 2/27/2014 1:10:07 PM
# Comment: File handler

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: File handler
Selected: False
Highlight: True
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Comment:
Pass: 1

Criteria: 2
BackColor: Yellow
SkipOver: True
Find: ' {Comment:".*"}
Replace: [Skip over]

Criteria: 3
BackColor: DeepSkyBlue
Find: {@Start}
Replace: #include <iostream>
         #include <fstream>
         {@Var: FreeFileNum}

Criteria: 4
BackColor: DeepSkyBlue
Find: Open {filespec}
      { For {{Input: Input}|{Output: Output}|{Append: Append}|{Binary: Binary}|{Random: Random}}|{Default: } }
      { Access Read | Access Write | Access Read Write | }
      { Lock {{LockRead: Read}|{LockWrite: Write}|{LockBoth: Read Write}|{LockShared: Shared}}|{LockDefault: } }
      As [#]{filenum} [Len = {size=128}]
Replace: fstream file_{filenum} (string({filespec}).c_str(),
            {Input:   ios::in}
            {Output:  ios::out | ios::trunc}
            {Append:  ios::out | ios::app}
            {Binary:  ios::binary | ios::in | ios::out}
            {Random:  ios::binary | ios::in | ios::out}
            {Default: ios::binary | ios::in | ios::out}
         );

Criteria: 5
BackColor: Lime
Find: Close [#]{filenum}
Replace: file_{filenum}.close() ' PB: Close #{filenum}

Criteria: 6
BackColor: RoyalBlue
PassOnce: False
Find: Close [#]{file1}, {more}
Replace: Close {file1}
         Close {more}

Criteria: 7
BackColor: Pink
Find: Seek [#] {filenum}, {position}
Replace: file_{filenum}.seekg({position}-1)
         file_{filenum}.seekp({position}-1)

Criteria: 8
Find: Seek([#] {filenum})
Replace: file_{filenum}.tellg()+1

Criteria: 9
BackColor: SlateBlue
Find: LOF({filenum})
Replace: (missing)

Criteria: 10
Find: EOF({filenum})
Replace: file_{filenum}.eof()

Criteria: 11
Find: FreeFile
Replace: {@Eval: FreeFileNum += 1; FreeFileNum}

Criteria: 12
BackColor: Green
Find: Get$ [#] {filenum}, {count}, {StringVar}
Replace: {StringVar}.resize({count})
         file_{filenum}.read(&{StringVar}[0], {count})

Criteria: 13
BackColor: SandyBrown
Find: Put$ [#] {filenum}, {text}
Replace: file_{filenum}.write(&{text}[0], {text}.size())

Criteria: 14
Find: IsFile({file})
Replace: PB_ISFILE({file})

Criteria: 15
BackColor: Gold
Find: EXE.Extn$
Replace: PB_EXE_EXTN

Criteria: 16
BackColor: Silver
Find: EXE.Full$
Replace: PB_EXE_FULL()

Criteria: 17
Find: EXE.Name$
Replace: PB_EXE_NAME

Criteria: 18
BackColor: CornflowerBlue
Find: EXE.Namex$
Replace: PB_EXE_NAMEX

Criteria: 19
Selected: True
Find: EXE.Path$
Replace: PB_EXE_PATH

Criteria: 20
Comment:
Pass: 2

Criteria: 21
BackColor: Yellow
Find: fstream {file} ({args+})
Replace: {@Eval: Replace('{Self}', '{"[ \n]+"}', ' ')}

# End Search

# filehandler.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.5 on 2/26/2014 4:57:34 PM
# Comment: File handler

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: File handler
Selected: False
Highlight: True
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Comment:
Pass: 1

Criteria: 2
BackColor: Yellow
SkipOver: True
Find: ' {Comment:".*"}
Replace: [Skip over]

Criteria: 3
BackColor: DeepSkyBlue
Find: {@Start}
Replace: #include <iostream>
         #include <fstream>
         {@Var: FreeFileNum}

Criteria: 4
BackColor: DeepSkyBlue
Find: Open {filespec}
      { For {{Input: Input}|{Output: Output}|{Append: Append}|{Binary: Binary}|{Random: Random}}|{Default: } }
      { Access Read | Access Write | Access Read Write | }
      { Lock {{LockRead: Read}|{LockWrite: Write}|{LockBoth: Read Write}|{LockShared: Shared}}|{LockDefault: } }
      As [#]{filenum} [Len = {size=128}]
Replace: fstream file_{filenum} (string({filespec}).c_str(),
            {Input:   ios::in}
            {Output:  ios::out | ios::trunc}
            {Append:  ios::out | ios::app}
            {Binary:  ios::binary | ios::in | ios::out}
            {Random:  ios::binary | ios::in | ios::out}
            {Default: ios::binary | ios::in | ios::out}
         );

Criteria: 5
BackColor: Lime
Find: Close [#]{filenum}
Replace: file_{filenum}.close() ' PB: Close #{filenum}

Criteria: 6
BackColor: RoyalBlue
PassOnce: False
Find: Close [#]{file1}, {more}
Replace: Close {file1}
         Close {more}

Criteria: 7
BackColor: Pink
Find: Seek [#] {filenum}, {position}
Replace: file_{filenum}.seekg({position}-1)
         file_{filenum}.seekp({position}-1)

Criteria: 8
Find: Seek([#] {filenum})
Replace: file_{filenum}.tellg()+1

Criteria: 9
BackColor: SlateBlue
Find: LOF({filenum})
Replace: (missing)

Criteria: 10
Find: EOF({filenum})
Replace: file_{filenum}.eof()

Criteria: 11
Find: FreeFile
Replace: {@Eval: FreeFileNum += 1; FreeFileNum}

Criteria: 12
BackColor: Green
Find: Get$ [#] {filenum}, {count}, {StringVar}
Replace: {StringVar}.resize({count})
         file_{filenum}.read(&{StringVar}[0], {count})

Criteria: 13
BackColor: SandyBrown
Find: Put$ [#] {filenum}, {text}
Replace: file_{filenum}.write(&{text}[0], {text}.size())

Criteria: 14
Selected: True
Find: IsFile({file})
Replace: PB_ISFILE({file})

Criteria: 15
Comment:
Pass: 2

Criteria: 16
BackColor: Yellow
Find: fstream {file} ({args+})
Replace: {@Eval: Replace('{Self}', '{"[ \n]+"}', ' ')}

# End Search