fixed replication of rocket speed

fixed replication of rocket speed

removed log spam

// MutatH0r.CRZMutator_Roq3t
// ----------------
// Modify rocket damage (direct, splash, self), knockback (horiz, vert) and fire rate
// by PredatH0r
//================================================================

class CRZMutator_Roq3t extends CRZMutator config (MutatH0r);

const OPT_DrawDamageRadius = "?DrawDamageRadius=";
const OPT_Preset = "?Roq3tPreset=";
const OPT_Mutate = "?Roq3tMutate=";

var float Knockback, KnockbackFactorOthers, KnockbackFactorSelf, MinKnockbackVert, MaxKnockbackVert, FireInterval, DamageFactorDirect, DamageFactorSplash;
var float DamageFactorSelf, DamageRadius;
var float Speed;
var bool DrawDamageRadius;
var bool AllowMutate;

replication
{
  if (Role == ENetRole.ROLE_Authority && (bNetInitial || bNetDirty))
    Knockback, FireInterval, DamageFactorDirect, DamageRadius, DrawDamageRadius, AllowMutate, Speed;
}

simulated event PostBeginPlay()
{
  super.PostBeginPlay();
  SetTickGroup(ETickingGroup.TG_PreAsyncWork);
  Enable('Tick');
}

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

  super.InitMutator(options, error);

  ApplyPreset(class 'Utils'.static.GetOption(options, OPT_Preset));
  val = class 'Utils'.static.GetOption(options, OPT_DrawDamageRadius);
  if (val != "")
    DrawDamageRadius = bool(val);

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

function ApplyPreset(string presetName)
{
  local Roq3tConfig preset;

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

  Speed = preset.Speed;
  Knockback = preset.Knockback;
  KnockbackFactorSelf = preset.KnockbackFactorSelf;
  KnockbackFactorOthers = preset.KnockbackFactorOthers;
  MinKnockbackVert = preset.MinKnockbackVert;
  MaxKnockbackVert = preset.MaxKnockbackVert;
  FireInterval = preset.FireInterval;
  DamageFactorDirect = preset.DamageFactorDirect;
  DamageFactorSplash = preset.DamageFactorSplash;
  DamageFactorSelf = preset.DamageFactorSelf;
  DamageRadius = preset.DamageRadius;
  DrawDamageRadius = preset.DrawDamageRadius;
}

function NetDamage(int OriginalDamage, out int Damage, Pawn Injured, Controller InstigatedBy, vector HitLocation, out vector Momentum, class<DamageType> DamageType, Actor DamageCauser)
{
  local float kbFactor;

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

  if (string(DamageType) != "CRZDmgType_RocketLauncher")
    return;

  Damage *= Damage == 100 ? DamageFactorDirect : DamageFactorSplash; // MaxDamage (=InstigatedBy.Pawn.DamageScaling) seems to be applied later, so 100 is still ok here
  if (Injured == InstigatedBy.Pawn)
  {
    Damage *= DamageFactorSelf;
    kbFactor = KnockbackFactorSelf;
  }
  else
    kbFactor = KnockbackFactorOthers;

  Momentum.X = Momentum.X * kbFactor;
  Momentum.Y = Momentum.Y * kbFactor;
  Momentum.Z = FClamp(Momentum.Z * kbFactor, MinKnockbackVert, MaxKnockbackVert);
}

simulated event Tick(float DeltaTime)
{
  local UTPawn P;
  local PlayerController PC;
  local CRZProj_RocketLauncher proj;
  local vector v;

  Super.Tick(Deltatime);

  // modify Cerberus
  if (Role == ROLE_Authority)
  {
    foreach WorldInfo.AllPawns(class'UTPawn', P)
      TweakCerberus(P);
  }
  else
  {
    foreach WorldInfo.LocalPlayerControllers(class'PlayerController', PC)
      TweakCerberus(PC.Pawn);
  }

  // modify rocket projectiles
  foreach WorldInfo.DynamicActors(class'CRZProj_RocketLauncher', proj)
  {
    if (abs(vsizesq(proj.Velocity) - proj.Speed * proj.Speed) < 10) // initial value
    {
      proj.Velocity = normal(proj.Velocity) * Speed; // override velocity
      proj.MaxSpeed = Speed;
    }
    proj.Damage = 100 * DamageFactorDirect;
    proj.DamageRadius = DamageRadius;
    proj.MomentumTransfer = Knockback;
  }

  // draw splash radius
  if (DrawDamageRadius && (WorldInfo.NetMode == NM_Client || WorldInfo.NetMode == NM_Standalone))
  {
    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, 255, 0, 0, false);
    }
  }
}

function TweakCerberus(Pawn p)
{
  local UTWeapon w;

  if (p != none && p.Weapon != none && string(p.Weapon.Class) == "CRZWeap_RocketLauncher")
  {
    w = UTWeapon(p.Weapon);
    w.FireInterval[0] = FireInterval;
  }
}

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

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

  if (left(MutateString, 3) != "ro ")
  {
    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("ro: modifications are disabled");
    return;
  }

  if (cmd == "preset")
    ApplyPreset("preset" $ arg);
  else if (cmd ~= "RocketSpeed")
    Speed = float(arg);
  else if (cmd ~= "KnockbackFactorOthers")
    KnockbackFactorOthers = float(arg);
  else if (cmd ~= "KnockbackFactorSelf")
    KnockbackFactorSelf = float(arg);
  else if (cmd ~= "MinKnockbackVert")
    MinKnockbackVert = float(arg);
  else if (cmd ~= "MaxKnockbackVert")
    MaxKnockbackVert = float(arg);
  else if (cmd ~= "FireInterval")
    FireInterval = float(arg);
  else if (cmd ~= "DamageFactorDirect")
    DamageFactorDirect = float(arg);
  else if (cmd ~= "DamageFactorSplash")
    DamageFactorSplash = float(arg);
  else if (cmd ~= "DamageFactorSelf")
    DamageFactorSelf = float(arg);
  else if (cmd ~= "DrawDamageRadius")
    DrawDamageRadius = bool(arg);
  else
  {
    sender.ClientMessage("Roq3t: unknown command: " $ cmd @ arg);
    return;
  }

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

  if (sender == none)
    return;

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

function ShowHelp(PlayerController pc)
{
  pc.ClientMessage("mutate ro DrawDamageRadius 0/1", 'Info');
  pc.ClientMessage("mutate ro [setting] [value]: change [setting] to [value] (see 'mutate ro info')", 'Info');
  pc.ClientMessage("mutate ro info: show current Stingray settings", 'Info');
  pc.ClientMessage("mutate ro preset 3: reload=0.85, splash=0.5, self-bounce: 1.25, other-bounce=0.75", 'Info');
  pc.ClientMessage("mutate ro preset 2: reload=1.1, smaller splash radius, self-bounce=1.25, other-bounce=0.75", 'Info');
  pc.ClientMessage("mutate ro preset 1: reload=1.1, knockback=0.75, self-bounce=1.25", 'Info');
  pc.ClientMessage("mutate ro preset 0: TOXIKK defaults", 'Info');
  pc.ClientMessage("_____ Roq3t help _____");
}

function ShowInfo(PlayerController pc)
{
  // reverse order for chat log
  pc.ClientMessage("MinKnockbackVert=" $ MinKnockbackVert $ ", MaxKnockbackVert=" $ MaxKnockbackVert, 'Info');
  pc.ClientMessage("Knockback=" $ Knockback $ ", KnockbackFactorOthers=" $ KnockbackFactorOthers $ ", KnockbackFactorSelf=" $ KnockbackFactorSelf, 'Info');
  pc.ClientMessage("DamageFactorDirect=" $ DamageFactorDirect $ ", DamageFactorSplash=" $ DamageFactorSplash $ ", DamageFactorSelf=" $ DamageFactorSelf, 'Info');
  pc.ClientMessage("FireInterval=" $ FireInterval $ ", DamageRadius=" $ DamageRadius $ ", RocketSpeed=" $ Speed, 'Info');
  pc.ClientMessage("_____ Roq3t settings _____");
}

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

  super.PopulateConfigView(ConfigView, MutatorDataProvider);
  preset = new(none, "Preset1") class'Roq3tConfig';
  class'MutConfigHelper'.static.NotifyPopulated(class'CRZMutator_Roq3t');

  class'MutConfigHelper'.static.AddSlider(ConfigView, "Rocket Speed", "Speed of the rocket projectile [1800]", 500, 7500, 50, preset.Speed, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Knockback", "Force pushing players away from point of impact [80]", 0, 200, 1, preset.Knockback / 1000, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "KB Factor Self", "Knockback factor when rocket-jumping [100%]", 0, 200, 1, preset.KnockbackFactorSelf * 100, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "KB Factor Others", "Knockback factor when hitting other players [100%]", 0, 200, 1, preset.KnockbackFactorOthers * 100, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Min Vertical KB", "Minimum vertical knockback [0]", 0, 1000, 10, preset.MinKnockbackVert, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Max Vertical KB", "Maximum vertical knockback [1000]", 0, 2000, 10, preset.MaxKnockbackVert, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Fire Rate", "Time between firing 2 rockets [1000 millisec]", 500, 2000, 10, preset.FireInterval * 1000, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Direct Damage %", "Factor to adjust damage of a direct hit [100]", 0, 200, 1, preset.DamageFactorDirect * 100, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Splash Damage %", "Factor to adjust splash damage hits [100]", 0, 200, 1, preset.DamageFactorSplash * 100, 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 [220]", 0, 300, 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 Roq3tConfig preset;

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

  switch(label)
  {
    case "Rocket Speed": preset.Speed = value; break;
    case "Knockback": preset.Knockback = value * 1000; break;
    case "KB Factor Self": preset.KnockbackFactorSelf = value/100; break;
    case "KB Factor Others": preset.KnockbackFactorOthers = value/100; break;
    case "Min Vertical KB": preset.MinKnockbackVert = value; break;
    case "Max Vertical KB": preset.MaxKnockbackVert = value; break;
    case "Fire Rate": preset.FireInterval = value / 1000; break;
    case "Direct Damage %": preset.DamageFactorDirect = value / 100; break;
    case "Splash Damage %": preset.DamageFactorSplash = value / 100; break;
    case "Self Damage %": preset.DamageFactorSelf = value/100; break;
    case "Splash Radius": preset.DamageRadius = value; break;
  }

  preset.SaveConfig();
}

static function OnCheckboxClick(string label, bool value, GFxClikWidget.EventData ev)
{
  local Roq3tConfig preset;
  preset = new(none, "Preset1") class'Roq3tConfig';
  preset.DrawDamageRadius = value;
  preset.SaveConfig();
}

defaultproperties
{
  RemoteRole=ROLE_SimulatedProxy
  bAlwaysRelevant=true
  GroupNames[0]="CERBERUS"
}

// MutatH0r.CRZMutator_Roq3t
// ----------------
// Modify rocket damage (direct, splash, self), knockback (horiz, vert) and fire rate
// by PredatH0r
//================================================================

class CRZMutator_Roq3t extends CRZMutator config (MutatH0r);

const OPT_DrawDamageRadius = "?DrawDamageRadius=";
const OPT_Preset = "?Roq3tPreset=";
const OPT_Mutate = "?Roq3tMutate=";

var float Knockback, KnockbackFactorOthers, KnockbackFactorSelf, MinKnockbackVert, MaxKnockbackVert, FireInterval, DamageFactorDirect, DamageFactorSplash;
var float DamageFactorSelf, DamageRadius;
var float Speed;
var bool DrawDamageRadius;
var bool AllowMutate;

replication
{
  if (Role == ENetRole.ROLE_Authority && (bNetInitial || bNetDirty))
    Knockback, FireInterval, DamageFactorDirect, DamageRadius, DrawDamageRadius, AllowMutate;
}

simulated event PostBeginPlay()
{
  super.PostBeginPlay();
  SetTickGroup(ETickingGroup.TG_PreAsyncWork);
  Enable('Tick');
}

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

  super.InitMutator(options, error);

  ApplyPreset(class 'Utils'.static.GetOption(options, OPT_Preset));
  val = class 'Utils'.static.GetOption(options, OPT_DrawDamageRadius);
  if (val != "")
    DrawDamageRadius = bool(val);

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

function ApplyPreset(string presetName)
{
  local Roq3tConfig preset;

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

  Speed = preset.Speed;
  Knockback = preset.Knockback;
  KnockbackFactorSelf = preset.KnockbackFactorSelf;
  KnockbackFactorOthers = preset.KnockbackFactorOthers;
  MinKnockbackVert = preset.MinKnockbackVert;
  MaxKnockbackVert = preset.MaxKnockbackVert;
  FireInterval = preset.FireInterval;
  DamageFactorDirect = preset.DamageFactorDirect;
  DamageFactorSplash = preset.DamageFactorSplash;
  DamageFactorSelf = preset.DamageFactorSelf;
  DamageRadius = preset.DamageRadius;
  DrawDamageRadius = preset.DrawDamageRadius;
}

//function bool CheckReplacement(Actor other)
//{
//  if (other.class == class'CRZWeap_RocketLauncher')
//  {
//    spawn(class'H0Weap_RocketLauncher');
//    return false;
//  }
//  return super.CheckReplacement(other);
//}

function NetDamage(int OriginalDamage, out int Damage, Pawn Injured, Controller InstigatedBy, vector HitLocation, out vector Momentum, class<DamageType> DamageType, Actor DamageCauser)
{
  local float kbFactor;

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

  if (string(DamageType) != "CRZDmgType_RocketLauncher")
    return;

  Damage *= Damage == 100 ? DamageFactorDirect : DamageFactorSplash; // MaxDamage (=InstigatedBy.Pawn.DamageScaling) seems to be applied later, so 100 is still ok here
  if (Injured == InstigatedBy.Pawn)
  {
    Damage *= DamageFactorSelf;
    kbFactor = KnockbackFactorSelf;
  }
  else
    kbFactor = KnockbackFactorOthers;

  Momentum.X = Momentum.X * kbFactor;
  Momentum.Y = Momentum.Y * kbFactor;
  `Log("Momentum.Z=" $ Momentum.Z);
  Momentum.Z = FClamp(Momentum.Z * kbFactor, MinKnockbackVert, MaxKnockbackVert);
}

simulated event Tick(float DeltaTime)
{
  local UTPawn P;
  local PlayerController PC;
  local CRZProj_RocketLauncher proj;
  local vector v;

  Super.Tick(Deltatime);

  // modify Cerberus
  if (Role == ROLE_Authority)
  {
    foreach WorldInfo.AllPawns(class'UTPawn', P)
      TweakCerberus(P);
  }
  else
  {
    foreach WorldInfo.LocalPlayerControllers(class'PlayerController', PC)
      TweakCerberus(PC.Pawn);
  }

  // modify rocket projectiles
  foreach WorldInfo.DynamicActors(class'CRZProj_RocketLauncher', proj)
  {
    if (abs(vsizesq(proj.Velocity) - proj.Speed * proj.Speed) < 10) // initial value
    {
      proj.Velocity = normal(proj.Velocity) * Speed; // override velocity
      proj.MaxSpeed = Speed;
      `Log("changed rocket speed to " $ speed);
    }
    proj.Damage = 100 * DamageFactorDirect;
    proj.DamageRadius = DamageRadius;
    proj.MomentumTransfer = Knockback;
  }

  // draw splash radius
  if (DrawDamageRadius && (WorldInfo.NetMode == NM_Client || WorldInfo.NetMode == NM_Standalone))
  {
    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, 255, 0, 0, false);
    }
  }
}

function TweakCerberus(Pawn p)
{
  local UTWeapon w;

  if (p != none && p.Weapon != none && string(p.Weapon.Class) == "CRZWeap_RocketLauncher")
  {
    w = UTWeapon(p.Weapon);
    w.FireInterval[0] = FireInterval;
  }
}

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

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

  if (left(MutateString, 3) != "ro ")
  {
    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("ro: modifications are disabled");
    return;
  }

  if (cmd == "preset")
    ApplyPreset("preset" $ arg);
  else if (cmd ~= "RocketSpeed")
    Speed = float(arg);
  else if (cmd ~= "KnockbackFactorOthers")
    KnockbackFactorOthers = float(arg);
  else if (cmd ~= "KnockbackFactorSelf")
    KnockbackFactorSelf = float(arg);
  else if (cmd ~= "MinKnockbackVert")
    MinKnockbackVert = float(arg);
  else if (cmd ~= "MaxKnockbackVert")
    MaxKnockbackVert = float(arg);
  else if (cmd ~= "FireInterval")
    FireInterval = float(arg);
  else if (cmd ~= "DamageFactorDirect")
    DamageFactorDirect = float(arg);
  else if (cmd ~= "DamageFactorSplash")
    DamageFactorSplash = float(arg);
  else if (cmd ~= "DamageFactorSelf")
    DamageFactorSelf = float(arg);
  else if (cmd ~= "DrawDamageRadius")
    DrawDamageRadius = bool(arg);
  else
  {
    sender.ClientMessage("Roq3t: unknown command: " $ cmd @ arg);
    return;
  }

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

  if (sender == none)
    return;

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

function ShowHelp(PlayerController pc)
{
  pc.ClientMessage("mutate ro DrawDamageRadius 0/1", 'Info');
  pc.ClientMessage("mutate ro [setting] [value]: change [setting] to [value] (see 'mutate ro info')", 'Info');
  pc.ClientMessage("mutate ro info: show current Stingray settings", 'Info');
  pc.ClientMessage("mutate ro preset 3: reload=0.85, splash=0.5, self-bounce: 1.25, other-bounce=0.75", 'Info');
  pc.ClientMessage("mutate ro preset 2: reload=1.1, smaller splash radius, self-bounce=1.25, other-bounce=0.75", 'Info');
  pc.ClientMessage("mutate ro preset 1: reload=1.1, knockback=0.75, self-bounce=1.25", 'Info');
  pc.ClientMessage("mutate ro preset 0: TOXIKK defaults", 'Info');
  pc.ClientMessage("_____ Roq3t help _____");
}

function ShowInfo(PlayerController pc)
{
  // reverse order for chat log
  pc.ClientMessage("MinKnockbackVert=" $ MinKnockbackVert $ ", MaxKnockbackVert=" $ MaxKnockbackVert, 'Info');
  pc.ClientMessage("Knockback=" $ Knockback $ ", KnockbackFactorOthers=" $ KnockbackFactorOthers $ ", KnockbackFactorSelf=" $ KnockbackFactorSelf, 'Info');
  pc.ClientMessage("DamageFactorDirect=" $ DamageFactorDirect $ ", DamageFactorSplash=" $ DamageFactorSplash $ ", DamageFactorSelf=" $ DamageFactorSelf, 'Info');
  pc.ClientMessage("FireInterval=" $ FireInterval $ ", DamageRadius=" $ DamageRadius $ ", RocketSpeed=" $ Speed, 'Info');
  pc.ClientMessage("_____ Roq3t settings _____");
}

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

  super.PopulateConfigView(ConfigView, MutatorDataProvider);
  preset = new(none, "Preset1") class'Roq3tConfig';
  class'MutConfigHelper'.static.NotifyPopulated(class'CRZMutator_Roq3t');

  class'MutConfigHelper'.static.AddSlider(ConfigView, "Rocket Speed", "Speed of the rocket projectile [1800]", 500, 7500, 50, preset.Speed, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Knockback", "Force pushing players away from point of impact [80]", 0, 200, 1, preset.Knockback / 1000, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "KB Factor Self", "Knockback factor when rocket-jumping [100%]", 0, 200, 1, preset.KnockbackFactorSelf * 100, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "KB Factor Others", "Knockback factor when hitting other players [100%]", 0, 200, 1, preset.KnockbackFactorOthers * 100, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Min Vertical KB", "Minimum vertical knockback [0]", 0, 1000, 10, preset.MinKnockbackVert, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Max Vertical KB", "Maximum vertical knockback [1000]", 0, 2000, 10, preset.MaxKnockbackVert, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Fire Rate", "Time between firing 2 rockets [1000 millisec]", 500, 2000, 10, preset.FireInterval * 1000, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Direct Damage %", "Factor to adjust damage of a direct hit [100]", 0, 200, 1, preset.DamageFactorDirect * 100, OnSliderChanged);
  class'MutConfigHelper'.static.AddSlider(ConfigView, "Splash Damage %", "Factor to adjust splash damage hits [100]", 0, 200, 1, preset.DamageFactorSplash * 100, 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 [220]", 0, 300, 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 Roq3tConfig preset;

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

  switch(label)
  {
    case "Rocket Speed": preset.Speed = value; break;
    case "Knockback": preset.Knockback = value * 1000; break;
    case "KB Factor Self": preset.KnockbackFactorSelf = value/100; break;
    case "KB Factor Others": preset.KnockbackFactorOthers = value/100; break;
    case "Min Vertical KB": preset.MinKnockbackVert = value; break;
    case "Max Vertical KB": preset.MaxKnockbackVert = value; break;
    case "Fire Rate": preset.FireInterval = value / 1000; break;
    case "Direct Damage %": preset.DamageFactorDirect = value / 100; break;
    case "Splash Damage %": preset.DamageFactorSplash = value / 100; break;
    case "Self Damage %": preset.DamageFactorSelf = value/100; break;
    case "Splash Radius": preset.DamageRadius = value; break;
  }

  preset.SaveConfig();
}

static function OnCheckboxClick(string label, bool value, GFxClikWidget.EventData ev)
{
  local Roq3tConfig preset;
  preset = new(none, "Preset1") class'Roq3tConfig';
  preset.DrawDamageRadius = value;
  preset.SaveConfig();
}

defaultproperties
{
  RemoteRole=ROLE_SimulatedProxy
  bAlwaysRelevant=true
  GroupNames[0]="CERBERUS"
}


Update strings.uc

Update strings.uc

Added REPLACE

# strings.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.5 on 2/14/2014 1:44:00 PM
# Comment: Converts string-related code from PowerBASIC to C++

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 string-related code from PowerBASIC to C++
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
SkipOver: True
Find: ' {Comment:".*"}
Replace: [Skip over]

Criteria: 2
Find: String
Replace: string

Criteria: 3
Find: WString
Replace: wstring

Criteria: 4
Find: {@Start}
Replace: #include <algorithm>
         #include <string>
         #include "pbstrings.h"
         using namespace std;{nl}{nl}

Criteria: 5
BackColor: DodgerBlue
PassOnce: False
Find: InStr([{n=1},] {MainStr}, {MatchStr})
Replace: PB_INSTR({n}, {MainStr}, {MatchStr})

Criteria: 6
BackColor: Tomato
PassOnce: False
Find: InStr([{n=1},] {MainStr}, Any {MatchStr})
Replace: PB_INSTR_ANY({n}, {MainStr}, {MatchStr})

Criteria: 7
BackColor: Red
PassOnce: False
Find: Left$({Str}, {n})
Replace: PB_LEFT({Str}, {n})

Criteria: 8
BackColor: Brown
PassOnce: False
Find: Right$({Str}, {n})
Replace: PB_RIGHT({Str}, {n})

Criteria: 9
BackColor: Orange
PassOnce: False
Find: Mid$({Str}, {Start} [, {Length=FULL_STRING}])
Replace: PB_MID({Str}, {Start}, {Length})

Criteria: 10
BackColor: DeepSkyBlue
PassOnce: False
Find: {Sep: {nl} | : | Then | Else }
      Mid$({Str}, {Start} [, {Length=FULL_STRING}]) = {Txt%}
Replace: {Sep} PB_MID_REPLACE({Str}, {Txt}, {Start}, {Length})

Criteria: 11
BackColor: RoyalBlue
PassOnce: False
Find: Val({Str})
Replace: stold({Str})

Criteria: 12
BackColor: Pink
PassOnce: False
Find: Str$({Number})
Replace: to_string({Number})

Criteria: 13
Find: Space$({count})
Replace: string({count}, _char( ))

Criteria: 14
Find: String$({count}, {char})
Replace: string({count}, {char})

Criteria: 15
BackColor: Violet
Find: String$({count}, {q}{char}{q})
Replace: string({count}, _char({char}))

Criteria: 16
Find: UCase$({text})
Replace: PB_UCASE({text})

Criteria: 17
BackColor: YellowGreen
Find: LCase$({text})
Replace: PB_LCASE({text})

Criteria: 18
Find: Trim$({Str} [, ANY {chars=" "}])
Replace: PB_TRIM_ANY({Str}, {chars})

Criteria: 19
BackColor: Gold
Find: LTrim$({Str} [, ANY {chars=" "}])
Replace: PB_LTRIM_ANY({Str}, {chars})

Criteria: 20
BackColor: Silver
Find: RTrim$({Str} [, ANY {chars=" "}])
Replace: PB_RTRIM_ANY({Str}, {chars})

Criteria: 21
Find: Extract$([{start=1},] {MainStr}, {MatchStr})
Replace: PB_EXTRACT({start}, {MainStr}, {MatchStr})

Criteria: 22
Find: Extract$([{start=1},] {MainStr}, Any {MatchStr})
Replace: PB_EXTRACT_ANY({start}, {MainStr}, {MatchStr})

Criteria: 23
Find: Remain$([{start=1},] {MainStr}, {MatchStr})
Replace: PB_REMAIN({start}, {MainStr}, {MatchStr})

Criteria: 24
Find: Remain$([{start=1},] {MainStr}, Any {MatchStr})
Replace: PB_REMAIN_ANY({start}, {MainStr}, {MatchStr})

Criteria: 25
Find: Remove$({Str}, {MatchStr})
Replace: PB_REMOVE({Str}, {MatchStr})

Criteria: 26
Find: Remove$({Str}, Any {MatchStr})
Replace: PB_REMOVE_ANY({Str}, {MatchStr})

Criteria: 27
Find: Replace {MatchStr} With {NewStr} In {MainStr}
Replace: PB_REPLACE({MainStr}, {MatchStr}, {NewStr})

Criteria: 28
Selected: True
Find: Replace Any {MatchStr} With {NewStr} In {MainStr}
Replace: PB_REPLACE_ANY({MainStr}, {MatchStr}, {NewStr})

# End Search

# strings.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.5 on 2/13/2014 5:48:42 PM
# Comment: Converts string-related code from PowerBASIC to C++

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 string-related code from PowerBASIC to C++
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
SkipOver: True
Find: ' {Comment:".*"}
Replace: [Skip over]

Criteria: 2
Find: String
Replace: string

Criteria: 3
Find: WString
Replace: wstring

Criteria: 4
Find: {@Start}
Replace: #include <algorithm>
         #include <string>
         #include "pbstrings.h"
         using namespace std;{nl}{nl}

Criteria: 5
BackColor: DodgerBlue
PassOnce: False
Find: InStr([{n=1},] {MainStr}, {MatchStr})
Replace: PB_INSTR({n}, {MainStr}, {MatchStr})

Criteria: 6
BackColor: Tomato
PassOnce: False
Find: InStr([{n=1},] {MainStr}, Any {MatchStr})
Replace: PB_INSTR_ANY({n}, {MainStr}, {MatchStr})

Criteria: 7
BackColor: Red
PassOnce: False
Find: Left$({Str}, {n})
Replace: PB_LEFT({Str}, {n})

Criteria: 8
BackColor: Brown
PassOnce: False
Find: Right$({Str}, {n})
Replace: PB_RIGHT({Str}, {n})

Criteria: 9
BackColor: Orange
PassOnce: False
Find: Mid$({Str}, {Start} [, {Length=FULL_STRING}])
Replace: PB_MID({Str}, {Start}, {Length})

Criteria: 10
BackColor: DeepSkyBlue
PassOnce: False
Find: {Sep: {nl} | : | Then | Else }
      Mid$({Str}, {Start} [, {Length=FULL_STRING}]) = {Txt%}
Replace: {Sep} PB_MID_REPLACE({Str}, {Txt}, {Start}, {Length})

Criteria: 11
BackColor: RoyalBlue
PassOnce: False
Find: Val({Str})
Replace: stold({Str})

Criteria: 12
BackColor: Pink
PassOnce: False
Find: Str$({Number})
Replace: to_string({Number})

Criteria: 13
Find: Space$({count})
Replace: string({count}, _char( ))

Criteria: 14
Find: String$({count}, {char})
Replace: string({count}, {char})

Criteria: 15
BackColor: Violet
Find: String$({count}, {q}{char}{q})
Replace: string({count}, _char({char}))

Criteria: 16
Find: UCase$({text})
Replace: PB_UCASE({text})

Criteria: 17
BackColor: YellowGreen
Find: LCase$({text})
Replace: PB_LCASE({text})

Criteria: 18
Find: Trim$({Str} [, ANY {chars=" "}])
Replace: PB_TRIM_ANY({Str}, {chars})

Criteria: 19
BackColor: Gold
Find: LTrim$({Str} [, ANY {chars=" "}])
Replace: PB_LTRIM_ANY({Str}, {chars})

Criteria: 20
BackColor: Silver
Find: RTrim$({Str} [, ANY {chars=" "}])
Replace: PB_RTRIM_ANY({Str}, {chars})

Criteria: 21
Find: Extract$([{start=1},] {MainStr}, {MatchStr})
Replace: PB_EXTRACT({start}, {MainStr}, {MatchStr})

Criteria: 22
Find: Extract$([{start=1},] {MainStr}, Any {MatchStr})
Replace: PB_EXTRACT_ANY({start}, {MainStr}, {MatchStr})

Criteria: 23
Find: Remain$([{start=1},] {MainStr}, {MatchStr})
Replace: PB_REMAIN({start}, {MainStr}, {MatchStr})

Criteria: 24
Find: Remain$([{start=1},] {MainStr}, Any {MatchStr})
Replace: PB_REMAIN_ANY({start}, {MainStr}, {MatchStr})

Criteria: 25
Find: Remove$({Str}, {MatchStr})
Replace: PB_REMOVE({Str}, {MatchStr})

Criteria: 26
Selected: True
Find: Remove$({Str}, Any {MatchStr})
Replace: PB_REMOVE_ANY({Str}, {MatchStr})

# End Search