Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

code

By: a guest on Jul 23rd, 2011  |  syntax: ActionScript 3  |  size: 236.58 KB  |  views: 69  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. package Game{
  2.         import Actions.*;
  3.        
  4.         import Box2D.Collision.*;
  5.         import Box2D.Collision.Shapes.*;
  6.         import Box2D.Common.Math.*;
  7.         import Box2D.Dynamics.*;
  8.         import Box2D.Dynamics.Contacts.*;
  9.         import Box2D.Dynamics.Joints.*;
  10.        
  11.         import Game.Challenges.*;
  12.         import Game.Graphics.*;
  13.         import Game.Tutorials.*;
  14.        
  15.         import General.*;
  16.  
  17.         import Gui.*;
  18.         import Parts.*;
  19.         import flash.display.*;
  20.         import flash.errors.IllegalOperationError;
  21.         import flash.events.*;
  22.         import flash.geom.Matrix;
  23.         import flash.media.*;
  24.         import flash.text.*;
  25.         import flash.utils.getTimer;
  26.  
  27.        
  28.         public class ControllerGame extends Controller {
  29.  
  30.                 //======================
  31.                 // Member Data
  32.                 //======================
  33.                 static public const INIT_PHYS_SCALE:Number = 30;
  34.  
  35.                 protected static const MIN_ZOOM_VAL:Number = 0.01;
  36.                 protected static const MAX_ZOOM_VAL:Number = 20000;
  37.  
  38.                 static public const ZOOM_FOCUS_X:Number = 400;
  39.                 static public const ZOOM_FOCUS_Y:Number = 310;
  40.                
  41.                 public static const REPLAY_SYNC_FRAMES:int = 3;
  42.                
  43.                 public static const ADMIN_USERS:Array = ["Oliver", "Ryan Clark", "aaaaajon", "andreas002", "BillyJimBob", "EMDF", "fighterlegend", "Sruixan", "Illume", "Cheeseyx", "Leafsnail", "bigjohnpalmer", "jayther", "Spedione", "Thax", "b0tman", "zom", "KyuubisSlave", "Redstater", "rutgersemp", "Euphrates", "lakeeriesuperstar", "SilverGun", "mattbob", "bowman9898", "willempiee", "dark dan21", "pandm"];
  44.                 static public var playingReplay:Boolean = false;
  45.                 static public var viewingUnsavedReplay:Boolean = false;
  46.                 static public var replay:Replay;
  47.                 static public var replayDirectlyLinked:Boolean = false;
  48.  
  49.                 private var replaySplineXs:Array;
  50.                 private var replaySplineYs:Array;
  51.                 private var replaySplineAngles:Array;
  52.  
  53.                 static public var collisionGroup:int = 0x0001;
  54.                
  55.                 public var degree:Number;
  56.                 public var newAngle:Number;
  57.                 public var radian:Number;
  58.                 public var newdegree:Number;
  59.                 public var initrotang:Number;
  60.                
  61.                 public var rect:ShapePart;
  62.                
  63.                 public var m_world:b2World = null;
  64.                 public var m_mouseJoint:b2MouseJoint = null;
  65.                 public var m_iterations:int = 10;
  66.                 public var m_timeStep:Number = 1.0/30;
  67.                 public var m_physScale:Number = INIT_PHYS_SCALE;
  68.                 // world mouse position
  69.                 static public var wasMouseDown:Boolean = false;
  70.                 static public var mouseXWorldPhys:Number;
  71.                 static public var mouseYWorldPhys:Number;
  72.                 static public var mouseXWorld:Number;
  73.                 static public var mouseYWorld:Number;
  74.                 static public var prevMouseXWorld:Number;
  75.                 static public var prevMouseYWorld:Number;
  76.                 // Sprite to draw in to
  77.                 public var m_canvas:Sprite;
  78.                 public var m_buildAreas:Array = new Array();
  79.                 public var m_badBuildAreas:Array = new Array();
  80.                 public var m_selectedBuildAreas:Array = new Array();
  81.                 public var m_guiMenu:DropDownMenu;
  82.                 public var m_guiPanel:MainEditPanel;
  83.                 public var m_sidePanel:PartEditWindow;
  84.                 public var m_chooserWindow:SaveLoadWindow = null;
  85.                 public var m_loginWindow:LoginWindow = null;
  86.                 public var m_newUserWindow:NewUserWindow = null;
  87.                 public var m_scoreWindow:ScoreWindow = null;
  88.                 public var m_progressDialog:DialogWindow = null;
  89.                 public var m_linkDialog:LinkWindow = null;
  90.                 public var m_tutorialDialog:TutorialWindow = null;
  91.                 public var m_postReplayWindow:PostReplayWindow = null;
  92.                 public var m_rateDialog:RateWindow = null;
  93.                 public var m_restrictionsDialog:RestrictionsWindow = null;
  94.                 public var m_conditionsDialog:ConditionsWindow = null;
  95.                 public var m_sandboxWindow:AdvancedSandboxWindow = null;
  96.                 public var m_challengeWindow:ChooseChallengeWindow = null;
  97.                 public var m_reportWindow:ReportWindow = null;
  98.                 public var m_loadWindow:LoadWindow = null;
  99.                 public var m_exportDialog:ExportWindow = null;
  100.                 public var m_importDialog:ImportWindow = null;
  101.                 public var m_fader:Sprite;
  102.  
  103.                 public static var minDensity:Number = 0.01;
  104.                 public static var maxDensity:Number = 100;
  105.                 public static var maxRJStrength:Number = 100;
  106.                 public static var maxRJSpeed:Number = 100;
  107.                 public static var maxSJStrength:Number = 100;
  108.                 public static var maxSJSpeed:Number = 100;
  109.                 public static var maxThrusterStrength:Number = 100;
  110.                
  111.                 protected var hasPanned:Boolean = true;
  112.                 protected var hasZoomed:Boolean = true;
  113.                 protected var redrawBuildArea:Boolean = true;
  114.                 protected var redrawRobot:Boolean = true;
  115.                
  116.                 public var paused:Boolean = true;
  117.                 public var simStarted:Boolean = false;
  118.                 public var wonChallenge:Boolean = false;
  119.                 public var canSaveReplay:Boolean = true;
  120.                 protected var autoPanning:Boolean = true;
  121.                 protected var cameraPart:ShapePart = null;
  122.                
  123.                 public static var initX:Number = Number.MAX_VALUE;
  124.                 public static var initY:Number = Number.MAX_VALUE;
  125.                 public static var initZoom:Number = Number.MAX_VALUE;
  126.                
  127.                 public static var defaultR:Number = 150;
  128.                 public static var defaultG:Number = 150;
  129.                 public static var defaultB:Number = 150;
  130.                 public static var defaultO:Number = 255;
  131.                 public static var clickedBox:Boolean = false;
  132.                 public static var adStarted:Boolean = false;
  133.                 public static var snapToCenter:Boolean = true;
  134.                 public static var showJoints:Boolean = true;
  135.                 public static var showOutlines:Boolean = true;
  136.                 public static var showGraphics:Boolean = true;
  137.                 public static var showColours:Boolean = true;
  138.                 public static var centerOnSelected:Boolean = false;
  139.                 public static var failedChallenge:Boolean = false;
  140.                 public static var justLoadedRobotWithChallenge:Boolean = false;
  141.                 private var initRotatingAngle:Number;
  142.                 private var initDragX:Number;
  143.                 private var initDragY:Number;
  144.                 protected var curAction:int = -1;
  145.                 private var actionStep:int = 0;
  146.                 private var firstClickX:Number;
  147.                 private var firstClickY:Number;
  148.                 private var secondClickX:Number;
  149.                 private var secondClickY:Number;
  150.                 private var savedDrawXOff:Number;
  151.                 private var savedDrawYOff:Number;
  152.                 private var mostRecentScaleFactor:Number
  153.                
  154.                 public var draw:Draw;
  155.                
  156.                 public var sSky:Sky;
  157.                
  158.                 public var allParts:Array;
  159.                 public static var cannonballs:Array = null;
  160.                 public var actions:Array;
  161.                 public var cameraMovements:Array;
  162.                 public var keyPresses:Array;
  163.                 public var syncPoints:Array;
  164.                
  165.                 public var frameCounter:int;
  166.                 public var lastAction:int = -1;
  167.                 protected var partsFit:Boolean = true;
  168.                 private var draggingTutorial:Boolean = false;
  169.                 private var selectingCondition:Boolean = false;
  170.                 private var delayedSelection:Boolean = false;
  171.                 public var ignoreAClick:Boolean = false;
  172.                 public var backToSaveWindow:Boolean = false;
  173.                 public var clickedReport:Boolean = false;
  174.                 public var clickedSave:Boolean = false;
  175.                 public var clickedSaveReplay:Boolean = false;
  176.                 public var clickedSaveChallenge:Boolean = false;
  177.                 public var clickedSubmitScore:Boolean = false;
  178.                 public static var showTutorial:Boolean = true;
  179.                 private var redirectAfterRating:int = 0;
  180.                 public static var ratedCurRobot:Boolean = false;
  181.                 public static var ratedCurReplay:Boolean = false;
  182.                 public static var ratedCurChallenge:Boolean = false;
  183.                 public var saveAfterRestrictions:Boolean = false;
  184.  
  185.                 public static var loadAndInsert:Boolean = false;
  186.                 public static var potentialRobotID:String = "";
  187.                 public static var potentialRobotEditable:Boolean = false;
  188.                 public static var potentialRobotPublic:Boolean = false;
  189.                 public static var potentialRobotFeatured:Boolean = false;
  190.                 public static var potentialChallengeID:String = "";
  191.                 public static var potentialChallengeEditable:Boolean = false;
  192.                 public static var potentialChallengePublic:Boolean = false;
  193.                 public static var potentialChallengeFeatured:Boolean = false;
  194.                 public static var potentialReplayID:String = "";
  195.                 public static var potentialReplayPublic:Boolean = false;
  196.                 public static var potentialReplayFeatured:Boolean = false;
  197.                 public static var curRobotID:String = "";
  198.                 public static var curRobotEditable:Boolean = true;
  199.                 public static var curRobotPublic:Boolean = false;
  200.                 public static var curRobotFeatured:Boolean = false;
  201.                 public static var curChallengeID:String = "";
  202.                 public static var curChallengePublic:Boolean = false;
  203.                 public static var curChallengeFeatured:Boolean = false;
  204.                 public static var curReplayID:String = "";
  205.                 public static var curReplayPublic:Boolean = false;
  206.                 public static var curReplayFeatured:Boolean = false;
  207.                 public static var userName:String = "_Public";
  208.                 public static var password:String = "";
  209.                 public static var sessionID:String = "";
  210.  
  211.                 public var selectedParts:Array = new Array();
  212.                 public var selectedBuildArea:b2AABB;
  213.                 public var rotatingPart:Object = null;
  214.                 public var rotatingParts:Array = null;
  215.                 public var draggingPart:Part = null;
  216.                 public var draggingParts:Array = null;
  217.                 public static var clipboardParts:Array = new Array();
  218.                 public var jointPart:ShapePart = null;
  219.                 private var lastSelectedShape:ShapePart = null;
  220.                 private var lastSelectedJoint:JointPart = null;
  221.                 private var lastSelectedText:TextPart = null;
  222.                 private var lastSelectedThrusters:Thrusters = null;
  223.                 public var copiedJoint:JointPart = null;
  224.                 public var copiedThrusters:Thrusters = null;
  225.                 public static var replayParts:Array = new Array();
  226.                 public static var loadedParts:Array = null;
  227.                
  228.                 protected var removedGraphics:Array = new Array();
  229.                
  230.                 protected var uneditableText:TextField;
  231.                 protected var rotatingText:TextField;
  232.                 protected var scalingText:TextField;
  233.                 protected var boxText:TextField;
  234.                 protected var horizLineText:TextField;
  235.                 protected var vertLineText:TextField;
  236.                 protected var shapeText:TextField;
  237.                 private var newText:Object = null;
  238.                 private var oldText:String = "";
  239.                
  240.                 public var potentialJointPart1:ShapePart = null;
  241.                 public var potentialJointPart2:ShapePart = null;
  242.                 public var candidateJointX:Number;
  243.                 public var candidateJointY:Number;
  244.                 public var candidateJointType:int;
  245.                 public var candidateJointParts:Array;
  246.                
  247.                 public static var shapeSound1:Sound = new Resource.cShape1();
  248.                 public static var shapeSound2:Sound = new Resource.cShape2();
  249.                 public static var shapeSound3:Sound = new Resource.cShape3();
  250.                 public static var shapeSound4:Sound = new Resource.cShape4();
  251.                 public static var shapeSound5:Sound = new Resource.cShape5();
  252.                 public static var jointSound1:Sound = new Resource.cJoint1();
  253.                 public static var jointSound2:Sound = new Resource.cJoint2();
  254.                 public static var jointSound3:Sound = new Resource.cJoint3();
  255.                 public static var jointSound4:Sound = new Resource.cJoint4();
  256.                 public static var jointSound5:Sound = new Resource.cJoint5();
  257.                 public static var winSound:Sound = new Resource.cWin();
  258.                 public static var loseSound:Sound = new Resource.cLose();
  259.                 public static var channel:SoundChannel = null;
  260.                 public static var musicChannel:SoundChannel = null;
  261.                 public static var introVolume:Number = 0.5;
  262.                
  263.                 public static const NEW_CIRCLE:int = 0;
  264.                 public static const NEW_RECT:int = 1;
  265.                 public static const NEW_TRIANGLE:int = 2;
  266.                 public static const NEW_FIXED_JOINT:int = 3;
  267.                 public static const NEW_REVOLUTE_JOINT:int = 4;
  268.                 public static const NEW_PRISMATIC_JOINT:int = 5;
  269.                 public static const ROTATE:int = 6;
  270.                 public static const PASTE:int = 7;
  271.                 public static const BOX_SELECTING:int = 8;
  272.                 public static const FINALIZING_JOINT:int = 9;
  273.                 public static const NEW_TEXT:int = 10;
  274.                 public static const RESIZING_TEXT:int = 11;
  275.                 public static const RESIZING_SHAPES:int = 12;
  276.                 public static const NEW_THRUSTERS:int = 13;
  277.                 public static const DRAWING_BOX:int = 14;
  278.                 public static const DRAWING_HORIZONTAL_LINE:int = 15;
  279.                 public static const DRAWING_VERTICAL_LINE:int = 16;
  280.                 public static const SELECTING_SHAPE:int = 17;
  281.                 public static const DRAWING_BUILD_BOX:int = 18;
  282.                 public static const NEW_CANNON:int = 19;
  283.                
  284.                 public function ControllerGame() {
  285.                         allParts = new Array();
  286.                         cannonballs = new Array();
  287.                         actions = new Array();
  288.                        
  289.                         Input.m_currController = this;
  290.                         Action.m_controller = this;
  291.                        
  292.                         m_canvas = new Sprite();
  293.                         m_guiPanel = new MainEditPanel(this);
  294.                         m_guiMenu = new DropDownMenu(this);
  295.                         m_sidePanel = new PartEditWindow(this);
  296.  
  297.                         m_fader = new Sprite();
  298.                         m_fader.graphics.beginFill(0, 0.2);
  299.                         m_fader.graphics.lineStyle(0, 0, 0.2);
  300.                         m_fader.graphics.moveTo(0, 0);
  301.                         m_fader.graphics.lineTo(800, 0);
  302.                         m_fader.graphics.lineTo(800, 600);
  303.                         m_fader.graphics.lineTo(0, 600);
  304.                         m_fader.graphics.lineTo(0, 0);
  305.                         m_fader.graphics.endFill();
  306.                         m_fader.visible = false;
  307.  
  308.                         uneditableText = new TextField();
  309.                         uneditableText.x = 0;
  310.                         uneditableText.y = 102;
  311.                         uneditableText.width = 800;
  312.                         uneditableText.text = "The current robot is uneditable.  Some features, including saving and submitting scores, will be disabled.";
  313.                         uneditableText.selectable = false;
  314.                         uneditableText.visible = false;
  315.                         var format:TextFormat = new TextFormat();
  316.                         format.align = TextFormatAlign.CENTER;
  317.                         format.font = Main.GLOBAL_FONT;
  318.                         format.size = 12;
  319.                         uneditableText.setTextFormat(format);
  320.  
  321.                         rotatingText = new TextField();
  322.                         rotatingText.x = 0;
  323.                         rotatingText.y = 102;
  324.                         rotatingText.width = 800;
  325.                         rotatingText.text = "Move the mouse around to rotate the shape - hold shift to increment by 45 degrees, and click when you're done.";
  326.                         rotatingText.selectable = false;
  327.                         rotatingText.visible = false;
  328.                         rotatingText.setTextFormat(format);
  329.  
  330.                         scalingText = new TextField();
  331.                         scalingText.x = 0;
  332.                         scalingText.y = 102;
  333.                         scalingText.width = 800;
  334.                         scalingText.text = "Move the mouse to the right to increase the shape's size, and left to decrease it.";
  335.                         scalingText.selectable = false;
  336.                         scalingText.visible = false;
  337.                         scalingText.setTextFormat(format);
  338.  
  339.                         boxText = new TextField();
  340.                         boxText.x = 0;
  341.                         boxText.y = 102;
  342.                         boxText.width = 800;
  343.                         boxText.text = "Use the mouse to click and drag a box for the given condition.  You can use the arrow keys to scroll.";
  344.                         boxText.selectable = false;
  345.                         boxText.visible = false;
  346.                         boxText.setTextFormat(format);
  347.  
  348.                         horizLineText = new TextField();
  349.                         horizLineText.x = 0;
  350.                         horizLineText.y = 102;
  351.                         horizLineText.width = 800;
  352.                         horizLineText.text = "Use the mouse to draw a horizontal line for the given condition.  You can use the arrow keys to scroll.";
  353.                         horizLineText.selectable = false;
  354.                         horizLineText.visible = false;
  355.                         horizLineText.setTextFormat(format);
  356.  
  357.                         vertLineText = new TextField();
  358.                         vertLineText.x = 0;
  359.                         vertLineText.y = 102;
  360.                         vertLineText.width = 800;
  361.                         vertLineText.text = "Use the mouse to draw a vertical line for the given condition.  You can use the arrow keys to scroll.";
  362.                         vertLineText.selectable = false;
  363.                         vertLineText.visible = false;
  364.                         vertLineText.setTextFormat(format);
  365.  
  366.                         shapeText = new TextField();
  367.                         shapeText.x = 0;
  368.                         shapeText.y = 102;
  369.                         shapeText.width = 800;
  370.                         shapeText.text = "Select a shape for the given condition.  You can use the arrow keys to scroll.";
  371.                         shapeText.selectable = false;
  372.                         shapeText.visible = false;
  373.                         shapeText.setTextFormat(format);
  374.  
  375.                         // set debug draw
  376.                         draw = new Draw();
  377.                         draw.m_sprite = m_canvas;
  378.                         draw.m_drawScale = m_physScale;
  379.                         draw.m_drawYOff = -100;
  380.                         if (showColours) draw.m_fillAlpha = 1.0;
  381.                         else draw.m_fillAlpha = 0.5;
  382.                         draw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;
  383.  
  384.                         if (playingReplay) {
  385.                                 replay.cont = this;
  386.                         } else {
  387.                                 viewingUnsavedReplay = false;
  388.                         }
  389.                        
  390.                         addEventListener(Event.ADDED_TO_STAGE, Init);
  391.                 }
  392.                
  393.                 public virtual function Init(e:Event):void {
  394.                         addChild(m_canvas);
  395.                         addChild(uneditableText);
  396.                         addChild(rotatingText);
  397.                         addChild(scalingText);
  398.                         addChild(boxText);
  399.                         addChild(horizLineText);
  400.                         addChild(vertLineText);
  401.                         addChild(shapeText);
  402.                         addChild(m_guiPanel);
  403.                         addChild(m_sidePanel);
  404.                         addChild(m_guiMenu);
  405.                         addChild(m_fader);
  406.                         if (playingReplay) {
  407.                                 allParts = allParts.concat(replayParts);
  408.                                 for (var i:int = 0; i < allParts.length; i++) {
  409.                                         if (allParts[i] is TextPart) {
  410.                                                 var newTextPart:TextPart = new TextPart(this, allParts[i].x, allParts[i].y, allParts[i].w, allParts[i].h, allParts[i].text);
  411.                                                 newTextPart.alwaysVisible = allParts[i].alwaysVisible;
  412.                                                 newTextPart.displayKey = allParts[i].displayKey;
  413.                                                 newTextPart.red = allParts[i].red;
  414.                                                 newTextPart.green = allParts[i].green;
  415.                                                 newTextPart.blue = allParts[i].blue;
  416.                                                 newTextPart.size = allParts[i].size;
  417.                                                 allParts[i] = newTextPart;
  418.                                         }
  419.                                 }
  420.                         }
  421.                        
  422.                         if (loadedParts) {
  423.                                 if (this is ControllerChallenge && ControllerChallenge.playChallengeMode && !justLoadedRobotWithChallenge) {
  424.                                         for (i = 0; i < loadedParts.length; i++) {
  425.                                                 loadedParts[i].isEditable = false;
  426.                                         }
  427.                                 }
  428.                                 if (justLoadedRobotWithChallenge) {
  429.                                         allParts = allParts.concat(ControllerChallenge.challenge.allParts);
  430.                                         for (i = 0; i < allParts.length; i++) {
  431.                                                 allParts[i].isEditable = false;
  432.                                         }
  433.                                 }
  434.                                 justLoadedRobotWithChallenge = false;
  435.                                 allParts = allParts.concat(loadedParts);
  436.                                 for (i = 0; i < allParts.length; i++) {
  437.                                         if (allParts[i] is TextPart) {
  438.                                                 newTextPart = new TextPart(this, allParts[i].x, allParts[i].y, allParts[i].w, allParts[i].h, allParts[i].text);
  439.                                                 newTextPart.alwaysVisible = allParts[i].alwaysVisible;
  440.                                                 newTextPart.displayKey = allParts[i].displayKey;
  441.                                                 newTextPart.red = allParts[i].red;
  442.                                                 newTextPart.green = allParts[i].green;
  443.                                                 newTextPart.blue = allParts[i].blue;
  444.                                                 newTextPart.size = allParts[i].size;
  445.                                                 if (!allParts[i].isEditable) newTextPart.isEditable = false;
  446.                                                 allParts[i] = newTextPart;
  447.                                         }
  448.                                 }
  449.                                 loadedParts = null;
  450.                                 if (initX != Number.MAX_VALUE) {
  451.                                         draw.m_drawXOff = initX;
  452.                                         draw.m_drawYOff = initY;
  453.                                         m_physScale = initZoom;
  454.                                 } else if (!(this is ControllerChallenge)) {
  455.                                         CenterOnLoadedRobot();
  456.                                 }
  457.                         } else if (!playingReplay) {
  458.                                 curRobotID = "";
  459.                                 curRobotEditable = true;
  460.                                 curRobotPublic = false;
  461.                         }
  462.                        
  463.                         initX = Number.MAX_VALUE;
  464.                         initY = Number.MAX_VALUE;
  465.                         initZoom = Number.MAX_VALUE;
  466.                        
  467.                         if (this is ControllerChallenge) {
  468.                                 minDensity = (ControllerChallenge.challenge.minDensity == -Number.MAX_VALUE ? 1 : ControllerChallenge.challenge.minDensity);
  469.                                 maxDensity = (ControllerChallenge.challenge.maxDensity == Number.MAX_VALUE ? 30 : ControllerChallenge.challenge.maxDensity);
  470.                                 maxRJStrength = (ControllerChallenge.challenge.maxRJStrength == Number.MAX_VALUE ? 30 : ControllerChallenge.challenge.maxRJStrength);
  471.                                 maxRJSpeed = (ControllerChallenge.challenge.maxRJSpeed == Number.MAX_VALUE ? 30 : ControllerChallenge.challenge.maxRJSpeed);
  472.                                 maxSJStrength = (ControllerChallenge.challenge.maxSJStrength == Number.MAX_VALUE ? 30 : ControllerChallenge.challenge.maxSJStrength);
  473.                                 maxSJSpeed = (ControllerChallenge.challenge.maxSJSpeed == Number.MAX_VALUE ? 30 : ControllerChallenge.challenge.maxSJSpeed);
  474.                                 maxThrusterStrength = (ControllerChallenge.challenge.maxThrusterStrength == Number.MAX_VALUE ? 30 : ControllerChallenge.challenge.maxThrusterStrength);
  475.                         } else {
  476.                                 minDensity = 1;
  477.                                 maxDensity = 30;
  478.                                 maxRJStrength = 30;
  479.                                 maxRJSpeed = 30;
  480.                                 maxSJStrength = 30;
  481.                                 maxSJSpeed = 30;
  482.                                 maxThrusterStrength = 30;
  483.                         }
  484.                        
  485.                         PrismaticJoint.jbTutorial = false;
  486.                        
  487.                         if (Main.inIFrame) {
  488.                                 curRobotEditable = false;
  489.                                 uneditableText.text = "";
  490.                         }
  491.                 }
  492.                
  493.                 public function BuildBuildArea():void {
  494.                         for (var i:int = 0; i < m_buildAreas.length; i++) {
  495.                                 removeChild(m_buildAreas[i]);
  496.                                 removeChild(m_badBuildAreas[i]);
  497.                                 removeChild(m_selectedBuildAreas[i]);
  498.                         }
  499.                         m_buildAreas = new Array();
  500.                         m_badBuildAreas = new Array();
  501.                         m_selectedBuildAreas = new Array();
  502.                        
  503.                         var childIndex:int = sSky.lastCloudIndex + 1;
  504.                         for (i = 0; i < NumBuildingAreas(); i++) {
  505.                                 var m_buildArea:Sprite = new Sprite();
  506.                                 m_buildArea.graphics.lineStyle(6, 0xDEB05D);
  507.                                 var m:Matrix = new Matrix();
  508.                                 m.createGradientBox(700, 550, Math.PI / 2);
  509.                                 m_buildArea.graphics.beginGradientFill(GradientType.LINEAR, [0xFF8F17, 0xFFC150], [0.15, 0.15], [0, 255], m);
  510.                                 m_buildArea.graphics.drawRect(0, 0, 700, 550);
  511.                                 m_buildArea.graphics.endFill();
  512.                                 addChildAt(m_buildArea, childIndex);
  513.                                 m_buildAreas.push(m_buildArea);
  514.                                 var m_badBuildArea:Sprite = new Sprite();
  515.                                 m_badBuildArea.graphics.lineStyle(6, 0xDE6A5D);
  516.                                 m = new Matrix();
  517.                                 m.createGradientBox(700, 550, Math.PI / 2);
  518.                                 m_badBuildArea.graphics.beginGradientFill(GradientType.LINEAR, [0xFF4D17, 0xFF8F50], [0.15, 0.15], [0, 255], m);
  519.                                 m_badBuildArea.graphics.drawRect(0, 0, 700, 550);
  520.                                 m_badBuildArea.graphics.endFill();
  521.                                 addChildAt(m_badBuildArea, childIndex);
  522.                                 m_badBuildAreas.push(m_badBuildArea);
  523.                                 var m_selectedBuildArea:Sprite = new Sprite();
  524.                                 m_selectedBuildArea.graphics.lineStyle(6, 0xFECA5D);
  525.                                 m = new Matrix();
  526.                                 m.createGradientBox(700, 550, Math.PI / 2);
  527.                                 m_selectedBuildArea.graphics.beginGradientFill(GradientType.LINEAR, [0xFF4D17, 0xFF8F50], [0.15, 0.15], [0, 255], m);
  528.                                 m_selectedBuildArea.graphics.drawRect(0, 0, 700, 550);
  529.                                 m_selectedBuildArea.graphics.endFill();
  530.                                 addChildAt(m_selectedBuildArea, childIndex);
  531.                                 m_selectedBuildAreas.push(m_selectedBuildArea);
  532.                         }
  533.                 }
  534.                
  535.                 public function PlayShapeSound():void {
  536.                         if (Main.enableSound) {
  537.                                 var soundNum:int = int(Util.RangedRandom(0, 5));
  538.                                 var sound:Sound = (soundNum == 0 ? shapeSound1 : (soundNum == 1 ? shapeSound2 : (soundNum == 2 ? shapeSound3 : (soundNum == 3 ? shapeSound4 : shapeSound5))));
  539.                                 channel = sound.play();
  540.                                 var st:SoundTransform = new SoundTransform(0.7);
  541.                                 channel.soundTransform = st;
  542.                         }
  543.                 }
  544.                
  545.                 public function PlayJointSound():void {
  546.                         if (Main.enableSound) {
  547.                                 var soundNum:int = int(Util.RangedRandom(0, 5));
  548.                                 var sound:Sound = (soundNum == 0 ? jointSound1 : (soundNum == 1 ? jointSound2 : (soundNum == 2 ? jointSound3 : (soundNum == 3 ? jointSound4 : jointSound5))));
  549.                                 channel = sound.play();
  550.                                 var st:SoundTransform = new SoundTransform(0.7);
  551.                                 channel.soundTransform = st;
  552.                         }
  553.                 }
  554.                
  555.                 public override function GetPhysScale():Number {
  556.                         return m_physScale;
  557.                 }
  558.                
  559.                 public virtual override function GetMinX():Number {
  560.                         return -Number.MAX_VALUE;
  561.                 }
  562.                
  563.                 public virtual override function GetMaxX():Number {
  564.                         return Number.MAX_VALUE;
  565.                 }
  566.                
  567.                 public virtual override function GetMinY():Number {
  568.                         return -Number.MAX_VALUE;
  569.                 }
  570.                
  571.                 public virtual override function GetMaxY():Number {
  572.                         return Number.MAX_VALUE;
  573.                 }
  574.                
  575.                 public virtual override function Update():void {
  576.                         if (ControllerMainMenu.channel) {
  577.                                 introVolume -= 0.005;
  578.                                 var st:SoundTransform = new SoundTransform(introVolume);
  579.                                 ControllerMainMenu.channel.soundTransform = st;
  580.                                 if (introVolume <= 0) {
  581.                                         ControllerMainMenu.channel.stop();
  582.                                         ControllerMainMenu.channel = null;
  583.                                 }
  584.                         }
  585.                        
  586.                         if (!m_fader.visible) {
  587.                                 if (showColours) draw.m_fillAlpha = 1.0;
  588.                                 else draw.m_fillAlpha = 0.5;
  589.                                
  590.                                 if (playingReplay && !simStarted) playButton(new MouseEvent(""));
  591.                                
  592.                                 // update mouse position
  593.                                 mouseXWorldPhys = ((Input.mouseX) + draw.m_drawXOff)/m_physScale;
  594.                                 mouseYWorldPhys = ((Input.mouseY) + draw.m_drawYOff)/m_physScale;
  595.                                 prevMouseXWorld = mouseXWorld;
  596.                                 prevMouseYWorld = mouseYWorld;
  597.                                 mouseXWorld = (Input.mouseX);
  598.                                 mouseYWorld = (Input.mouseY);
  599.  
  600.                                 Main.ShowMouse();
  601.  
  602.                                 if (!paused && autoPanning) {
  603.                                         HandleCamera();
  604.                                 }
  605.  
  606.                                 MouseDrag();
  607.                                 HandleKey();
  608.  
  609.                                 for (var i:int = 0; i < allParts.length; i++) {
  610.                                         if (allParts[i] is RevoluteJoint || allParts[i] is PrismaticJoint) allParts[i].CheckForBreakage(m_world);
  611.                                 }
  612.  
  613.                                 m_guiMenu.Update();
  614.                                 m_guiPanel.Update(curAction);
  615.  
  616.                                 uneditableText.visible = (!curRobotEditable && !playingReplay && !simStarted);
  617.                                 rotatingText.visible = (curAction == ROTATE);
  618.                                 scalingText.visible = (curAction == RESIZING_SHAPES);
  619.  
  620.                                 if (newText && lastSelectedText is TextPart) {
  621.                                         lastSelectedText.text = newText.text;
  622.                                         lastSelectedText.m_textField.text = newText.text;
  623.                                         newText = null;
  624.                                 }
  625.  
  626.                                 // Update physics
  627.                                 var physStart:uint = getTimer();
  628.                                 if (!paused) {
  629.                                         if (!playingReplay) {
  630.                                                 if (frameCounter % REPLAY_SYNC_FRAMES == 0) AddSyncPoint();
  631.                                                 m_world.Step(1/60, 5);
  632.                                                 m_world.Step(1/60, m_iterations);
  633.                                         }
  634.                                         frameCounter++;
  635.                                         m_guiPanel.SetTimer(frameCounter);
  636.                                        
  637.                                         if (frameCounter >= 9000 || cannonballs.length > 500) canSaveReplay = false;
  638.                                 }
  639.                         }
  640.  
  641.                         draw.m_drawScale = m_physScale;
  642.                         draw.drawColours = showColours;
  643.                         if (!simStarted) {
  644.                                 for (i = 0; i < m_buildAreas.length; i++) {
  645.                                         var box:b2AABB = GetBuildingAreaNumber(i);
  646.                                         if (hasPanned || hasZoomed || redrawBuildArea) {
  647.                                                 m_buildAreas[i].x = World2ScreenX(box.lowerBound.x);
  648.                                                 m_buildAreas[i].y = World2ScreenY(box.lowerBound.y);
  649.                                                 m_badBuildAreas[i].x = World2ScreenX(box.lowerBound.x);
  650.                                                 m_badBuildAreas[i].y = World2ScreenY(box.lowerBound.y);
  651.                                                 m_selectedBuildAreas[i].x = World2ScreenX(box.lowerBound.x);
  652.                                                 m_selectedBuildAreas[i].y = World2ScreenY(box.lowerBound.y);
  653.                                         }
  654.                                         if (hasZoomed || redrawBuildArea) {
  655.                                                 m_buildAreas[i].width = World2ScreenX(box.upperBound.x) - World2ScreenX(box.lowerBound.x);
  656.                                                 m_buildAreas[i].height = World2ScreenY(box.upperBound.y) - World2ScreenY(box.lowerBound.y);
  657.                                                 m_badBuildAreas[i].width = World2ScreenX(box.upperBound.x) - World2ScreenX(box.lowerBound.x);
  658.                                                 m_badBuildAreas[i].height = World2ScreenY(box.upperBound.y) - World2ScreenY(box.lowerBound.y);
  659.                                                 m_selectedBuildAreas[i].width = World2ScreenX(box.upperBound.x) - World2ScreenX(box.lowerBound.x);
  660.                                                 m_selectedBuildAreas[i].height = World2ScreenY(box.upperBound.y) - World2ScreenY(box.lowerBound.y);
  661.                                         }
  662.                                         m_selectedBuildAreas[i].visible = (m_sidePanel.BuildWindowShowing() && selectedBuildArea == ControllerChallenge.challenge.buildAreas[i]);
  663.                                         m_buildAreas[i].visible = (!m_selectedBuildAreas[i].visible && partsFit);
  664.                                         m_badBuildAreas[i].visible = (!m_selectedBuildAreas[i].visible && !partsFit);
  665.                                 }
  666.                                 redrawBuildArea = false;
  667.                         } else {
  668.                                 for (i = 0; i < m_buildAreas.length; i++) {
  669.                                         m_buildAreas[i].visible = false;
  670.                                         m_badBuildAreas[i].visible = false;
  671.                                         m_selectedBuildAreas[i].visible = false;
  672.                                 }
  673.                         }
  674.                         if (hasPanned || hasZoomed || !paused || draggingPart || curAction != -1 || redrawRobot) {
  675.                                 m_canvas.graphics.clear();
  676.                                 draw.DrawWorld(allParts, selectedParts, m_world, !simStarted, false, showJoints, showOutlines, ((this is ControllerChallenge) ? ControllerChallenge.challenge : null));
  677.                                 redrawRobot = false;
  678.                         }
  679.                         var snapPart:ShapePart = FindPartToSnapTo();
  680.                         if (!simStarted) {
  681.                                 if (snapToCenter && snapPart && (curAction == NEW_FIXED_JOINT || curAction == NEW_REVOLUTE_JOINT || curAction == NEW_PRISMATIC_JOINT || curAction == NEW_THRUSTERS)) {
  682.                                         draw.DrawTempShape(curAction, actionStep, firstClickX, firstClickY, secondClickX, secondClickY, snapPart.centerX, snapPart.centerY);
  683.                                 } else if (curAction == FINALIZING_JOINT && candidateJointType == NEW_PRISMATIC_JOINT && actionStep == 1) {
  684.                                         draw.DrawTempShape(NEW_PRISMATIC_JOINT, actionStep, firstClickX, firstClickY, secondClickX, secondClickY, candidateJointX, candidateJointY);
  685.                                 } else if (curAction == FINALIZING_JOINT && candidateJointType == NEW_THRUSTERS) {
  686.                                         draw.DrawTempShape(NEW_THRUSTERS, actionStep, firstClickX, firstClickY, secondClickX, secondClickY, candidateJointX, candidateJointY);
  687.                                 } else if (curAction == FINALIZING_JOINT) {
  688.                                         draw.DrawTempShape(curAction, actionStep, firstClickX, firstClickY, secondClickX, secondClickY, candidateJointX, candidateJointY);
  689.                                 } else {
  690.                                         draw.DrawTempShape(curAction, actionStep, firstClickX, firstClickY, secondClickX, secondClickY, mouseXWorldPhys, mouseYWorldPhys);
  691.                                 }
  692.                         }
  693.                        
  694.                         //Main.m_fpsCounter.updatePhys(physStart);
  695.                        
  696.                         if (Database.errorOccurred) {
  697.                                 m_progressDialog.StopTimer();
  698.                                 m_progressDialog.SetMessage(Database.lastErrorMsg, true);
  699.                                 Database.errorOccurred = false;
  700.                                 if (Database.versionErrorOccurred) {
  701.                                         Database.versionErrorOccurred = false;
  702.                                         m_progressDialog.ShowOKAndCancelButton(5);
  703.                                 } else {
  704.                                         m_progressDialog.ShowOKButton();
  705.                                 }
  706.                                 removeChild(m_progressDialog);
  707.                                 addChild(m_progressDialog);
  708.                                 Main.ShowMouse();
  709.                         }
  710.                        
  711.                         if (!paused && ChallengeOver()) {
  712.                                 wonChallenge = true;
  713.                                 pauseButton(new MouseEvent(""));
  714.                                 if (!playingReplay || viewingUnsavedReplay) {
  715.                                         m_fader.visible = true;
  716.                                         if (this is ControllerTutorial || WonChallenge()) {
  717.                                                 if (m_scoreWindow) {
  718.                                                         try {
  719.                                                                 removeChild(m_scoreWindow);
  720.                                                         } catch (type:Error) {
  721.                                                                
  722.                                                         }
  723.                                                 }
  724.                                                 m_scoreWindow = new ScoreWindow(this, GetScore());
  725.                                                 if (Main.enableSound) {
  726.                                                         musicChannel = winSound.play();
  727.                                                         st = new SoundTransform(0.5);
  728.                                                         musicChannel.soundTransform = st;
  729.                                                 }
  730.                                                 addChild(m_scoreWindow);
  731.                                                 if (this is ControllerTutorial) {
  732.                                                         LSOManager.SetLevelDone(Main.nextControllerType - 10);
  733.                                                 } else if (this is ControllerMonkeyBars || this is ControllerClimb || this is ControllerRace || this is ControllerSpaceship) {
  734.                                                         LSOManager.SetLevelDone(Main.nextControllerType + 8);
  735.                                                 }
  736.                                         } else {
  737.                                                 failedChallenge = true;
  738.                                                 ShowDialog3("Sorry, you have failed this challenge!");
  739.                                                 m_progressDialog.ShowOKButton();
  740.                                                 m_progressDialog.StopTimer();
  741.                                                 if (Main.enableSound) {
  742.                                                         musicChannel = loseSound.play();
  743.                                                         st = new SoundTransform(0.5);
  744.                                                         musicChannel.soundTransform = st;
  745.                                                 }
  746.                                         }
  747.                                 }
  748.                         }                      
  749.                 }
  750.                
  751.                 public override function MoveCameraForReplay(cameraMovement:Object):void {
  752.                         if (cameraMovement.x != Number.POSITIVE_INFINITY) {
  753.                                 var oldX:Number = draw.m_drawXOff;
  754.                                 var oldY:Number = draw.m_drawYOff;
  755.                                 draw.m_drawXOff = cameraMovement.x;
  756.                                 draw.m_drawYOff = cameraMovement.y;
  757.                                 autoPanning = false;
  758.                                 if (oldX != draw.m_drawXOff || oldY != draw.m_drawYOff) hasPanned = true;
  759.                         }
  760.                         var oldScale:Number = m_physScale;
  761.                         m_physScale = cameraMovement.scale;
  762.                         if (m_physScale != oldScale) hasZoomed = true;
  763.                         if (autoPanning) HandleCamera();
  764.                 }
  765.                
  766.                 public function AddSyncPoint():void  {
  767.                         if (syncPoints.length == 0 || frameCounter != syncPoints[syncPoints.length - 1].frame) {
  768.                                 var bodiesUsed:Array = new Array();
  769.                                 var syncPoint:ReplaySyncPoint = new ReplaySyncPoint();
  770.                                 syncPoint.frame = frameCounter;
  771.                                 for (var i:int = 0; i < allParts.length; i++) {
  772.                                         if (allParts[i] is ShapePart && !allParts[i].isStatic && !Util.ObjectInArray(allParts[i].GetBody(), bodiesUsed)) {
  773.                                                 syncPoint.positions.push(Util.Vector(allParts[i].GetBody().GetPosition().x, allParts[i].GetBody().GetPosition().y));
  774.                                                 syncPoint.angles.push(allParts[i].GetBody().GetAngle());
  775.                                                 bodiesUsed.push(allParts[i].GetBody());
  776.                                         }
  777.                                 }
  778.                                 for (i = 0; i < cannonballs.length; i++) {
  779.                                         syncPoint.cannonballPositions.push(Util.Vector(cannonballs[i].GetPosition().x, cannonballs[i].GetPosition().y));
  780.                                 }
  781.                                 syncPoints.push(syncPoint);
  782.                         }
  783.                 }
  784.                
  785.                 private function ComputeReplaySplines(type:int):Array {
  786.                         // Compute the h and b
  787.                         var h:Array = new Array();
  788.                         var b:Array = new Array();
  789.                         for (var i:int = 0; i < replay.syncPoints.length - 1; i++) {
  790.                                 h.push(replay.syncPoints[i + 1].frame - replay.syncPoints[i].frame);
  791.                                 var inner:Array = new Array();
  792.                                 for (var j:int = 0; j < replay.syncPoints[0].positions.length; j++) {
  793.                                         if (type == 0) inner.push((replay.syncPoints[i + 1].positions[j].x - replay.syncPoints[i].positions[j].x) / h[i]);
  794.                                         else if (type == 1) inner.push((replay.syncPoints[i + 1].positions[j].y - replay.syncPoints[i].positions[j].y) / h[i]);
  795.                                         else {
  796.                                                 var deltaAngle:Number = replay.syncPoints[i + 1].angles[j] - replay.syncPoints[i].angles[j];
  797.                                                 if (Math.abs(deltaAngle) > 20) {
  798.                                                         var a1:Number = Util.NormalizeAngle(replay.syncPoints[i].angles[j]);
  799.                                                         var a2:Number = Util.NormalizeAngle(replay.syncPoints[i + 1].angles[j]);
  800.                                                         if (Math.abs(a1 - a2) < Math.PI) {
  801.                                                                 deltaAngle = a2 - a1;
  802.                                                         } else if (a1 > a2) {
  803.                                                                 deltaAngle = a2 + 2 * Math.PI - a1;
  804.                                                         } else {
  805.                                                                 deltaAngle = a2 - (a1 + 2 * Math.PI);
  806.                                                         }
  807.                                                 }
  808.                                                 inner.push(deltaAngle / h[i]);
  809.                                         }
  810.                                 }
  811.                                 b.push(inner);
  812.                         }
  813.  
  814.                         // Gaussian Elimination
  815.                         var u:Array = new Array();
  816.                         var v:Array = new Array();
  817.                         u.push(0);
  818.                         u.push(2 * (h[0] + h[1]));
  819.                         inner = new Array();
  820.                         for (j = 0; j < replay.syncPoints[0].positions.length; j++) {
  821.                                 inner.push(0);
  822.                         }
  823.                         v.push(inner);
  824.                         inner = new Array();
  825.                         for (j = 0; j < replay.syncPoints[0].positions.length; j++) {
  826.                                 if (b.length < 2) inner.push(0);
  827.                                 else inner.push(6 * (b[1][j] - b[0][j]));
  828.                         }
  829.                         v.push(inner);
  830.                         for (i = 2; i < replay.syncPoints.length - 1; i++) {
  831.                                 u.push(2 * (h[i - 1] + h[i]) - h[i - 1] * h[i - 1] / u[i - 1]);
  832.                                 inner = new Array();
  833.                                 for (j = 0; j < replay.syncPoints[0].positions.length; j++) {
  834.                                         inner.push(6 * (b[i][j] - b[i - 1][j]) - h[i - 1] * v[i - 1][j] / u[i - 1]);
  835.                                 }
  836.                                 v.push(inner);
  837.                         }
  838.  
  839.                         // Back-substitution
  840.                         var z:Array = new Array();
  841.                         inner = new Array();
  842.                         for (j = 0; j < replay.syncPoints[0].positions.length; j++) {
  843.                                 inner.push(0);
  844.                         }
  845.                         z[replay.syncPoints.length - 1] = inner;
  846.                         for (i = replay.syncPoints.length - 2; i > 0; i--) {
  847.                                 inner = new Array();
  848.                                 for (j = 0; j < replay.syncPoints[0].positions.length; j++) {
  849.                                         inner.push((v[i][j] - h[i] * z[i + 1][j]) / u[i]);
  850.                                 }
  851.                                 z[i] = inner;
  852.                         }
  853.                         inner = new Array();
  854.                         for (j = 0; j < replay.syncPoints[0].positions.length; j++) {
  855.                                 inner.push(0);
  856.                         }
  857.                         z[0] = inner;
  858.                        
  859.                         var S:Array = new Array();
  860.                         var As:Array = new Array();
  861.                         var Bs:Array = new Array();
  862.                         var Cs:Array = new Array();
  863.                         var Ds:Array = new Array();
  864.                         for (i = 0; i < replay.syncPoints.length - 1; i++) {
  865.                                 var innerA:Array = new Array();
  866.                                 var innerB:Array = new Array();
  867.                                 var innerC:Array = new Array();
  868.                                 var innerD:Array = new Array();
  869.                                 for (j = 0; j < replay.syncPoints[0].positions.length; j++) {
  870.                                         innerA.push(type == 0 ? replay.syncPoints[i].positions[j].x : (type == 1 ? replay.syncPoints[i].positions[j].y : replay.syncPoints[i].angles[j]));
  871.                                         deltaAngle = replay.syncPoints[i + 1].angles[j] - replay.syncPoints[i].angles[j];
  872.                                         if (Math.abs(deltaAngle) > 20) {
  873.                                                 a1 = Util.NormalizeAngle(replay.syncPoints[i].angles[j]);
  874.                                                 a2 = Util.NormalizeAngle(replay.syncPoints[i + 1].angles[j]);
  875.                                                 if (Math.abs(a1 - a2) < Math.PI) {
  876.                                                         deltaAngle = a2 - a1;
  877.                                                 } else if (a1 > a2) {
  878.                                                         deltaAngle = a2 + 2 * Math.PI - a1;
  879.                                                 } else {
  880.                                                         deltaAngle = a2 - (a1 + 2 * Math.PI);
  881.                                                 }
  882.                                         }
  883.                                         innerB.push(-h[i] * z[i + 1][j] / 6 - h[i] * z[i][j] / 3 + (type == 0 ? replay.syncPoints[i + 1].positions[j].x - innerA[j] : (type == 1 ? replay.syncPoints[i + 1].positions[j].y - innerA[j] : deltaAngle)) / h[i]);
  884.                                         innerC.push(z[i][j] / 2);
  885.                                         innerD.push((z[i + 1][j] - z[i][j]) / (6 * h[i]));
  886.                                 }
  887.                                 As.push(innerA);
  888.                                 Bs.push(innerB);
  889.                                 Cs.push(innerC);
  890.                                 Ds.push(innerD);
  891.                         }
  892.                         S.push(As);
  893.                         S.push(Bs);
  894.                         S.push(Cs);
  895.                         S.push(Ds);
  896.                         return S;
  897.                 }
  898.                
  899.                 public override function SyncReplay(syncPoint:Object):void {
  900.                         var bodiesUsed:Array = new Array();
  901.                         var curIndex:int = 0;
  902.                         for (var i:int = 0; i < allParts.length; i++) {
  903.                                 if (allParts[i] is ShapePart && !allParts[i].isStatic && !Util.ObjectInArray(allParts[i].GetBody(), bodiesUsed)) {
  904.                                         allParts[i].GetBody().SetXForm(syncPoint.positions[curIndex], syncPoint.angles[curIndex]);
  905.                                         curIndex++;
  906.                                         bodiesUsed.push(allParts[i].GetBody());
  907.                                 }
  908.                         }
  909.                         for (i = 0; i < cannonballs.length; i++) {
  910.                                 cannonballs[i].SetXForm(syncPoint.cannonballPositions[i], 0);
  911.                         }
  912.                 }
  913.  
  914.                 public override function SyncReplay2(syncPoint1:Object, syncPoint2:Object):void {
  915.                         var syncPointIndex:int = replay.syncPoints.indexOf(syncPoint1);
  916.                         var bodiesUsed:Array = new Array();
  917.                         var curIndex:int = 0;
  918.                         for (var i:int = 0; i < allParts.length; i++) {
  919.                                 if (allParts[i] is ShapePart && !allParts[i].isStatic && !Util.ObjectInArray(allParts[i].GetBody(), bodiesUsed)) {
  920.                                         var x:Number = replaySplineXs[0][syncPointIndex][curIndex] + (frameCounter - syncPoint1.frame) * (replaySplineXs[1][syncPointIndex][curIndex] + (frameCounter - syncPoint1.frame) * (replaySplineXs[2][syncPointIndex][curIndex] + (frameCounter - syncPoint1.frame) * replaySplineXs[3][syncPointIndex][curIndex]));
  921.                                         var y:Number = replaySplineYs[0][syncPointIndex][curIndex] + (frameCounter - syncPoint1.frame) * (replaySplineYs[1][syncPointIndex][curIndex] + (frameCounter - syncPoint1.frame) * (replaySplineYs[2][syncPointIndex][curIndex] + (frameCounter - syncPoint1.frame) * replaySplineYs[3][syncPointIndex][curIndex]));
  922.                                         var angle:Number = replaySplineAngles[0][syncPointIndex][curIndex] + (frameCounter - syncPoint1.frame) * (replaySplineAngles[1][syncPointIndex][curIndex] + (frameCounter - syncPoint1.frame) * (replaySplineAngles[2][syncPointIndex][curIndex] + (frameCounter - syncPoint1.frame) * replaySplineAngles[3][syncPointIndex][curIndex]));
  923.                                         allParts[i].GetBody().SetXForm(Util.Vector(x, y), angle);
  924.                                         curIndex++;
  925.                                         bodiesUsed.push(allParts[i].GetBody());
  926.                                 }
  927.                         }
  928.                         for (i = 0; i < cannonballs.length; i++) {
  929.                                 if (syncPoint1.cannonballPositions.length > i) {
  930.                                         var frameDiff:int = syncPoint2.frame - syncPoint1.frame;
  931.                                         var newX:Number = (syncPoint1.cannonballPositions[i].x * (syncPoint2.frame - frameCounter) + syncPoint2.cannonballPositions[i].x * (frameCounter - syncPoint1.frame)) / frameDiff;
  932.                                         var newY:Number = (syncPoint1.cannonballPositions[i].y * (syncPoint2.frame - frameCounter) + syncPoint2.cannonballPositions[i].y * (frameCounter - syncPoint1.frame)) / frameDiff;
  933.                                         cannonballs[i].SetXForm(Util.Vector(newX, newY), 0);
  934.                                 } else {
  935.                                         cannonballs[i].SetXForm(syncPoint2.cannonballPositions[i], 0);
  936.                                 }
  937.                         }
  938.                 }
  939.  
  940.                 public override function IsPaused():Boolean {
  941.                         return paused;
  942.                 }
  943.                
  944.                 public override function World2ScreenX(x:Number):Number {
  945.                         return x * m_physScale - draw.m_drawXOff;
  946.                 }
  947.                
  948.                 public override function World2ScreenY(y:Number):Number {
  949.                         return y * m_physScale - draw.m_drawYOff;
  950.                 }
  951.                
  952.                 public function Screen2WorldX(x:Number):Number {
  953.                         return (x + draw.m_drawXOff) / m_physScale;
  954.                 }
  955.                
  956.                 public function Screen2WorldY(y:Number):Number {
  957.                         return (y + draw.m_drawYOff) / m_physScale;
  958.                 }
  959.                
  960.                 protected virtual function ChallengeOver():Boolean {
  961.                         throw new IllegalOperationError("abstract function ControllerGame.ChallengeOver() called");
  962.                 }
  963.                
  964.                 protected virtual function WonChallenge():Boolean {
  965.                         return false;
  966.                 }
  967.                
  968.                 protected virtual function LostChallenge():Boolean {
  969.                         return false;
  970.                 }
  971.                
  972.                 public virtual function GetScore():int {
  973.                         throw new IllegalOperationError("abstract function ControllerGame.GetScore() called");
  974.                 }
  975.                
  976.                 public virtual function ContactAdded(point:b2ContactPoint):void {
  977.                        
  978.                 }
  979.                
  980.                 protected virtual function GetBuildingArea():b2AABB {
  981.                         throw new IllegalOperationError("abstract function ControllerGame.GetBuildingArea() called");
  982.                 }
  983.                
  984.                 protected virtual function GetBuildingAreaNumber(i:int):b2AABB {
  985.                         return GetBuildingArea();
  986.                 }
  987.                
  988.                 protected virtual function NumBuildingAreas():int {
  989.                         return 1;
  990.                 }
  991.                
  992.                 public function GetBoxForConditions():void {
  993.                         boxText.visible = true;
  994.                         curAction = DRAWING_BOX;
  995.                         actionStep = 0;
  996.                         selectingCondition = true;
  997.                 }
  998.                
  999.                 public function GetHorizontalLineForConditions():void {
  1000.                         horizLineText.visible = true;
  1001.                         curAction = DRAWING_HORIZONTAL_LINE;
  1002.                         actionStep = 0;
  1003.                         selectingCondition = true;
  1004.                 }
  1005.                
  1006.                 public function GetVerticalLineForConditions():void {
  1007.                         vertLineText.visible = true;
  1008.                         curAction = DRAWING_VERTICAL_LINE;
  1009.                         actionStep = 0;
  1010.                         selectingCondition = true;
  1011.                 }
  1012.                
  1013.                 public function GetShapeForConditions():void {
  1014.                         if (!m_conditionsDialog.shape1) selectedParts = new Array();
  1015.                         shapeText.visible = true;
  1016.                         curAction = SELECTING_SHAPE;
  1017.                         selectingCondition = true;
  1018.                 }
  1019.                
  1020.                 protected function CheckIfPartsFit():void {
  1021.                         var partsToCheck:Array = allParts.filter(PartIsEditable);
  1022.                         var numAreas:int = NumBuildingAreas();
  1023.                        
  1024.                         partsFit = true;
  1025.                        
  1026.                         if (this is ControllerSandbox && !(this is ControllerChallenge)) return;
  1027.                         if (this is ControllerChallenge && !ControllerChallenge.playChallengeMode) return;
  1028.                         if (numAreas == 0) return;
  1029.                        
  1030.                         // Make sure the parts fit in the allowed building area
  1031.                         var minX:Number;
  1032.                         var maxX:Number;
  1033.                         var minY:Number;
  1034.                         var maxY:Number;
  1035.                         for (var i:int = 0; i < partsToCheck.length; i++) {
  1036.                                 var partFits:Boolean = false;
  1037.                                 for (var j:int = 0; j < numAreas; j++) {
  1038.                                         var buildingArea:b2AABB = GetBuildingAreaNumber(j);
  1039.                                         if (partsToCheck[i] is Circle) {
  1040.                                                 minX = partsToCheck[i].centerX - partsToCheck[i].radius;
  1041.                                                 maxX = partsToCheck[i].centerX + partsToCheck[i].radius;
  1042.                                                 minY = partsToCheck[i].centerY - partsToCheck[i].radius;
  1043.                                                 maxY = partsToCheck[i].centerY + partsToCheck[i].radius;
  1044.                                         } else if (partsToCheck[i] is Rectangle || partsToCheck[i] is Triangle || partsToCheck[i] is Cannon) {
  1045.                                                 var verts:Array = partsToCheck[i].GetVertices();
  1046.                                                 minX = Number.MAX_VALUE;
  1047.                                                 minY = Number.MAX_VALUE;
  1048.                                                 maxX = -Number.MAX_VALUE;
  1049.                                                 maxY = -Number.MAX_VALUE;
  1050.                                                 for (var k:int = 0; k < verts.length; k++) {
  1051.                                                         minX = Math.min(minX, verts[k].x);
  1052.                                                         maxX = Math.max(maxX, verts[k].x);
  1053.                                                         minY = Math.min(minY, verts[k].y);
  1054.                                                         maxY = Math.max(maxY, verts[k].y);
  1055.                                                 }
  1056.                                         } else {
  1057.                                                 minX = Number.MAX_VALUE;
  1058.                                                 minY = Number.MAX_VALUE;
  1059.                                                 maxX = -Number.MAX_VALUE;
  1060.                                                 maxY = -Number.MAX_VALUE;
  1061.                                         }
  1062.                                         if (minX >= buildingArea.lowerBound.x && minY >= buildingArea.lowerBound.y && maxX < buildingArea.upperBound.x && maxY < buildingArea.upperBound.y) {
  1063.                                                 partFits = true;
  1064.                                                 break;
  1065.                                         }
  1066.                                 }
  1067.                                 if (!partFits) {
  1068.                                         partsFit = false;
  1069.                                         break;
  1070.                                 }
  1071.                         }
  1072.                 }
  1073.                
  1074.                 protected virtual function HandleKey():void {
  1075.                         // keyboard input for motors/pistons
  1076.                         if (!paused) {
  1077.                                 if (playingReplay) {
  1078.                                         if (replay.Update(frameCounter)) {
  1079.                                                 pauseButton(new MouseEvent(""));
  1080.                                         }
  1081.                                 }
  1082.                                 for (var i:int = 0; i < allParts.length; i++) {
  1083.                                         allParts[i].Update(m_world);
  1084.                                 }
  1085.                         } else if (!simStarted && !m_sidePanel.EnteringInput()) {
  1086.                                 if (Input.isKeyDown(37)) {
  1087.                                         draw.m_drawXOff -= 10;
  1088.                                         hasPanned = true;
  1089.                                 }
  1090.                                 if (Input.isKeyDown(39)) {
  1091.                                         draw.m_drawXOff += 10;
  1092.                                         hasPanned = true;
  1093.                                 }
  1094.                                 if (Input.isKeyDown(38)) {
  1095.                                         draw.m_drawYOff -= 10;
  1096.                                         hasPanned = true;
  1097.                                 }
  1098.                                 if (Input.isKeyDown(40)) {
  1099.                                         draw.m_drawYOff += 10;
  1100.                                         hasPanned = true;
  1101.                                 }
  1102.                         }
  1103.                 }
  1104.                
  1105.                 protected function CenterOnLoadedRobot():void {
  1106.                         var cameraPart:ShapePart = null;
  1107.                         for (var i:int = 0; i < allParts.length; i++) {
  1108.                                 if (allParts[i] is ShapePart && allParts[i].isCameraFocus) cameraPart = allParts[i];
  1109.                         }
  1110.                         if (!cameraPart) {
  1111.                                 for (i = 0; i < allParts.length; i++) {
  1112.                                         allParts[i].checkedCollisionGroup = false;
  1113.                                 }
  1114.                                 for (i = 0; i < allParts.length; i++) {
  1115.                                         if (allParts[i] is ShapePart) allParts[i].SetCollisionGroup(-(i + 1));
  1116.                                 }
  1117.                                 cameraPart = FindCenterOfRobot();
  1118.                         }
  1119.                         if (cameraPart) {
  1120.                                 var oldX:Number = draw.m_drawXOff;
  1121.                                 var oldY:Number = draw.m_drawYOff;
  1122.                                 draw.m_drawXOff = cameraPart.centerX * m_physScale - ZOOM_FOCUS_X;
  1123.                                 draw.m_drawYOff = cameraPart.centerY * m_physScale - ZOOM_FOCUS_Y;
  1124.                                 if (oldX != draw.m_drawXOff || oldY != draw.m_drawYOff) hasPanned = true;
  1125.                         }
  1126.                 }
  1127.                
  1128.                 protected virtual function HandleCamera():void {
  1129.                         if (cameraPart) {
  1130.                                 var oldX:Number = draw.m_drawXOff;
  1131.                                 var oldY:Number = draw.m_drawYOff;
  1132.                                 draw.m_drawXOff = cameraPart.GetBody().GetWorldCenter().x * m_physScale - ZOOM_FOCUS_X;
  1133.                                 draw.m_drawYOff = cameraPart.GetBody().GetWorldCenter().y * m_physScale - ZOOM_FOCUS_Y;
  1134.                                 if (isNaN(draw.m_drawXOff) || isNaN(draw.m_drawYOff)) {
  1135.                                         draw.m_drawXOff = oldX;
  1136.                                         draw.m_drawYOff = oldY;
  1137.                                 }
  1138.                                 if (oldX != draw.m_drawXOff || oldY != draw.m_drawYOff) hasPanned = true;
  1139.                         }
  1140.                 }
  1141.                
  1142.                 public function MouseDrag():void {
  1143.                         if (!simStarted) {
  1144.                                 // mouse press
  1145.                                 if (Input.mouseDown && mouseYWorld >= 100 && !m_sidePanel.sliderDown && !m_guiMenu.MouseOverMenu(mouseXWorld, mouseYWorld) && (mouseXWorld >= 120 || !m_sidePanel.visible) && (mouseXWorld >= 230 || mouseYWorld >= 340 || !m_sidePanel.ColourWindowShowing()) && curAction != BOX_SELECTING && curAction != DRAWING_BUILD_BOX && curAction != DRAWING_BOX && curAction != DRAWING_HORIZONTAL_LINE && curAction != DRAWING_VERTICAL_LINE) {
  1146.                                         if (!m_tutorialDialog || !m_tutorialDialog.MouseOver(mouseXWorld, mouseYWorld)) {
  1147.                                                 var shapeOrJoint:Part = GetPartAtMouse();
  1148.                                                
  1149.                                                 if (!wasMouseDown && curRobotEditable && shapeOrJoint is ShapePart) {
  1150.                                                         var part:ShapePart = (shapeOrJoint as ShapePart);
  1151.                                                         // rotation
  1152.                                                         if (draggingPart == null && (curAction == -1 || curAction == SELECTING_SHAPE)) {
  1153.                                                                 if (MouseOverSelectedPart()) {
  1154.                                                                         delayedSelection = true;
  1155.                                                                 } else {
  1156.                                                                         if (!Util.ObjectInArray(part, selectedParts)) {
  1157.                                                                                 if (!Input.isKeyDown(16)) {
  1158.                                                                                         selectedParts = new Array();
  1159.                                                                                 }
  1160.                                                                                 selectedParts.push(part);
  1161.                                                                         } else if (Input.isKeyDown(16)) {
  1162.                                                                                 selectedParts = Util.RemoveFromArray(part, selectedParts);
  1163.                                                                         }
  1164.                                                                         redrawRobot = true;
  1165.                                                                 }
  1166.                                                                 draggingPart = selectedParts[0];
  1167.                                                                 initDragX = mouseXWorldPhys;
  1168.                                                                 initDragY = mouseYWorldPhys;
  1169.                                                                 draggingParts = new Array();
  1170.                                                                 for (var i:int = 0; i < selectedParts.length; i++) {
  1171.                                                                         draggingParts = Util.RemoveDuplicates(draggingParts.concat(selectedParts[i].GetAttachedParts()));
  1172.                                                                 }
  1173.                                                                 for (i = 0; i < draggingParts.length; i++) {
  1174.                                                                         if (draggingParts[i] is ShapePart || draggingParts[i] is Thrusters) {
  1175.                                                                                 draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].centerX;
  1176.                                                                                 draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].centerY;
  1177.                                                                         } else if (draggingParts[i] is JointPart) {
  1178.                                                                                 draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].anchorX;
  1179.                                                                                 draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].anchorY;
  1180.                                                                         } else {
  1181.                                                                                 draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].x;
  1182.                                                                                 draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].y;
  1183.                                                                         }
  1184.                                                                 }
  1185.                                                         }
  1186.                                                 } else if (!wasMouseDown && curRobotEditable && shapeOrJoint is JointPart && draggingPart == null && (curAction == -1 || curAction == SELECTING_SHAPE)) {
  1187.                                                         if (MouseOverSelectedPart()) {
  1188.                                                                 delayedSelection = true;
  1189.                                                         } else {
  1190.                                                                 if (!Util.ObjectInArray(shapeOrJoint, selectedParts)) {
  1191.                                                                         if (!Input.isKeyDown(16)) {
  1192.                                                                                 selectedParts = new Array();
  1193.                                                                         }
  1194.                                                                         selectedParts.push(shapeOrJoint);
  1195.                                                                 } else if (Input.isKeyDown(16)) {
  1196.                                                                         selectedParts = Util.RemoveFromArray(shapeOrJoint, selectedParts);
  1197.                                                                 }
  1198.                                                                 redrawRobot = true;
  1199.                                                         }
  1200.                                                         draggingPart = shapeOrJoint;
  1201.                                                         initDragX = mouseXWorldPhys;
  1202.                                                         initDragY = mouseYWorldPhys;
  1203.                                                         draggingParts = new Array();
  1204.                                                         for (i = 0; i < selectedParts.length; i++) {
  1205.                                                                 draggingParts = Util.RemoveDuplicates(draggingParts.concat(selectedParts[i].GetAttachedParts()));
  1206.                                                         }
  1207.                                                         for (i = 0; i < draggingParts.length; i++) {
  1208.                                                                 if (draggingParts[i] is ShapePart || draggingParts[i] is Thrusters) {
  1209.                                                                         draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].centerX;
  1210.                                                                         draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].centerY;
  1211.                                                                 } else if (draggingParts[i] is JointPart) {
  1212.                                                                         draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].anchorX;
  1213.                                                                         draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].anchorY;
  1214.                                                                 } else {
  1215.                                                                         draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].x;
  1216.                                                                         draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].y;
  1217.                                                                 }
  1218.                                                         }
  1219.                                                 } else if (!wasMouseDown && curRobotEditable && shapeOrJoint is TextPart && draggingPart == null && (curAction == -1 || curAction == SELECTING_SHAPE)) {
  1220.                                                         if (MouseOverSelectedPart()) {
  1221.                                                                 delayedSelection = true;
  1222.                                                         } else {
  1223.                                                                 if (!Util.ObjectInArray(shapeOrJoint, selectedParts)) {
  1224.                                                                         if (!Input.isKeyDown(16)) {
  1225.                                                                                 selectedParts = new Array();
  1226.                                                                         }
  1227.                                                                         selectedParts.push(shapeOrJoint);
  1228.                                                                 } else if (Input.isKeyDown(16)) {
  1229.                                                                         selectedParts = Util.RemoveFromArray(shapeOrJoint, selectedParts);
  1230.                                                                 }
  1231.                                                                 redrawRobot = true;
  1232.                                                         }
  1233.                                                         draggingPart = shapeOrJoint;
  1234.                                                         initDragX = mouseXWorldPhys;
  1235.                                                         initDragY = mouseYWorldPhys;
  1236.                                                         if ((shapeOrJoint as TextPart).InsideMoveBox(mouseXWorldPhys, mouseYWorldPhys, m_physScale, true)) {
  1237.                                                                 curAction = RESIZING_TEXT;
  1238.                                                         } else {
  1239.                                                                 draggingParts = new Array();
  1240.                                                                 for (i = 0; i < selectedParts.length; i++) {
  1241.                                                                         draggingParts = Util.RemoveDuplicates(draggingParts.concat(selectedParts[i].GetAttachedParts()));
  1242.                                                                 }
  1243.                                                                 for (i = 0; i < draggingParts.length; i++) {
  1244.                                                                         if (draggingParts[i] is ShapePart || draggingParts[i] is Thrusters) {
  1245.                                                                                 draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].centerX;
  1246.                                                                                 draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].centerY;
  1247.                                                                         } else if (draggingParts[i] is JointPart) {
  1248.                                                                                 draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].anchorX;
  1249.                                                                                 draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].anchorY;
  1250.                                                                         } else {
  1251.                                                                                 draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].x;
  1252.                                                                                 draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].y;
  1253.                                                                         }
  1254.                                                                 }
  1255.                                                         }
  1256.                                                 } else if (!wasMouseDown && curRobotEditable && shapeOrJoint is Thrusters && draggingPart == null && (curAction == -1 || curAction == SELECTING_SHAPE)) {
  1257.                                                         if (MouseOverSelectedPart()) {
  1258.                                                                 delayedSelection = true;
  1259.                                                         } else {
  1260.                                                                 if (!Util.ObjectInArray(shapeOrJoint, selectedParts)) {
  1261.                                                                         if (!Input.isKeyDown(16)) {
  1262.                                                                                 selectedParts = new Array();
  1263.                                                                         }
  1264.                                                                         selectedParts.push(shapeOrJoint);
  1265.                                                                 } else if (Input.isKeyDown(16)) {
  1266.                                                                         selectedParts = Util.RemoveFromArray(shapeOrJoint, selectedParts);
  1267.                                                                 }
  1268.                                                                 redrawRobot = true;
  1269.                                                         }
  1270.                                                         draggingPart = shapeOrJoint;
  1271.                                                         initDragX = mouseXWorldPhys;
  1272.                                                         initDragY = mouseYWorldPhys;
  1273.                                                         draggingParts = new Array();
  1274.                                                         for (i = 0; i < selectedParts.length; i++) {
  1275.                                                                 draggingParts = Util.RemoveDuplicates(draggingParts.concat(selectedParts[i].GetAttachedParts()));
  1276.                                                         }
  1277.                                                         for (i = 0; i < draggingParts.length; i++) {
  1278.                                                                 if (draggingParts[i] is ShapePart || draggingParts[i] is Thrusters) {
  1279.                                                                         draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].centerX;
  1280.                                                                         draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].centerY;
  1281.                                                                 } else if (draggingParts[i] is JointPart) {
  1282.                                                                         draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].anchorX;
  1283.                                                                         draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].anchorY;
  1284.                                                                 } else {
  1285.                                                                         draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].x;
  1286.                                                                         draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].y;
  1287.                                                                 }
  1288.                                                         }
  1289.                                                 } else if (draggingPart == null && rotatingPart == null && (curAction == -1 || curAction == SELECTING_SHAPE)) {
  1290.                                                         if (Input.isKeyDown(16) && curRobotEditable) {
  1291.                                                                 curAction = BOX_SELECTING;
  1292.                                                                 firstClickX = mouseXWorldPhys;
  1293.                                                                 firstClickY = mouseYWorldPhys;
  1294.                                                         } else {
  1295.                                                                 // dragging the world around
  1296.                                                                 var oldX:Number = draw.m_drawXOff;
  1297.                                                                 var oldY:Number = draw.m_drawYOff;
  1298.                                                                 draw.m_drawXOff -= (mouseXWorld - prevMouseXWorld);
  1299.                                                                 draw.m_drawYOff -= (mouseYWorld - prevMouseYWorld);
  1300.                                                                 if (oldX != draw.m_drawXOff || oldY != draw.m_drawYOff) hasPanned = true;
  1301.                                                         }
  1302.                                                        
  1303.                                                         selectedParts = new Array();
  1304.                                                         redrawRobot = true;
  1305.                                                 }
  1306.                                         }
  1307.                                 }
  1308.  
  1309.                                 if (Input.mouseDown && !m_sidePanel.sliderDown && !m_guiMenu.MouseOverMenu(mouseXWorld, mouseYWorld) && mouseYWorld >= 100 && (mouseXWorld >= 120 || !m_sidePanel.visible) && (mouseXWorld >= 230 || mouseYWorld >= 340 || !m_sidePanel.ColourWindowShowing()) && curAction != BOX_SELECTING) {
  1310.                                         if (!m_tutorialDialog || !m_tutorialDialog.MouseOver(mouseXWorld, mouseYWorld)) {
  1311.                                                 RefreshSidePanel();
  1312.                                         }
  1313.                                 }
  1314.  
  1315.                                 if (!Input.mouseDown) draggingTutorial = false;
  1316.                                 if (draggingTutorial) {
  1317.                                         m_tutorialDialog.x = mouseXWorld - initDragX;
  1318.                                         m_tutorialDialog.y = mouseYWorld - initDragY;
  1319.                                 }
  1320.  
  1321.                                 // drag a part
  1322.                                 if (draggingPart != null && curAction != RESIZING_TEXT) {
  1323.                                         for (i = 0; i < draggingParts.length; i++) {
  1324.                                                 draggingParts[i].Move(mouseXWorldPhys - draggingParts[i].dragXOff, mouseYWorldPhys - draggingParts[i].dragYOff);
  1325.                                         }
  1326.                                         curRobotID = "";
  1327.                                 }
  1328.                        
  1329.                                 // rotate a part
  1330.                                 if (curAction == ROTATE && rotatingPart != null) {
  1331.                                         if (Input.isKeyDown(16) == false) {
  1332.                                                 newAngle = Math.atan2(mouseYWorldPhys - rotatingPart.centerY, mouseXWorldPhys - rotatingPart.centerX);
  1333.                                                 // Radians to Degrees
  1334.                                                 degree = (newAngle * 180 / Math.PI);
  1335.                                                 newdegree = Math.round(degree / 15) * 15;
  1336.                                                 // Degrees to Radians
  1337.                                                 initrotang = initRotatingAngle;
  1338.                                                 newAngle = initrotang + (newdegree * Math.PI / 180);
  1339.                                                         for (i = 0; i < rotatingParts.length; i++) {
  1340.                                                         rotatingParts[i].RotateAround(rotatingPart.centerX, rotatingPart.centerY, newAngle - initRotatingAngle);
  1341.                                                         }
  1342.                                         } else {
  1343.                                                 newAngle = Math.atan2(mouseYWorldPhys - rotatingPart.centerY, mouseXWorldPhys - rotatingPart.centerX);
  1344.                                                 // Radians to Degrees
  1345.                                                 degree = (newAngle * 180 / Math.PI);
  1346.                                                 newdegree = Math.round(degree / 45) * 45;
  1347.                                                 // Degrees to Radians
  1348.                                                 initrotang = initRotatingAngle;
  1349.                                                 newAngle = initrotang + (newdegree * Math.PI / 180);
  1350.                                                         for (i = 0; i < rotatingParts.length; i++) {
  1351.                                                                 rotatingParts[i].RotateAround(rotatingPart.centerX, rotatingPart.centerY, newAngle - initRotatingAngle);
  1352.                                                         }
  1353.  
  1354.                                         }
  1355.                                 }
  1356.                                
  1357.                                 if (curAction == SELECTING_SHAPE && selectedParts.length == 1 && selectedParts[0] is ShapePart && selectedParts[0] != m_conditionsDialog.shape1) {
  1358.                                         m_conditionsDialog.visible = true;
  1359.                                         m_fader.visible = true;
  1360.                                         curAction = -1;
  1361.                                         m_sidePanel.visible = false;
  1362.                                         shapeText.visible = false;
  1363.                                         selectingCondition = false;
  1364.                                         m_conditionsDialog.FinishSelectingForCondition(selectedParts[0]);
  1365.                                 }
  1366.                                
  1367.                                 // scale parts?
  1368.                                 if (curAction == RESIZING_SHAPES) {
  1369.                                         // determine scale factor
  1370.                                         var scaleFactor:Number = (mouseXWorld - firstClickX);
  1371.                                         if (scaleFactor >= 0) {
  1372.                                                 scaleFactor /= 75;
  1373.                                                 scaleFactor += 1;
  1374.                                         } else {
  1375.                                                 scaleFactor /= 25;
  1376.                                                 scaleFactor -= 1;
  1377.                                                 scaleFactor = -1 / scaleFactor;
  1378.                                         }
  1379.                                         for (i = 0; i < draggingParts.length; i++) {
  1380.                                                 if (draggingParts[i] is Circle) {
  1381.                                                         if (draggingParts[i].initRadius * scaleFactor > Circle.MAX_RADIUS) scaleFactor = Circle.MAX_RADIUS / draggingParts[i].initRadius;
  1382.                                                         if (draggingParts[i].initRadius * scaleFactor < Circle.MIN_RADIUS) scaleFactor = Circle.MIN_RADIUS / draggingParts[i].initRadius;
  1383.                                                 } else if (draggingParts[i] is Rectangle) {
  1384.                                                         if (draggingParts[i].initW * scaleFactor > Rectangle.MAX_WIDTH) scaleFactor = Rectangle.MAX_WIDTH / draggingParts[i].initW;
  1385.                                                         if (draggingParts[i].initW * scaleFactor < Rectangle.MIN_WIDTH) scaleFactor = Rectangle.MIN_WIDTH / draggingParts[i].initW;
  1386.                                                         if (draggingParts[i].initH * scaleFactor > Rectangle.MAX_WIDTH) scaleFactor = Rectangle.MAX_WIDTH / draggingParts[i].initH;
  1387.                                                         if (draggingParts[i].initH * scaleFactor < Rectangle.MIN_WIDTH) scaleFactor = Rectangle.MIN_WIDTH / draggingParts[i].initH;
  1388.                                                 } else if (draggingParts[i] is Triangle) {
  1389.                                                         var length1:Number = Util.GetDist(draggingParts[i].initX1, draggingParts[i].initY1, draggingParts[i].initX2, draggingParts[i].initY2);
  1390.                                                         if (length1 * scaleFactor > Triangle.MAX_SIDE_LENGTH) scaleFactor = Triangle.MAX_SIDE_LENGTH / length1;
  1391.                                                         if (length1 * scaleFactor < Triangle.MIN_SIDE_LENGTH) scaleFactor = Triangle.MIN_SIDE_LENGTH / length1;
  1392.                                                         var length2:Number = Util.GetDist(draggingParts[i].initX1, draggingParts[i].initY1, draggingParts[i].initX3, draggingParts[i].initY3);
  1393.                                                         if (length2 * scaleFactor > Triangle.MAX_SIDE_LENGTH) scaleFactor = Triangle.MAX_SIDE_LENGTH / length2;
  1394.                                                         if (length2 * scaleFactor < Triangle.MIN_SIDE_LENGTH) scaleFactor = Triangle.MIN_SIDE_LENGTH / length2;
  1395.                                                         var length3:Number = Util.GetDist(draggingParts[i].initX2, draggingParts[i].initY2, draggingParts[i].initX3, draggingParts[i].initY3);
  1396.                                                         if (length3 * scaleFactor > Triangle.MAX_SIDE_LENGTH) scaleFactor = Triangle.MAX_SIDE_LENGTH / length3;
  1397.                                                         if (length3 * scaleFactor < Triangle.MIN_SIDE_LENGTH) scaleFactor = Triangle.MIN_SIDE_LENGTH / length3;
  1398.                                                 } else if (draggingParts[i] is Cannon) {
  1399.                                                         if (draggingParts[i].initW * scaleFactor > Cannon.MAX_WIDTH) scaleFactor = Cannon.MAX_WIDTH / draggingParts[i].initW;
  1400.                                                         if (draggingParts[i].initW * scaleFactor < Cannon.MIN_WIDTH) scaleFactor = Cannon.MIN_WIDTH / draggingParts[i].initW;
  1401.                                                 }
  1402.                                         }
  1403.                                        
  1404.                                         // scale the parts
  1405.                                         for (i = 0; i < draggingParts.length; i++) {
  1406.                                                 if (draggingParts[i] is Circle) {
  1407.                                                         draggingParts[i].radius = draggingParts[i].initRadius * scaleFactor;
  1408.                                                         draggingParts[i].Move(initDragX + draggingParts[i].dragXOff * scaleFactor, initDragY + draggingParts[i].dragYOff * scaleFactor);
  1409.                                                 } else if (draggingParts[i] is Rectangle) {
  1410.                                                         draggingParts[i].w = draggingParts[i].initW * scaleFactor;
  1411.                                                         draggingParts[i].h = draggingParts[i].initH * scaleFactor;
  1412.                                                         draggingParts[i].Move(initDragX + draggingParts[i].dragXOff * scaleFactor, initDragY + draggingParts[i].dragYOff * scaleFactor);
  1413.                                                 } else if (draggingParts[i] is Triangle) {
  1414.                                                         draggingParts[i].centerX = initDragX + draggingParts[i].dragXOff * scaleFactor;
  1415.                                                         draggingParts[i].centerY = initDragY + draggingParts[i].dragYOff * scaleFactor;
  1416.                                                         draggingParts[i].x1 = draggingParts[i].centerX + draggingParts[i].initX1 * scaleFactor;
  1417.                                                         draggingParts[i].y1 = draggingParts[i].centerY + draggingParts[i].initY1 * scaleFactor;
  1418.                                                         draggingParts[i].x2 = draggingParts[i].centerX + draggingParts[i].initX2 * scaleFactor;
  1419.                                                         draggingParts[i].y2 = draggingParts[i].centerY + draggingParts[i].initY2 * scaleFactor;
  1420.                                                         draggingParts[i].x3 = draggingParts[i].centerX + draggingParts[i].initX3 * scaleFactor;
  1421.                                                         draggingParts[i].y3 = draggingParts[i].centerY + draggingParts[i].initY3 * scaleFactor;
  1422.                                                 } else if (draggingParts[i] is Cannon) {
  1423.                                                         draggingParts[i].w = draggingParts[i].initW * scaleFactor;
  1424.                                                         draggingParts[i].Move(initDragX + draggingParts[i].dragXOff * scaleFactor, initDragY + draggingParts[i].dragYOff * scaleFactor);
  1425.                                                 } else if (draggingParts[i] is JointPart) {
  1426.                                                         draggingParts[i].Move(initDragX + draggingParts[i].dragXOff * scaleFactor, initDragY + draggingParts[i].dragYOff * scaleFactor);
  1427.                                                         if (draggingParts[i] is PrismaticJoint) {
  1428.                                                                 draggingParts[i].initLength = draggingParts[i].initInitLength * scaleFactor;
  1429.                                                         }
  1430.                                                 } else if (draggingParts[i] is TextPart) {
  1431.                                                         draggingParts[i].w = draggingParts[i].initW * scaleFactor;
  1432.                                                         draggingParts[i].h = draggingParts[i].initH * scaleFactor;
  1433.                                                         draggingParts[i].x = initDragX + draggingParts[i].dragXOff * scaleFactor - draggingParts[i].w / 2;
  1434.                                                         draggingParts[i].y = initDragY + draggingParts[i].dragYOff * scaleFactor - draggingParts[i].h / 2;
  1435.                                                 } else if (draggingParts[i] is Thrusters) {
  1436.                                                         draggingParts[i].Move(initDragX + draggingParts[i].dragXOff * scaleFactor, initDragY + draggingParts[i].dragYOff * scaleFactor);
  1437.                                                 }
  1438.                                         }
  1439.                                         mostRecentScaleFactor = scaleFactor;
  1440.                                 }
  1441.                                
  1442.                                 // finalize a joint
  1443.                                 if (curAction == FINALIZING_JOINT && Util.GetDist(candidateJointX, candidateJointY, mouseXWorldPhys, mouseYWorldPhys) > 0.5 * 30 / m_physScale) {
  1444.                                         if (candidateJointType == NEW_REVOLUTE_JOINT) {
  1445.                                                 var rjoint:RevoluteJoint = new RevoluteJoint(potentialJointPart1, potentialJointPart2, candidateJointX, candidateJointY);
  1446.                                                 if (copiedJoint is RevoluteJoint) rjoint.SetJointProperties(copiedJoint as RevoluteJoint);
  1447.                                                 allParts.push(rjoint);
  1448.                                                 AddAction(new CreateAction(rjoint));
  1449.                                                 m_sidePanel.ShowJointPanel(rjoint);
  1450.                                                 selectedParts = new Array();
  1451.                                                 selectedParts.push(rjoint);
  1452.                                                 curAction = -1;
  1453.                                                 potentialJointPart1.highlightForJoint = false;
  1454.                                                 potentialJointPart2.highlightForJoint = false;
  1455.                                                 curRobotID = "";
  1456.                                                 if (centerOnSelected) CenterOnSelected();
  1457.                                                 redrawRobot = true;
  1458.                                                 PlayJointSound();
  1459.                                         } else if (candidateJointType == NEW_FIXED_JOINT) {
  1460.                                                 var fjoint:JointPart = new FixedJoint(potentialJointPart1, potentialJointPart2, candidateJointX, candidateJointY);
  1461.                                                 allParts.push(fjoint);
  1462.                                                 AddAction(new CreateAction(fjoint));
  1463.                                                 m_sidePanel.ShowJointPanel(fjoint);
  1464.                                                 selectedParts = new Array();
  1465.                                                 selectedParts.push(fjoint);
  1466.                                                 curAction = -1;
  1467.                                                 potentialJointPart1.highlightForJoint = false;
  1468.                                                 potentialJointPart2.highlightForJoint = false;
  1469.                                                 curRobotID = "";
  1470.                                                 if (centerOnSelected) CenterOnSelected();
  1471.                                                 redrawRobot = true;
  1472.                                                 PlayJointSound();
  1473.                                         } else if (candidateJointType == NEW_THRUSTERS) {
  1474.                                                 var t:Thrusters = new Thrusters(potentialJointPart1, candidateJointX, candidateJointY);
  1475.                                                 if (copiedThrusters) {
  1476.                                                         t.strength = copiedThrusters.strength;
  1477.                                                         t.angle = copiedThrusters.angle;
  1478.                                                         t.thrustKey = copiedThrusters.thrustKey;
  1479.                                                         t.autoOn = copiedThrusters.autoOn;
  1480.                                                 }
  1481.                                                 allParts.push(t);
  1482.                                                 AddAction(new CreateAction(t));
  1483.                                                 m_sidePanel.ShowThrustersPanel(t);
  1484.                                                 selectedParts = new Array();
  1485.                                                 selectedParts.push(t);
  1486.                                                 curAction = -1;
  1487.                                                 potentialJointPart1.highlightForJoint = false;
  1488.                                                 curRobotID = "";
  1489.                                                 if (centerOnSelected) CenterOnSelected();
  1490.                                                 redrawRobot = true;
  1491.                                                 PlayJointSound();
  1492.                                         } else if (candidateJointType == NEW_PRISMATIC_JOINT && actionStep == 0) {
  1493.                                                 jointPart = potentialJointPart1;
  1494.                                                 firstClickX = candidateJointX;
  1495.                                                 firstClickY = candidateJointY;
  1496.                                                 curAction = NEW_PRISMATIC_JOINT;
  1497.                                                 actionStep++;
  1498.                                                 PlayJointSound();
  1499.                                         } else if (candidateJointType == NEW_PRISMATIC_JOINT) {
  1500.                                                 var pjoint:PrismaticJoint = new PrismaticJoint(jointPart, potentialJointPart1, firstClickX, firstClickY, candidateJointX, candidateJointY);
  1501.                                                 if (copiedJoint is PrismaticJoint) pjoint.SetJointProperties(copiedJoint as PrismaticJoint);
  1502.                                                 allParts.push(pjoint);
  1503.                                                 AddAction(new CreateAction(pjoint));
  1504.                                                 m_sidePanel.ShowJointPanel(pjoint);
  1505.                                                 selectedParts = new Array();
  1506.                                                 selectedParts.push(pjoint);
  1507.                                                 curAction = -1;
  1508.                                                 jointPart.highlightForJoint = false;
  1509.                                                 potentialJointPart1.highlightForJoint = false;
  1510.                                                 curRobotID = "";
  1511.                                                 if (centerOnSelected) CenterOnSelected();
  1512.                                                 redrawRobot = true;
  1513.                                                 PlayJointSound();
  1514.                                         }
  1515.                                 }
  1516.                                
  1517.                                 // resize text
  1518.                                 if (curAction == RESIZING_TEXT) {
  1519.                                         (draggingPart as TextPart).Resize(mouseXWorldPhys - initDragX, mouseYWorldPhys - initDragY);
  1520.                                         redrawRobot = true;
  1521.                                 }
  1522.                         } else if (!paused && (((this is ControllerSandbox) && !(this is ControllerChallenge)) || ((this is ControllerChallenge) && ControllerChallenge.challenge.mouseDragAllowed))) {
  1523.                                 // mouse press
  1524.                                 if (Input.mouseDown && !m_mouseJoint) {
  1525.                                         var body:b2Body = GetBodyAtMouse();
  1526.                                        
  1527.                                         if (!playingReplay && body) {
  1528.                                                 var md:b2MouseJointDef = new b2MouseJointDef();
  1529.                                                 md.body1 = m_world.m_groundBody;
  1530.                                                 md.body2 = body;
  1531.                                                 md.target.Set(mouseXWorldPhys, mouseYWorldPhys);
  1532.                                                 md.maxForce = 300.0 * body.m_mass;
  1533.                                                 md.timeStep = m_timeStep;
  1534.                                                 m_mouseJoint = m_world.CreateJoint(md) as b2MouseJoint;
  1535.                                                 body.WakeUp();
  1536.                                         }
  1537.                                 }
  1538.                        
  1539.                                 // mouse move
  1540.                                 if (m_mouseJoint) {
  1541.                                         var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
  1542.                                         m_mouseJoint.SetTarget(p2);
  1543.                                 }
  1544.                        
  1545.                                 // mouse release
  1546.                                 if (!Input.mouseDown) {
  1547.                                         if (m_mouseJoint) {
  1548.                                                 m_world.DestroyJoint(m_mouseJoint);
  1549.                                                 m_mouseJoint = null;
  1550.                                         }
  1551.                                 }
  1552.                         }
  1553.                        
  1554.                         if (simStarted && Input.mouseDown && !m_guiMenu.MouseOverMenu(mouseXWorld, mouseYWorld) && mouseYWorld >= 100 && (mouseXWorld >= 120 || !m_sidePanel.visible) && (mouseXWorld >= 230 || mouseYWorld >= 340 || !m_sidePanel.ColourWindowShowing()) && curAction != BOX_SELECTING && !m_mouseJoint) {
  1555.                                 if ((!m_tutorialDialog || !m_tutorialDialog.MouseOver(mouseXWorld, mouseYWorld)) && !draggingTutorial) {
  1556.                                         // dragging the world around
  1557.                                         var change:Boolean = (mouseXWorld != prevMouseXWorld || mouseYWorld != prevMouseYWorld);
  1558.                                         draw.m_drawXOff -= (mouseXWorld - prevMouseXWorld);
  1559.                                         draw.m_drawYOff -= (mouseYWorld - prevMouseYWorld);
  1560.                                         autoPanning = false;
  1561.                                        
  1562.                                         if (change) {
  1563.                                                 hasPanned = true;
  1564.                                                 cameraMovements.push(new CameraMovement(frameCounter, draw.m_drawXOff, draw.m_drawYOff, m_physScale));
  1565.                                         }
  1566.                                 }
  1567.                         }
  1568.                        
  1569.                         // make sure they haven't gone beyond the boundaries
  1570.                         var minY:Number = Screen2WorldY(85);
  1571.                         var maxY:Number = Screen2WorldY(600);
  1572.                         if (minY < GetMinY()) {
  1573.                                 draw.m_drawYOff += World2ScreenY(GetMinY()) - World2ScreenY(minY);
  1574.                         } else if (maxY > GetMaxY()) {
  1575.                                 draw.m_drawYOff -= World2ScreenY(maxY) - World2ScreenY(GetMaxY());
  1576.                         }
  1577.                        
  1578.                         var minX:Number = Screen2WorldX(0);
  1579.                         var maxX:Number = Screen2WorldX(800);
  1580.                         if (minX < GetMinX()) {
  1581.                                 draw.m_drawXOff += World2ScreenX(GetMinX()) - World2ScreenX(minX);
  1582.                                 hasPanned = true;
  1583.                         } else if (maxX > GetMaxX()) {
  1584.                                 draw.m_drawXOff -= World2ScreenX(maxX) - World2ScreenX(GetMaxX());
  1585.                                 hasPanned = true;
  1586.                         }
  1587.                        
  1588.                         wasMouseDown = Input.mouseDown;
  1589.                 }
  1590.  
  1591.                 public override function keyInput(key:int, up:Boolean):void {
  1592.                         var recorded:Boolean = false;
  1593.                         for (var i:int = 0; i < allParts.length; i++) {
  1594.                                 allParts[i].KeyInput(key, up, playingReplay);
  1595.                                 if (!recorded && up && !playingReplay && ((allParts[i] is TextPart && key == allParts[i].displayKey) || (allParts[i] is Cannon && key == allParts[i].fireKey))) {
  1596.                                         recorded = true;
  1597.                                         keyPresses.push(new KeyPress(frameCounter, key));
  1598.                                 }
  1599.                         }
  1600.                 }
  1601.                
  1602.                 public function keyPress(key:int, up:Boolean):void {
  1603.                         if (!paused && !playingReplay) {
  1604.                                 keyInput(key, up);
  1605.                         }
  1606.                        
  1607.                         if (!simStarted && !m_sidePanel.EnteringInput() && !m_fader.visible) {
  1608.                                 if (up && key == 49) {
  1609.                                         circleButton(new MouseEvent(""));
  1610.                                 } else if (up && key == 50) {
  1611.                                         rectButton(new MouseEvent(""));
  1612.                                 } else if (up && key == 51) {
  1613.                                         triangleButton(new MouseEvent(""));
  1614.                                 } else if (up && key == 52) {
  1615.                                         fjButton(new MouseEvent(""));
  1616.                                 } else if (up && key == 53) {
  1617.                                         rjButton(new MouseEvent(""));
  1618.                                 } else if (up && key == 54) {
  1619.                                         pjButton(new MouseEvent(""));
  1620.                                 } else if (up && key == 55) {
  1621.                                         textButton(new MouseEvent(""));
  1622.                                 } else if (up && key == 82) {
  1623.                                         rotateButton(new MouseEvent(""));
  1624.                                 } else if (up && key == 88) {
  1625.                                         cutButton(new MouseEvent(""));
  1626.                                 } else if (up && key == 67) {
  1627.                                         copyButton(new MouseEvent(""));
  1628.                                 } else if (up && key == 86) {
  1629.                                         pasteButton(new MouseEvent(""));
  1630.                                 } else if (up && (key == 8 || key == 46)) {
  1631.                                         if (selectedParts.length == 1 && !selectedParts[0] is TextPart) deleteButton(new MouseEvent(""));
  1632.                                         else multiDeleteButton(new MouseEvent(""));
  1633.                                 } else if (up && key == 89) {
  1634.                                         redoButton(new MouseEvent(""));
  1635.                                 } else if (up && key == 90) {
  1636.                                         undoButton(new MouseEvent(""));
  1637.                                 } else if (up && (key == 107 || key == 187)) {
  1638.                                         zoomInButton(new MouseEvent(""));
  1639.                                 } else if (up && (key == 109 || key == 189)) {
  1640.                                         zoomOutButton(new MouseEvent(""));
  1641.                                 } else if (up && key == 80) {
  1642.                                         playButton(new MouseEvent(""));
  1643.                                 }
  1644.                         }
  1645.                        
  1646.                         if (up && key == 27) {
  1647.                                 if (m_chooserWindow && m_chooserWindow.visible && !m_chooserWindow.fader.visible) {
  1648.                                         m_chooserWindow.visible = false;
  1649.                                         m_fader.visible = false;
  1650.                                 }
  1651.                                 if (m_challengeWindow && m_challengeWindow.visible && !m_challengeWindow.fader.visible) {
  1652.                                         m_challengeWindow.visible = false;
  1653.                                         m_fader.visible = false;
  1654.                                 }
  1655.                                 if (m_sidePanel.visible && !m_fader.visible) {
  1656.                                         m_sidePanel.visible = false;
  1657.                                 }
  1658.                                 if (m_scoreWindow && m_scoreWindow.visible) {
  1659.                                         m_scoreWindow.visible = false;
  1660.                                         m_fader.visible = false;
  1661.                                 }
  1662.                                 if (m_progressDialog && m_progressDialog.visible) {
  1663.                                         m_progressDialog.visible = false;
  1664.                                         if (m_chooserWindow && m_chooserWindow.visible) {
  1665.                                                 m_chooserWindow.HideFader();
  1666.                                         } else if (m_challengeWindow && m_challengeWindow.visible) {
  1667.                                                 m_challengeWindow.HideFader();
  1668.                                         } else if (m_loginWindow && m_loginWindow.visible) {
  1669.                                                 m_loginWindow.HideFader();
  1670.                                         } else if (m_newUserWindow && m_newUserWindow.visible) {
  1671.                                                 m_newUserWindow.HideFader();
  1672.                                         } else {
  1673.                                                 m_fader.visible = false;
  1674.                                         }
  1675.                                 }
  1676.                                 if (m_tutorialDialog && m_tutorialDialog.visible) {
  1677.                                         m_tutorialDialog.closeWindow(new MouseEvent(""));
  1678.                                 }
  1679.                                 if (m_linkDialog && m_linkDialog.visible) {
  1680.                                         m_linkDialog.visible = false;
  1681.                                         if (m_chooserWindow && m_chooserWindow.visible) {
  1682.                                                 m_chooserWindow.HideFader();
  1683.                                         } else {
  1684.                                                 m_fader.visible = false;
  1685.                                         }
  1686.                                 }
  1687.                                 if (m_loginWindow && m_loginWindow.visible && !m_loginWindow.fader.visible) {
  1688.                                         m_loginWindow.cancelButtonPressed(new MouseEvent(""));
  1689.                                 }
  1690.                                 if (m_newUserWindow && m_newUserWindow.visible) {
  1691.                                         m_newUserWindow.cancelButtonPressed(new MouseEvent(""));
  1692.                                 }
  1693.                         }
  1694.                 }
  1695.                
  1696.                 public function mouseMove(x:int, y:int):void {
  1697.                         Main.mouseCursor.x = x;
  1698.                         Main.mouseCursor.y = y;
  1699.                         Main.mouseHourglass.x = x;
  1700.                         Main.mouseHourglass.y = y;
  1701.                 }
  1702.                
  1703.                 public function mouseClick(up:Boolean):void {
  1704.                         m_guiMenu.MouseClick(up, mouseXWorld, mouseYWorld);
  1705.                         var part:ShapePart;
  1706.                        
  1707.                         if (up && delayedSelection) {
  1708.                                 delayedSelection = false;
  1709.                                 if (mouseXWorldPhys == initDragX && mouseYWorldPhys == initDragY) {
  1710.                                         var p:Part = GetPartAtMouse();
  1711.                                         if (!Util.ObjectInArray(p, selectedParts)) {
  1712.                                                 if (!Input.isKeyDown(16)) {
  1713.                                                         selectedParts = new Array();
  1714.                                                 }
  1715.                                                 selectedParts.push(p);
  1716.                                         } else if (Input.isKeyDown(16)) {
  1717.                                                 selectedParts = Util.RemoveFromArray(p, selectedParts);
  1718.                                         }
  1719.                                         redrawRobot = true;
  1720.                                         RefreshSidePanel();
  1721.                                 }
  1722.                         }
  1723.                        
  1724.                         if (up && rotatingPart != null) {
  1725.                                 curAction = -1;
  1726.                                 AddAction(new RotateAction((rotatingPart as Part), rotatingParts, Util.NormalizeAngle(Math.atan2(mouseYWorldPhys - rotatingPart.centerY, mouseXWorldPhys - rotatingPart.centerX) - initRotatingAngle)));
  1727.                                 CheckIfPartsFit();
  1728.                                 rotatingPart = null;
  1729.                         } else if (up && draggingPart != null) {
  1730.                                 if (!ignoreAClick) {
  1731.                                         if (curAction != PASTE && curAction != RESIZING_TEXT && (mouseXWorldPhys != initDragX || mouseYWorldPhys != initDragY)) AddAction(new MoveAction(draggingPart, draggingParts, mouseXWorldPhys - initDragX, mouseYWorldPhys - initDragY));
  1732.                                         if (curAction == RESIZING_TEXT) {
  1733.                                                 var tPart:TextPart = (draggingPart as TextPart);
  1734.                                                 AddAction(new ResizeTextAction(tPart, tPart.x - tPart.initX, tPart.y - tPart.initY, tPart.w - tPart.initW, tPart.h - tPart.initH));
  1735.                                         }
  1736.                                         CheckIfPartsFit();
  1737.                                         if (curAction == PASTE) {
  1738.                                                 var hasShape:Boolean = false;
  1739.                                                 for (var i:int = 0; i < draggingParts.length; i++) {
  1740.                                                         if (draggingParts[i] is ShapePart) {
  1741.                                                                 hasShape = true;
  1742.                                                                 break;
  1743.                                                         }
  1744.                                                 }
  1745.                                                 if (hasShape) PlayShapeSound();
  1746.                                         }
  1747.                                         if (curAction < 14) curAction = -1;
  1748.                                         draggingPart = null;
  1749.                                 } else {
  1750.                                         ignoreAClick = false;
  1751.                                 }
  1752.                         } else if (!up && curAction == RESIZING_SHAPES) {
  1753.                                 if (!ignoreAClick) {
  1754.                                         curAction = -1;
  1755.                                         AddAction(new ResizeShapesAction(draggingParts, mostRecentScaleFactor));
  1756.                                         draggingParts = new Array();
  1757.                                         CheckIfPartsFit();
  1758.                                 } else {
  1759.                                         ignoreAClick = false;
  1760.                                 }
  1761.                         } else if (!up && (curAction == DRAWING_BUILD_BOX || curAction == DRAWING_BOX || curAction == DRAWING_HORIZONTAL_LINE || curAction == DRAWING_VERTICAL_LINE) && actionStep == 0 && mouseYWorld > 100 && !m_guiMenu.MouseOverMenu(mouseXWorld, mouseYWorld) && (!m_tutorialDialog || !m_tutorialDialog.MouseOver(mouseXWorld, mouseYWorld))) {
  1762.                                 firstClickX = mouseXWorldPhys;
  1763.                                 firstClickY = mouseYWorldPhys;
  1764.                                 actionStep++;
  1765.                         } else if ((curAction == DRAWING_BOX || curAction == DRAWING_HORIZONTAL_LINE || curAction == DRAWING_VERTICAL_LINE) && actionStep == 1) {
  1766.                                 if (Math.abs(firstClickX - mouseXWorldPhys) > 0.1 || Math.abs(firstClickY - mouseYWorldPhys) > 0.1) {
  1767.                                         curAction = -1;
  1768.                                         m_conditionsDialog.visible = true;
  1769.                                         m_fader.visible = true;
  1770.                                         selectingCondition = false;
  1771.                                         m_conditionsDialog.FinishDrawingCondition(firstClickX, firstClickY, mouseXWorldPhys, mouseYWorldPhys);
  1772.                                         boxText.visible = false;
  1773.                                         horizLineText.visible = false;
  1774.                                         vertLineText.visible = false;
  1775.                                         redrawRobot = true;
  1776.                                 }
  1777.                         } else if (curAction == DRAWING_BUILD_BOX && actionStep == 1) {
  1778.                                 if (Math.abs(firstClickX - mouseXWorldPhys) > 0.5 || Math.abs(firstClickY - mouseYWorldPhys) > 0.5) {
  1779.                                         curAction = -1;
  1780.                                         var buildArea:b2AABB = new b2AABB();
  1781.                                         buildArea.lowerBound = Util.Vector(Math.min(firstClickX, mouseXWorldPhys), Math.min(firstClickY, mouseYWorldPhys));
  1782.                                         buildArea.upperBound = Util.Vector(Math.max(firstClickX, mouseXWorldPhys), Math.max(firstClickY, mouseYWorldPhys));
  1783.                                         ControllerChallenge.challenge.buildAreas.push(buildArea);
  1784.                                         selectedBuildArea = ControllerChallenge.challenge.buildAreas[ControllerChallenge.challenge.buildAreas.length - 1];
  1785.                                         m_sidePanel.ShowBuildBoxPanel();
  1786.                                         BuildBuildArea();
  1787.                                         redrawRobot = true;
  1788.                                         redrawBuildArea = true;
  1789.                                 }
  1790.                         }
  1791.                        
  1792.                         if (!up && !draggingTutorial && m_tutorialDialog && m_tutorialDialog.MouseOver(mouseXWorld, mouseYWorld)) {
  1793.                                 draggingTutorial = true;
  1794.                                 initDragX = mouseXWorld - m_tutorialDialog.x;
  1795.                                 initDragY = mouseYWorld - m_tutorialDialog.y;
  1796.                                 return;
  1797.                         }
  1798.                         if (!curRobotEditable || mouseYWorld < 100 || (mouseXWorld < 120 && m_sidePanel.visible) || m_guiMenu.MouseOverMenu(mouseXWorld, mouseYWorld) || (mouseXWorld < 230 && mouseYWorld < 340 && m_sidePanel.ColourWindowShowing()) || (m_tutorialDialog && m_tutorialDialog.MouseOver(mouseXWorld, mouseYWorld))) return;
  1799.                        
  1800.                         if (up && selectedParts.length == 1 && centerOnSelected) {
  1801.                                 CenterOnSelected();
  1802.                         } else if (selectedParts.length == 0 && curAction == -1 && this is ControllerChallenge && !ControllerChallenge.playChallengeMode) {
  1803.                                 for (i = 0; i < ControllerChallenge.challenge.buildAreas.length; i++) {
  1804.                                         if (mouseXWorldPhys > ControllerChallenge.challenge.buildAreas[i].lowerBound.x && mouseXWorldPhys < ControllerChallenge.challenge.buildAreas[i].upperBound.x && mouseYWorldPhys > ControllerChallenge.challenge.buildAreas[i].lowerBound.y && mouseYWorldPhys < ControllerChallenge.challenge.buildAreas[i].upperBound.y) {
  1805.                                                 selectedBuildArea = ControllerChallenge.challenge.buildAreas[i];
  1806.                                                 m_sidePanel.ShowBuildBoxPanel();
  1807.                                                 break;
  1808.                                         }
  1809.                                 }
  1810.                         }
  1811.                        
  1812.                         if (curAction == NEW_CIRCLE) {
  1813.                                 if (!up && actionStep == 0) {
  1814.                                         firstClickX = mouseXWorldPhys;
  1815.                                         firstClickY = mouseYWorldPhys;
  1816.                                         actionStep++;
  1817.                                 } else if (up && actionStep == 1) {
  1818.                                         var radius:Number = Util.GetDist(firstClickX, firstClickY, mouseXWorldPhys, mouseYWorldPhys);
  1819.                                         if (radius > 0) {
  1820.                                                 curAction = -1;
  1821.                                                 var circ:ShapePart = new Circle(firstClickX, firstClickY, radius);
  1822.                                                 allParts.push(circ);
  1823.                                                 selectedParts = new Array();
  1824.                                                 selectedParts.push(circ);
  1825.                                                 AddAction(new CreateAction(circ));
  1826.                                                 CheckIfPartsFit();
  1827.                                                 m_sidePanel.ShowObjectPanel(circ);
  1828.                                                 curRobotID = "";
  1829.                                                 if (centerOnSelected) CenterOnSelected();
  1830.                                                 redrawRobot = true;
  1831.                                                 PlayShapeSound();
  1832.                                         }
  1833.                                 }
  1834.                         } else if (curAction == NEW_RECT) {
  1835.                                 if (!up && actionStep == 0) {
  1836.                                         firstClickX = mouseXWorldPhys;
  1837.                                         firstClickY = mouseYWorldPhys;
  1838.                                         actionStep++;
  1839.                                 } else if (up && actionStep == 1) {
  1840.                                         if (mouseXWorldPhys != firstClickX || mouseYWorldPhys != firstClickY) {
  1841.                                                 curAction = -1;
  1842.                                                 rect = new Rectangle(firstClickX, firstClickY, mouseXWorldPhys - firstClickX, mouseYWorldPhys - firstClickY);
  1843.                                                 allParts.push(rect);
  1844.                                                 selectedParts = new Array();
  1845.                                                 selectedParts.push(rect);
  1846.                                                 AddAction(new CreateAction(rect));
  1847.                                                 CheckIfPartsFit();
  1848.                                                 m_sidePanel.ShowObjectPanel(rect);
  1849.                                                 curRobotID = "";
  1850.                                                 if (centerOnSelected) CenterOnSelected();
  1851.                                                 redrawRobot = true;
  1852.                                                 PlayShapeSound();
  1853.                                         }
  1854.                                 }
  1855.                         } else if (curAction == NEW_CANNON) {
  1856.                                 if (!up && actionStep == 0) {
  1857.                                         firstClickX = mouseXWorldPhys;
  1858.                                         firstClickY = mouseYWorldPhys;
  1859.                                         actionStep++;
  1860.                                 } else if (up && actionStep == 1) {
  1861.                                         if (mouseXWorldPhys != firstClickX || mouseYWorldPhys != firstClickY) {
  1862.                                                 curAction = -1;
  1863.                                                 var positive:Boolean = (mouseXWorldPhys >= firstClickX || mouseYWorldPhys >= firstClickY);
  1864.                                                 var w:Number = (positive ? Math.max(mouseXWorldPhys - firstClickX, 2 * (mouseYWorldPhys - firstClickY)) : Math.min(mouseXWorldPhys - firstClickX, 2 * (mouseYWorldPhys - firstClickY)));
  1865.                                                 var cannon:ShapePart = new Cannon(firstClickX, firstClickY, w);
  1866.                                                 allParts.push(cannon);
  1867.                                                 selectedParts = new Array();
  1868.                                                 selectedParts.push(cannon);
  1869.                                                 AddAction(new CreateAction(cannon));
  1870.                                                 CheckIfPartsFit();
  1871.                                                 m_sidePanel.ShowCannonPanel((cannon as Cannon));
  1872.                                                 curRobotID = "";
  1873.                                                 if (centerOnSelected) CenterOnSelected();
  1874.                                                 redrawRobot = true;
  1875.                                                 PlayShapeSound();
  1876.                                         }
  1877.                                 }
  1878.                         } else if (curAction == NEW_TRIANGLE) {
  1879.                                 if (!up && actionStep == 0) {
  1880.                                         firstClickX = mouseXWorldPhys;
  1881.                                         firstClickY = mouseYWorldPhys;
  1882.                                         actionStep++;
  1883.                                 } else if (up && actionStep == 1) {
  1884.                                         if (mouseXWorldPhys != firstClickX || mouseYWorldPhys != firstClickY) {
  1885.                                                 var x2:Number = mouseXWorldPhys;
  1886.                                                 var y2:Number = mouseYWorldPhys;
  1887.                                                
  1888.                                                 var sideLen:Number = Util.GetDist(firstClickX, firstClickY, mouseXWorldPhys, mouseYWorldPhys);
  1889.                                                 var angle:Number;
  1890.                                                 if (sideLen < Triangle.MIN_SIDE_LENGTH) {
  1891.                                                         angle = Math.atan2(firstClickY - mouseYWorldPhys, mouseXWorldPhys - firstClickX);
  1892.                                                         x2 = firstClickX + Triangle.MIN_SIDE_LENGTH * Math.cos(angle);
  1893.                                                         y2 = firstClickY - Triangle.MIN_SIDE_LENGTH * Math.sin(angle);
  1894.                                                 } else if (sideLen > Triangle.MAX_SIDE_LENGTH) {
  1895.                                                         angle = Math.atan2(firstClickY - mouseYWorldPhys, mouseXWorldPhys - firstClickX);
  1896.                                                         x2 = firstClickX + Triangle.MAX_SIDE_LENGTH * Math.cos(angle);
  1897.                                                         y2 = firstClickY - Triangle.MAX_SIDE_LENGTH * Math.sin(angle);
  1898.                                                 }
  1899.                                                 secondClickX = x2;
  1900.                                                 secondClickY = y2;
  1901.                                                 actionStep++;
  1902.                                                 PlayShapeSound();
  1903.                                         }
  1904.                                 } else if (up && actionStep == 2) {
  1905.                                         if ((mouseXWorldPhys != firstClickX || mouseYWorldPhys != firstClickY) && (mouseXWorldPhys != secondClickX || mouseYWorldPhys != secondClickY)) {
  1906.                                                 var sideLen1:Number = Util.GetDist(firstClickX, firstClickY, mouseXWorldPhys, mouseYWorldPhys);
  1907.                                                 var sideLen2:Number = Util.GetDist(secondClickX, secondClickY, mouseXWorldPhys, mouseYWorldPhys);
  1908.                                                 var sideLen0:Number = Util.GetDist(firstClickX, firstClickY, secondClickX, secondClickY);
  1909.                                                 var angle1:Number = Util.NormalizeAngle(Math.acos((sideLen0 * sideLen0 + sideLen1 * sideLen1 - sideLen2 * sideLen2) / (2 * sideLen0 * sideLen1)));
  1910.                                                
  1911.                                                 var angle2:Number = Util.NormalizeAngle(Math.acos((sideLen0 * sideLen0 + sideLen2 * sideLen2 - sideLen1 * sideLen1) / (2 * sideLen0 * sideLen2)));
  1912.                                                
  1913.                                                 var angle3:Number = Util.NormalizeAngle(Math.acos((sideLen1 * sideLen1 + sideLen2 * sideLen2 - sideLen0 * sideLen0) / (2 * sideLen1 * sideLen2)));
  1914.                                                
  1915.                                                 if (sideLen1 <= Triangle.MAX_SIDE_LENGTH && sideLen1 >= Triangle.MIN_SIDE_LENGTH && sideLen2 <= Triangle.MAX_SIDE_LENGTH && sideLen2 >= Triangle.MIN_SIDE_LENGTH && angle1 >= Triangle.MIN_TRIANGLE_ANGLE && angle2 >= Triangle.MIN_TRIANGLE_ANGLE && angle3 >= Triangle.MIN_TRIANGLE_ANGLE) {
  1916.                                                         curAction = -1;
  1917.                                                         var tri:ShapePart = new Triangle(firstClickX, firstClickY, secondClickX, secondClickY, mouseXWorldPhys, mouseYWorldPhys);
  1918.                                                         allParts.push(tri);
  1919.                                                         selectedParts = new Array();
  1920.                                                         selectedParts.push(tri);
  1921.                                                         AddAction(new CreateAction(tri));
  1922.                                                         CheckIfPartsFit();
  1923.                                                         m_sidePanel.ShowObjectPanel(tri);
  1924.                                                         curRobotID = "";
  1925.                                                         if (centerOnSelected) CenterOnSelected();
  1926.                                                         redrawRobot = true;
  1927.                                                         PlayShapeSound();
  1928.                                                 }
  1929.                                         }
  1930.                                 }
  1931.                                
  1932.                         } else if (up && actionStep == 0 && curAction == NEW_PRISMATIC_JOINT) {
  1933.                                 MaybeStartCreatingPrismaticJoint();
  1934.                         } else if (up && actionStep == 1 && curAction == NEW_PRISMATIC_JOINT) {
  1935.                                 if (Util.GetDist(firstClickX, firstClickY, mouseXWorldPhys, mouseYWorldPhys) > 0.3)     MaybeFinishCreatingPrismaticJoint();
  1936.                         } else if (up && actionStep == 0 && (curAction == NEW_REVOLUTE_JOINT || curAction == NEW_FIXED_JOINT)) {
  1937.                                 MaybeCreateJoint();
  1938.                         } else if (up && curAction == BOX_SELECTING) {
  1939.                                 selectedParts = new Array();
  1940.                                 for (i = 0; i < allParts.length; i++) {
  1941.                                         if (allParts[i].isEditable && allParts[i].IntersectsBox(Math.min(firstClickX, mouseXWorldPhys), Math.min(firstClickY, mouseYWorldPhys), Math.abs(firstClickX - mouseXWorldPhys), Math.abs(firstClickY - mouseYWorldPhys))) {
  1942.                                                 selectedParts.push(allParts[i]);
  1943.                                         }
  1944.                                 }
  1945.                                
  1946.                                 if (selectedParts.length == 0) {
  1947.                                         m_sidePanel.visible = false;
  1948.                                 } else if (selectedParts.length == 1 && selectedParts[0] is Cannon) {
  1949.                                         m_sidePanel.ShowCannonPanel(selectedParts[0]);
  1950.                                 } else if (selectedParts.length == 1 && selectedParts[0] is ShapePart) {
  1951.                                         m_sidePanel.ShowObjectPanel(selectedParts[0]);
  1952.                                 } else if (selectedParts.length == 1 && selectedParts[0] is JointPart) {
  1953.                                         m_sidePanel.ShowJointPanel(selectedParts[0]);
  1954.                                 } else if (selectedParts.length == 1 && selectedParts[0] is TextPart) {
  1955.                                         m_sidePanel.ShowTextPanel(selectedParts[0]);
  1956.                                 } else if (selectedParts.length == 1 && selectedParts[0] is Thrusters) {
  1957.                                         m_sidePanel.ShowThrustersPanel(selectedParts[0]);
  1958.                                 } else {
  1959.                                         m_sidePanel.ShowMultiSelectPanel(selectedParts);
  1960.                                 }
  1961.                                 curAction = -1;
  1962.                                 redrawRobot = true;
  1963.                         } else if (up && curAction == FINALIZING_JOINT) {
  1964.                                 if (candidateJointType == NEW_PRISMATIC_JOINT || candidateJointType == NEW_THRUSTERS) {
  1965.                                         potentialJointPart1.highlightForJoint = false;
  1966.                                         var index:int = -1;
  1967.                                         for (i = 0; i < candidateJointParts.length; i++) {
  1968.                                                 if (potentialJointPart1 == candidateJointParts[i]) index = i;
  1969.                                         }
  1970.                                         index++;
  1971.                                         if (index == candidateJointParts.length) index = 0;
  1972.                                         potentialJointPart1 = candidateJointParts[index];
  1973.                                         potentialJointPart1.highlightForJoint = true;
  1974.                                 } else {
  1975.                                         potentialJointPart1.highlightForJoint = false;
  1976.                                         potentialJointPart2.highlightForJoint = false;
  1977.                                         var index1:int = -1, index2:int = -1;
  1978.                                         for (i = 0; i < candidateJointParts.length; i++) {
  1979.                                                 if (potentialJointPart1 == candidateJointParts[i]) index1 = i;
  1980.                                                 if (potentialJointPart2 == candidateJointParts[i]) index2 = i;
  1981.                                         }
  1982.                                         if (index1 == candidateJointParts.length - 2 && index2 == candidateJointParts.length - 1) {
  1983.                                                 index1 = 0;
  1984.                                                 index2 = 1;
  1985.                                         } else {
  1986.                                                 index2++;
  1987.                                                 if (index2 == candidateJointParts.length) {
  1988.                                                         index1++;
  1989.                                                         index2 = index1 + 1;
  1990.                                                 }
  1991.                                         }
  1992.                                         potentialJointPart1 = candidateJointParts[index1];
  1993.                                         potentialJointPart2 = candidateJointParts[index2];
  1994.                                        
  1995.                                         potentialJointPart1.highlightForJoint = true;
  1996.                                         potentialJointPart2.highlightForJoint = true;
  1997.                                 }
  1998.                         } else if (!up && curAction == NEW_TEXT && actionStep == 0) {
  1999.                                 firstClickX = mouseXWorldPhys;
  2000.                                 firstClickY = mouseYWorldPhys;
  2001.                                 actionStep++;
  2002.                         } else if (up && curAction == NEW_TEXT && actionStep == 1) {
  2003.                                 var finalClickX:Number = mouseXWorldPhys;
  2004.                                 var finalClickY:Number = mouseYWorldPhys;
  2005.                                 if (Math.abs(finalClickX - firstClickX) < 1 || Math.abs(finalClickY - firstClickY) < 0.5) {
  2006.                                         var avgX:Number = (firstClickX + finalClickX) / 2.0;
  2007.                                         var avgY:Number = (firstClickY + finalClickY) / 2.0;
  2008.                                         firstClickX = avgX - 2;
  2009.                                         firstClickY = avgY - 1;
  2010.                                         finalClickX = avgX + 2;
  2011.                                         finalClickY = avgY + 1;
  2012.                                 }
  2013.                                 var text:TextPart = new TextPart(this, Math.min(firstClickX, finalClickX), Math.min(firstClickY, finalClickY), Math.max(firstClickX, finalClickX) - Math.min(firstClickX, finalClickX), Math.max(firstClickY, finalClickY) - Math.min(firstClickY, finalClickY), "New Text");
  2014.                                 selectedParts.push(text);
  2015.                                 allParts.push(text);
  2016.                                 AddAction(new CreateAction(text));
  2017.                                 curAction = -1;
  2018.                                 curRobotID = "";
  2019.                                 m_sidePanel.ShowTextPanel(text);
  2020.                                 redrawRobot = true;
  2021.                         } else if (up && curAction == NEW_THRUSTERS) {
  2022.                                 MaybeCreateThrusters();
  2023.                         } else if (up && curAction == RESIZING_TEXT) {
  2024.                                 curAction = -1;
  2025.                         }
  2026.                 }
  2027.                
  2028.                 public function RefreshSidePanel():void {
  2029.                         if (selectedParts.length == 0 || selectingCondition) {
  2030.                                 m_sidePanel.visible = false;
  2031.                         } else if (selectedParts.length == 1 && selectedParts[0] is Cannon) {
  2032.                                 m_sidePanel.ShowCannonPanel(selectedParts[0] as Cannon);
  2033.                                 lastSelectedShape = null;
  2034.                         } else if (selectedParts.length == 1 && selectedParts[0] is ShapePart) {
  2035.                                 m_sidePanel.ShowObjectPanel(selectedParts[0] as ShapePart);
  2036.                                 lastSelectedShape = null;
  2037.                         } else if (selectedParts.length == 1 && selectedParts[0] is TextPart) {
  2038.                                 m_sidePanel.ShowTextPanel(selectedParts[0] as TextPart);
  2039.                                 lastSelectedText = null;
  2040.                         } else if (selectedParts.length == 1 && selectedParts[0] is JointPart) {
  2041.                                 m_sidePanel.ShowJointPanel(selectedParts[0] as JointPart);
  2042.                                 lastSelectedJoint = null;
  2043.                         } else if (selectedParts.length == 1 && selectedParts[0] is Thrusters) {
  2044.                                 m_sidePanel.ShowThrustersPanel(selectedParts[0] as Thrusters);
  2045.                                 lastSelectedThrusters = null;
  2046.                         } else {
  2047.                                 m_sidePanel.ShowMultiSelectPanel(selectedParts);
  2048.                         }
  2049.                 }
  2050.                
  2051.                 public function AddAction(a:Action):void {
  2052.                         while (lastAction + 1 != actions.length) {
  2053.                                 actions.pop();
  2054.                         }
  2055.                         lastAction = actions.length;
  2056.                         actions.push(a);
  2057.                 }
  2058.                
  2059.                 public function CenterOnSelected():void {
  2060.                         if (selectedParts.length == 1) {
  2061.                                 var centerX:Number, centerY:Number;
  2062.                                 if (selectedParts[0] is ShapePart || selectedParts[0] is Thrusters) {
  2063.                                         centerX = selectedParts[0].centerX;
  2064.                                         centerY = selectedParts[0].centerY;
  2065.                                 } else if (selectedParts[0] is JointPart) {
  2066.                                         centerX = selectedParts[0].anchorX;
  2067.                                         centerY = selectedParts[0].anchorY;
  2068.                                 } else if (selectedParts[0] is TextPart) {
  2069.                                         centerX = selectedParts[0].x + selectedParts[0].w / 2;
  2070.                                         centerY = selectedParts[0].y + selectedParts[0].h / 2;
  2071.                                 }
  2072.                                
  2073.                                 var oldX:Number = draw.m_drawXOff;
  2074.                                 var oldY:Number = draw.m_drawYOff;
  2075.                                 draw.m_drawXOff += World2ScreenX(centerX) - ZOOM_FOCUS_X;
  2076.                                 draw.m_drawYOff += World2ScreenY(centerY) - ZOOM_FOCUS_Y;
  2077.                                 if (oldX != draw.m_drawXOff || oldY != draw.m_drawYOff) {
  2078.                                         hasPanned = true;
  2079.                                 }
  2080.                         }
  2081.                 }
  2082.                
  2083.                 // BUTTON LISTENERS
  2084.                
  2085.                 public virtual function circleButton(e:MouseEvent):void {
  2086.                         if (!curRobotEditable || selectingCondition) return;
  2087.                         if (curAction == NEW_CIRCLE) {
  2088.                                 curAction = -1;
  2089.                                 redrawRobot = true;
  2090.                         } else {
  2091.                                 curAction = NEW_CIRCLE;
  2092.                                 actionStep = 0;
  2093.                                 selectedParts = new Array();
  2094.                                 m_sidePanel.visible = false;
  2095.                         }
  2096.                 }
  2097.                
  2098.                 public virtual function rectButton(e:MouseEvent):void {
  2099.                         if (!curRobotEditable || selectingCondition) return;
  2100.                         if (curAction == NEW_RECT) {
  2101.                                 curAction = -1;
  2102.                                 redrawRobot = true;
  2103.                         } else {
  2104.                                 curAction = NEW_RECT;
  2105.                                 actionStep = 0;
  2106.                                 selectedParts = new Array();
  2107.                                 m_sidePanel.visible = false;
  2108.                         }
  2109.                 }
  2110.                
  2111.                 public virtual function triangleButton(e:MouseEvent):void {
  2112.                         if (!curRobotEditable || selectingCondition) return;
  2113.                         if (curAction == NEW_TRIANGLE) {
  2114.                                 curAction = -1;
  2115.                                 redrawRobot = true;
  2116.                         } else {
  2117.                                 curAction = NEW_TRIANGLE;
  2118.                                 actionStep = 0;
  2119.                                 selectedParts = new Array();
  2120.                                 m_sidePanel.visible = false;
  2121.                         }
  2122.                 }
  2123.                
  2124.                 public virtual function fjButton(e:MouseEvent):void {
  2125.                         if (!curRobotEditable || selectingCondition) return;
  2126.                         if (curAction == NEW_FIXED_JOINT) {
  2127.                                 curAction = -1;
  2128.                                 redrawRobot = true;
  2129.                         } else {
  2130.                                 curAction = NEW_FIXED_JOINT;
  2131.                                 actionStep = 0;
  2132.                                 selectedParts = new Array();
  2133.                                 m_sidePanel.visible = false;
  2134.                                 potentialJointPart1 = null;
  2135.                                 potentialJointPart2 = null;
  2136.                                 copiedJoint = null;
  2137.                         }
  2138.                 }
  2139.                
  2140.                 public virtual function rjButton(e:MouseEvent):void {
  2141.                         if (!curRobotEditable || selectingCondition) return;
  2142.                         if (curAction == NEW_REVOLUTE_JOINT) {
  2143.                                 curAction = -1;
  2144.                                 redrawRobot = true;
  2145.                         } else {
  2146.                                 curAction = NEW_REVOLUTE_JOINT;
  2147.                                 actionStep = 0;
  2148.                                 selectedParts = new Array();
  2149.                                 m_sidePanel.visible = false;
  2150.                                 potentialJointPart1 = null;
  2151.                                 potentialJointPart2 = null;
  2152.                                 copiedJoint = null;
  2153.                         }
  2154.                 }
  2155.                
  2156.                 public virtual function pjButton(e:MouseEvent):void {
  2157.                         if (!curRobotEditable || selectingCondition) return;
  2158.                         if (curAction == NEW_PRISMATIC_JOINT) {
  2159.                                 curAction = -1;
  2160.                                 redrawRobot = true;
  2161.                         } else {
  2162.                                 curAction = NEW_PRISMATIC_JOINT;
  2163.                                 actionStep = 0;
  2164.                                 selectedParts = new Array();
  2165.                                 m_sidePanel.visible = false;
  2166.                                 potentialJointPart1 = null;
  2167.                                 potentialJointPart2 = null;
  2168.                                 copiedJoint = null;
  2169.                         }
  2170.                 }
  2171.                
  2172.                 public virtual function textButton(e:MouseEvent):void {
  2173.                         if (!curRobotEditable || selectingCondition) return;
  2174.                         if (curAction == NEW_TEXT) {
  2175.                                 curAction = -1;
  2176.                                 redrawRobot = true;
  2177.                         } else {
  2178.                                 curAction = NEW_TEXT;
  2179.                                 actionStep = 0;
  2180.                                 selectedParts = new Array();
  2181.                                 m_sidePanel.visible = false;
  2182.                         }
  2183.                 }
  2184.                
  2185.                 public virtual function thrustersButton(e:MouseEvent):void {
  2186.                         if (/*Main.premiumMode*/ true) {
  2187.                                 if (!curRobotEditable || selectingCondition) return;
  2188.                                 curAction = NEW_THRUSTERS;
  2189.                                 actionStep = 0;
  2190.                                 selectedParts = new Array();
  2191.                                 m_sidePanel.visible = false;
  2192.                                 copiedThrusters = null;
  2193.                         } else {
  2194.                                 m_fader.visible = true;
  2195.                                 ShowConfirmDialog("That feature is only available to IncrediBots supporters. Become an IncrediBots supporter?", 8);
  2196.                         }
  2197.                 }
  2198.  
  2199.                 public virtual function cannonButton(e:MouseEvent):void {
  2200.                         if (/*Main.premiumMode*/ true) {
  2201.                                 if (!curRobotEditable || selectingCondition) return;
  2202.                                 curAction = NEW_CANNON;
  2203.                                 actionStep = 0;
  2204.                                 selectedParts = new Array();
  2205.                                 m_sidePanel.visible = false;
  2206.                         } else {
  2207.                                 m_fader.visible = true;
  2208.                                 ShowConfirmDialog("That feature is only available to IncrediBots supporters. Become an IncrediBots supporter?", 8);
  2209.                         }
  2210.                 }
  2211.  
  2212.                 private function mochiAdStarted():void {
  2213.                         adStarted = true;
  2214.                 }
  2215.                
  2216.                 private function mochiAdFinished():void {
  2217.                         adStarted = false;
  2218.                         playButton(new MouseEvent(""), false);
  2219.                 }
  2220.                
  2221.                 public virtual function playButton(e:MouseEvent, maybeShowAd:Boolean = true):void {
  2222.                         if (selectingCondition) return;
  2223.                         /*var time:int = getTimer();
  2224.                         if (!Main.DEBUG_VERSION && !Main.premiumMode && maybeShowAd && time > Main.lastAdTime + 30 * 60 * 1000) {
  2225.                                 MochiAd.showInterLevelAd({clip:root, id:"1913f89f65e17063", res:"800x600", ad_started:mochiAdStarted, ad_finished:mochiAdFinished});
  2226.                                 Main.lastAdTime = time;
  2227.                         }*/
  2228.                        
  2229.                         if (!adStarted) {
  2230.                                 CheckIfPartsFit();
  2231.                                 var tooManyShapes:Boolean = TooManyShapes();
  2232.                                 if ((partsFit && !tooManyShapes) || playingReplay) {
  2233.                                         m_guiPanel.ShowGamePanel();
  2234.                                         m_sidePanel.visible = false;
  2235.                                         selectedParts = new Array();
  2236.                                         curAction = -1;
  2237.                                         paused = false;
  2238.                                         if (!simStarted) {
  2239.                                                 frameCounter = 0;
  2240.                                                 m_guiPanel.SetTimer(frameCounter);
  2241.                                                 cameraMovements = new Array();
  2242.                                                 cameraMovements.push(new CameraMovement(0, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, m_physScale));
  2243.                                                 keyPresses = new Array();
  2244.                                                 syncPoints = new Array();
  2245.                                                 cannonballs = new Array();
  2246.                                                 if (playingReplay) {
  2247.                                                         replay.syncPointIndex = 0;
  2248.                                                         replay.cameraMovementIndex = 0;
  2249.                                                         replay.keyPressIndex = 0;
  2250.                                                         if (replay.syncPoints.length > 0) {
  2251.                                                                 replaySplineXs = ComputeReplaySplines(0);
  2252.                                                                 replaySplineYs = ComputeReplaySplines(1);
  2253.                                                                 replaySplineAngles = ComputeReplaySplines(2);
  2254.                                                         }
  2255.                                                 }
  2256.                                                 simStarted = true;
  2257.                                                 autoPanning = true;
  2258.                                                 canSaveReplay = true;
  2259.                                                 for (var i:int = 0; i < allParts.length; i++) {
  2260.                                                         allParts[i].checkedCollisionGroup = false;
  2261.                                                 }
  2262.                                                 for (i = 0; i < allParts.length; i++) {
  2263.                                                         if (allParts[i] is ShapePart) allParts[i].SetCollisionGroup(-(i + 1));
  2264.                                                 }
  2265.                                                
  2266.                                                 CreateWorld();
  2267.        
  2268.                                                 for (i = allParts.length; i >= 0; i--) {
  2269.                                                         if (allParts[i] is ShapePart || allParts[i] is TextPart) allParts[i].Init(m_world);
  2270.                                                 }
  2271.                                                 collisionGroup = 0x0001;
  2272.                                                 for (i = 0; i < allParts.length; i++) {
  2273.                                                         if (allParts[i] is PrismaticJoint) collisionGroup *= 2;
  2274.                                                         if (allParts[i] is JointPart || allParts[i] is Thrusters) allParts[i].Init(m_world);
  2275.                                                 }
  2276.                                                
  2277.                                                 cameraPart = null;
  2278.                                                 for (i = 0; i < allParts.length; i++) {
  2279.                                                         if (allParts[i] is ShapePart && allParts[i].isCameraFocus && allParts[i].isEnabled) cameraPart = allParts[i];
  2280.                                                 }
  2281.                                                 if (!cameraPart) cameraPart = FindCenterOfRobot();
  2282.                                                 savedDrawXOff = Screen2WorldX(ZOOM_FOCUS_X);
  2283.                                                 savedDrawYOff = Screen2WorldY(ZOOM_FOCUS_Y);
  2284.                                         }
  2285.                                 } else {
  2286.                                         m_fader.visible = true;
  2287.                                         if (!partsFit) ShowDialog3("You must fit your robot inside the starting box first!");
  2288.                                         else if (tooManyShapes) ShowDialog3("Your robot contains too many shapes!  (Limit 500)");
  2289.                                         m_progressDialog.ShowOKButton();
  2290.                                         m_progressDialog.StopTimer();
  2291.                                 }
  2292.                         }
  2293.                 }
  2294.                
  2295.                 public virtual function editButton(e:MouseEvent, confirmed:Boolean = false):void {
  2296.                        
  2297.                 }
  2298.                
  2299.                 public function pauseButton(e:MouseEvent):void {
  2300.                         if (playingReplay && replay.Update(frameCounter)) ShowPostReplayWindow();
  2301.                         m_guiPanel.ShowPausePanel(!playingReplay);
  2302.                         paused = true;
  2303.                 }
  2304.                
  2305.                 public virtual function resetButton(e:MouseEvent, rateRobot:Boolean = true):void {
  2306.                         if (playingReplay) {
  2307.                                 for (var i:int = 0; i < allParts.length; i++) {
  2308.                                         allParts[i].UnInit(m_world);
  2309.                                 }
  2310.                                 simStarted = false;
  2311.                                 playButton(e, false);
  2312.                         } else {
  2313.                                 m_guiPanel.ShowEditPanel();
  2314.                                 paused = true;
  2315.                                 simStarted = false;
  2316.                                 playingReplay = false;
  2317.                                 for (i = 0; i < allParts.length; i++) {
  2318.                                         allParts[i].UnInit(m_world);
  2319.                                 }
  2320.                                 draw.m_drawXOff = savedDrawXOff * m_physScale - ZOOM_FOCUS_X;
  2321.                                 draw.m_drawYOff = savedDrawYOff * m_physScale - ZOOM_FOCUS_Y;
  2322.                                 hasPanned = true;
  2323.                                 if (rateRobot) {
  2324.                                         if (curChallengeID != "" && curChallengePublic && !ratedCurChallenge && !LSOManager.HasRatedChallenge(curChallengeID)) {
  2325.                                                 ratedCurChallenge = true;
  2326.                                                 if (m_rateDialog) removeChild(m_rateDialog);
  2327.                                                 m_rateDialog = new RateWindow(this, 2, 0, true);
  2328.                                                 addChild(m_rateDialog);
  2329.                                                 m_fader.visible = true;
  2330.                                         } else if (curRobotID != "" && curRobotPublic && !ratedCurRobot && !LSOManager.HasRatedRobot(curRobotID)) {
  2331.                                                 ratedCurRobot = true;
  2332.                                                 if (m_rateDialog) removeChild(m_rateDialog);
  2333.                                                 m_rateDialog = new RateWindow(this, 0, 0, true);
  2334.                                                 addChild(m_rateDialog);
  2335.                                                 m_fader.visible = true;
  2336.                                                 paused = true;
  2337.                                         }
  2338.                                 }
  2339.                         }
  2340.                         wonChallenge = false;
  2341.                         redrawBuildArea = true;
  2342.                 }
  2343.                
  2344.                 public virtual function rewindButton(e:MouseEvent, makeThemRate:Boolean = true):void {
  2345.                         if (!playingReplay) {
  2346.                                 resetButton(e, false);
  2347.                                 playButton(e);
  2348.                         } else if (viewingUnsavedReplay) {
  2349.                                 paused = true;
  2350.                                 simStarted = false;
  2351.                                 playingReplay = false;
  2352.                                 wonChallenge = false;
  2353.                                 viewingUnsavedReplay = false;
  2354.                                 m_guiPanel.ShowEditPanel(true);
  2355.                                 for (var i:int = 0; i < allParts.length; i++) {
  2356.                                         allParts[i].UnInit(m_world);
  2357.                                 }
  2358.                                 draw.m_drawXOff = savedDrawXOff * m_physScale - ZOOM_FOCUS_X;
  2359.                                 draw.m_drawYOff = savedDrawYOff * m_physScale - ZOOM_FOCUS_Y;
  2360.                                 hasPanned = true;
  2361.                                 redrawBuildArea = true;
  2362.                         } else {
  2363.                                 if (makeThemRate && curReplayID != "" && !ratedCurReplay && curReplayPublic && !LSOManager.HasRatedReplay(curReplayID)) {
  2364.                                         ratedCurReplay = true;
  2365.                                         if (m_rateDialog) removeChild(m_rateDialog);
  2366.                                         m_rateDialog = new RateWindow(this, 1, 5);
  2367.                                         addChild(m_rateDialog);
  2368.                                         m_fader.visible = true;
  2369.                                 } else {
  2370.                                         Main.changeControllers = true;
  2371.                                         playingReplay = false;
  2372.                                         showTutorial = false;
  2373.                                         replayParts = new Array();
  2374.                                         curRobotID = "";
  2375.                                         curRobotEditable = true;
  2376.                                         curReplayID = "";
  2377.                                 }
  2378.                         }
  2379.                 }
  2380.                
  2381.                 public function reportButton(e:MouseEvent):void {
  2382.                         if (selectingCondition) return;
  2383.                         if (playingReplay && curReplayID != "" && curReplayPublic) {
  2384.                                 if (userName == "_Public") {
  2385.                                         clickedReport = true;
  2386.                                         loginButton(e, true, false);
  2387.                                 } else {
  2388.                                         if (m_reportWindow) removeChild(m_reportWindow);
  2389.                                         m_reportWindow = new ReportWindow(this, 1, curReplayID);
  2390.                                         addChild(m_reportWindow);
  2391.                                         m_fader.visible = true;
  2392.                                         m_guiPanel.ShowPausePanel(!playingReplay);
  2393.                                         paused = true;
  2394.                                 }
  2395.                         } else if (curChallengeID != "" && curChallengePublic) {
  2396.                                 if (userName == "_Public") {
  2397.                                         clickedReport = true;
  2398.                                         loginButton(e, true, false);
  2399.                                 } else {
  2400.                                         if (m_reportWindow) removeChild(m_reportWindow);
  2401.                                         m_reportWindow = new ReportWindow(this, 2, curChallengeID);
  2402.                                         addChild(m_reportWindow);
  2403.                                         m_fader.visible = true;
  2404.                                         m_guiPanel.ShowPausePanel(!playingReplay);
  2405.                                         paused = true;
  2406.                                 }
  2407.                         } else if (curRobotID != "" && curRobotPublic) {
  2408.                                 if (userName == "_Public") {
  2409.                                         clickedReport = true;
  2410.                                         loginButton(e, true, false);
  2411.                                 } else {
  2412.                                         if (m_reportWindow) removeChild(m_reportWindow);
  2413.                                         m_reportWindow = new ReportWindow(this, 0, curRobotID);
  2414.                                         addChild(m_reportWindow);
  2415.                                         m_fader.visible = true;
  2416.                                         m_guiPanel.ShowPausePanel(!playingReplay);
  2417.                                         paused = true;
  2418.                                 }
  2419.                         } else {
  2420.                                 m_fader.visible = true;
  2421.                                 ShowDialog3("You can only report publicly saved robots.");
  2422.                                 m_progressDialog.ShowOKButton();
  2423.                                 m_progressDialog.StopTimer();
  2424.                         }
  2425.                 }
  2426.                
  2427.                 public function finishReporting(e:Event):void {
  2428.                         var threadID:int = Database.FinishReporting(e);
  2429.                         if (threadID != -1) {
  2430.                                 ShowDialog3("Thank you, the moderators have been notified.");
  2431.                                 m_progressDialog.ShowOKButton();
  2432.                                 m_progressDialog.StopTimer();
  2433.                                 Main.ShowMouse();
  2434.                         }
  2435.                 }
  2436.                
  2437.                 public function featureButton(e:MouseEvent):void {
  2438.                         if (selectingCondition) return;
  2439.                         if (playingReplay && curReplayID != "" && curReplayPublic) {
  2440.                                 Database.FeatureReplay(curReplayID, !curReplayFeatured, finishFeaturing);
  2441.                                 m_fader.visible = true;
  2442.                                 ShowDialog("Featuring...");
  2443.                                 Main.ShowHourglass();
  2444.                         } else if (curChallengeID != "" && curChallengePublic) {
  2445.                                 Database.FeatureChallenge(curChallengeID, !curChallengeFeatured, finishFeaturing);
  2446.                                 m_fader.visible = true;
  2447.                                 ShowDialog("Featuring...");
  2448.                                 Main.ShowHourglass();
  2449.                         } else if (curRobotID != "" && curRobotPublic) {
  2450.                                 Database.FeatureRobot(curRobotID, !curRobotFeatured, finishFeaturing);
  2451.                                 m_fader.visible = true;
  2452.                                 ShowDialog("Featuring...");
  2453.                                 Main.ShowHourglass();
  2454.                         } else {
  2455.                                 m_fader.visible = true;
  2456.                                 ShowDialog3("You can only feature publicly saved robots.");
  2457.                                 m_progressDialog.ShowOKButton();
  2458.                                 m_progressDialog.StopTimer();
  2459.                         }
  2460.                 }
  2461.                
  2462.                 private function finishFeaturing(e:Event):void {
  2463.                         var retVal:Boolean = Database.FinishFeaturing(e);
  2464.                         if (retVal) {
  2465.                                 m_progressDialog.SetMessage("Success!");
  2466.                                 m_progressDialog.HideInXSeconds(1);
  2467.                                 m_fader.visible = false;
  2468.                                 Main.ShowMouse();
  2469.                                 if (playingReplay) curReplayFeatured = !curReplayFeatured;
  2470.                                 else if (curChallengeID != "") curChallengeFeatured = !curChallengeFeatured;
  2471.                                 else curRobotFeatured = !curRobotFeatured;
  2472.                         }
  2473.                 }
  2474.                
  2475.                 public function rateButton(e:MouseEvent):void {
  2476.                         if (selectingCondition) return;
  2477.                         if (curRobotID != "" && curRobotPublic && !LSOManager.HasRatedRobot(curRobotID)) {
  2478.                                 m_fader.visible = true;
  2479.                                 if (m_rateDialog) removeChild(m_rateDialog);
  2480.                                 m_rateDialog = new RateWindow(this, 0);
  2481.                                 addChild(m_rateDialog);
  2482.                         } else if (curRobotID == "" || !curRobotPublic) {
  2483.                                 m_fader.visible = true;
  2484.                                 ShowDialog3("You need to save your robot publicly first!");
  2485.                                 m_progressDialog.ShowOKButton();
  2486.                                 m_progressDialog.StopTimer();
  2487.                         } else {
  2488.                                 m_fader.visible = true;
  2489.                                 ShowDialog3("You've already rated this robot!");
  2490.                                 m_progressDialog.ShowOKButton();
  2491.                                 m_progressDialog.StopTimer();
  2492.                         }
  2493.                 }
  2494.                
  2495.                 public function rateWindowClosed(rating:int, redirect:int):void {
  2496.                         m_rateDialog.visible = false;
  2497.                         if (playingReplay && curReplayID != "" && curReplayPublic) {
  2498.                                 Database.RateReplay(curReplayID, rating, finishRatingReplay);
  2499.                         } else if (curChallengeID != "" && curChallengePublic) {
  2500.                                 Database.RateChallenge(curChallengeID, rating, finishRatingChallenge);
  2501.                         } else {
  2502.                                 Database.RateRobot(curRobotID, rating, finishRatingRobot);
  2503.                         }
  2504.                         redirectAfterRating = redirect;
  2505.                         m_fader.visible = true;
  2506.                         ShowDialog("Rating...");
  2507.                         Main.ShowHourglass();
  2508.                         curAction = -1;
  2509.                 }
  2510.                
  2511.                 public function conditionsButton(e:MouseEvent):void {
  2512.                         curAction = -1;
  2513.                         boxText.visible = false;
  2514.                         horizLineText.visible = false;
  2515.                         vertLineText.visible = false;
  2516.                         shapeText.visible = false;
  2517.                         m_sidePanel.visible = false;
  2518.                         if (m_conditionsDialog) removeChild(m_conditionsDialog);
  2519.                         m_conditionsDialog = new ConditionsWindow(this as ControllerChallenge);
  2520.                         addChild(m_conditionsDialog);
  2521.                         m_fader.visible = true;
  2522.                 }
  2523.  
  2524.                 public function restrictionsButton(e:MouseEvent):void {
  2525.                         if (selectingCondition) return;
  2526.                         m_sidePanel.visible = false;
  2527.                         if (m_restrictionsDialog) removeChild(m_restrictionsDialog);
  2528.                         m_restrictionsDialog = new RestrictionsWindow(this as ControllerChallenge);
  2529.                         addChild(m_restrictionsDialog);
  2530.                         m_fader.visible = true;
  2531.                         saveAfterRestrictions = false;
  2532.                 }
  2533.  
  2534.                 public function buildBoxButton(e:MouseEvent):void {
  2535.                         if (selectingCondition) return;
  2536.                         /*if (ControllerChallenge.challenge.buildAreas.length != 0) {
  2537.                                 m_fader.visible = true;
  2538.                                 if (m_progressDialog) removeChild(m_progressDialog);
  2539.                                 m_progressDialog = new DialogWindow(this, "One or more build boxes already exists.  Would you like to keep them or delete them?", true, false, true);
  2540.                                 m_progressDialog.ShowBuildBoxButtons();
  2541.                                 addChild(m_progressDialog);
  2542.                         }*/
  2543.                         curAction = DRAWING_BUILD_BOX;
  2544.                         actionStep = 0;
  2545.                 }
  2546.                
  2547.                 public function sandboxSettingsButton(e:MouseEvent):void {
  2548.                         if (!curRobotEditable || selectingCondition) return;
  2549.                         if (!simStarted) {
  2550.                                 if (this is ControllerSandbox && (!(this is ControllerChallenge) || !ControllerChallenge.playOnlyMode)) {
  2551.                                         m_sandboxWindow = new AdvancedSandboxWindow(this, ControllerSandbox.settings);
  2552.                                         m_fader.visible = true;
  2553.                                         addChild(m_sandboxWindow);
  2554.                                 } else {
  2555.                                         m_fader.visible = true;
  2556.                                         ShowDialog3("That feature is only available in Sandbox mode!");
  2557.                                         m_progressDialog.ShowOKButton();
  2558.                                         m_progressDialog.StopTimer();
  2559.                                 }
  2560.                         }
  2561.                 }
  2562.                
  2563.                 public virtual override function commentButton(e:MouseEvent, robotID:String = "", robotPublic:Boolean = false):void {
  2564.                         if (selectingCondition) return;
  2565.                         if (robotID == "") {
  2566.                                 robotID = curRobotID;
  2567.                                 robotPublic = curRobotPublic;
  2568.                         }
  2569.                         if (robotID != "" && robotPublic) {
  2570.                                 Database.CommentOnRobot(robotID, finishCommenting);
  2571.                                 m_fader.visible = true;
  2572.                                 ShowDialog("Connecting to forum...");
  2573.                                 Main.ShowHourglass();
  2574.                                 curAction = -1;
  2575.                         } else {
  2576.                                 m_fader.visible = true;
  2577.                                 ShowDialog3("You need to save your robot publicly first!");
  2578.                                 m_progressDialog.ShowOKButton();
  2579.                                 m_progressDialog.StopTimer();
  2580.                         }
  2581.                 }
  2582.  
  2583.                 public function finishCommenting(e:Event):void {
  2584.                         if (!Database.waitingForResponse || (Database.curTransactionType != Database.ACTION_COMMENT_ROBOT && Database.curTransactionType != Database.ACTION_COMMENT_REPLAY)) return;
  2585.                         var threadID:int = Database.FinishCommenting(e);
  2586.                         if (threadID != -1) {
  2587.                                 if (m_chooserWindow && m_chooserWindow.visible) m_chooserWindow.HideFader();
  2588.                                 else m_fader.visible = false;
  2589.                                 m_progressDialog.visible = false;
  2590.                                 Main.BrowserRedirect("http://www.incredibots.com/forums/posting.php?mode=reply&t=" + threadID + (userName == "_Public" ? "" : "&sid=" + sessionID), true);
  2591.                                 Main.ShowMouse();
  2592.                         }
  2593.                 }
  2594.                
  2595.                 public function finishRatingRobot(e:Event):void {
  2596.                         if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_RATE_ROBOT) return;
  2597.                         var retVal:Boolean = Database.FinishRating(e);
  2598.                         if (retVal) {
  2599.                                 LSOManager.SetRobotRated(curRobotID);
  2600.                                 m_progressDialog.SetMessage("Success!");
  2601.                                 m_progressDialog.HideInXSeconds(1);
  2602.                                 if (m_postReplayWindow && m_postReplayWindow.visible) m_postReplayWindow.HideFader();
  2603.                                 else m_fader.visible = false;
  2604.                                 m_rateDialog.visible = false;
  2605.                                 Main.ShowMouse();
  2606.                         }
  2607.                         if (redirectAfterRating == 1) {
  2608.                                 loadButton(new MouseEvent(""));
  2609.                         } else if (redirectAfterRating == 2) {
  2610.                                 loadRobotButton(new MouseEvent(""));                           
  2611.                         } else if (redirectAfterRating == 3) {
  2612.                                 loadReplayButton(new MouseEvent(""));                          
  2613.                         } else if (redirectAfterRating == 4) {
  2614.                                 loadChallengeButton(new MouseEvent(""));                               
  2615.                         } else if (redirectAfterRating == 5) {
  2616.                                 rewindButton(new MouseEvent(""));                              
  2617.                         }
  2618.                         redirectAfterRating = 0;
  2619.                 }
  2620.  
  2621.                 public function finishRatingReplay(e:Event):void {
  2622.                         if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_RATE_REPLAY) return;
  2623.                         var retVal:Boolean = Database.FinishRating(e);
  2624.                         if (retVal) {
  2625.                                 LSOManager.SetReplayRated(curReplayID);
  2626.                                 m_progressDialog.SetMessage("Success!");
  2627.                                 m_progressDialog.HideInXSeconds(1);
  2628.                                 if (m_postReplayWindow && m_postReplayWindow.visible) m_postReplayWindow.HideFader();
  2629.                                 else m_fader.visible = false;
  2630.                                 m_rateDialog.visible = false;
  2631.                                 Main.ShowMouse();
  2632.                         }
  2633.                         if (redirectAfterRating == 1) {
  2634.                                 loadButton(new MouseEvent(""));
  2635.                         } else if (redirectAfterRating == 2) {
  2636.                                 loadRobotButton(new MouseEvent(""));                           
  2637.                         } else if (redirectAfterRating == 3) {
  2638.                                 loadReplayButton(new MouseEvent(""));                          
  2639.                         } else if (redirectAfterRating == 4) {
  2640.                                 loadChallengeButton(new MouseEvent(""));                               
  2641.                         } else if (redirectAfterRating == 5) {
  2642.                                 rewindButton(new MouseEvent(""));                              
  2643.                         }
  2644.                         redirectAfterRating = 0;
  2645.                 }
  2646.  
  2647.                 public function finishRatingChallenge(e:Event):void {
  2648.                         if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_RATE_CHALLENGE) return;
  2649.                         var retVal:Boolean = Database.FinishRating(e);
  2650.                         if (retVal) {
  2651.                                 LSOManager.SetChallengeRated(curChallengeID);
  2652.                                 m_progressDialog.SetMessage("Success!");
  2653.                                 m_progressDialog.HideInXSeconds(1);
  2654.                                 if (m_postReplayWindow && m_postReplayWindow.visible) m_postReplayWindow.HideFader();
  2655.                                 else m_fader.visible = false;
  2656.                                 m_rateDialog.visible = false;
  2657.                                 Main.ShowMouse();
  2658.                         }
  2659.                         if (redirectAfterRating == 1) {
  2660.                                 loadButton(new MouseEvent(""));
  2661.                         } else if (redirectAfterRating == 2) {
  2662.                                 loadRobotButton(new MouseEvent(""));                           
  2663.                         } else if (redirectAfterRating == 3) {
  2664.                                 loadReplayButton(new MouseEvent(""));                          
  2665.                         } else if (redirectAfterRating == 4) {
  2666.                                 loadChallengeButton(new MouseEvent(""));                               
  2667.                         } else if (redirectAfterRating == 5) {
  2668.                                 rewindButton(new MouseEvent(""));                              
  2669.                         }
  2670.                         redirectAfterRating = 0;
  2671.                 }
  2672.                
  2673.                 public virtual override function embedButton(e:MouseEvent, robotID:String = "", robotPublic:Boolean = false):void {
  2674.                         if (selectingCondition) return;
  2675.                         if (robotID == "") {
  2676.                                 robotID = curRobotID;
  2677.                                 robotPublic = curRobotPublic;
  2678.                         }
  2679.                         if (robotID != "" && robotPublic) {
  2680.                                 m_fader.visible = true;
  2681.                                 ShowLinkDialog("Copy the HTML below into your\n  website to embed this robot.", null, false, robotID);
  2682.                         } else {
  2683.                                 m_fader.visible = true;
  2684.                                 ShowDialog3("You need to save your robot publicly first!");
  2685.                                 m_progressDialog.ShowOKButton();
  2686.                                 m_progressDialog.StopTimer();
  2687.                         }
  2688.                 }
  2689.                
  2690.                 public virtual override function linkButton(e:MouseEvent, robotID:String = "", robotPublic:Boolean = false):void {
  2691.                         if (selectingCondition) return;
  2692.                         if (robotID == "") {
  2693.                                 robotID = curRobotID;
  2694.                                 robotPublic = curRobotPublic;
  2695.                         }
  2696.                         if (robotID != "" && robotPublic) {
  2697.                                 m_fader.visible = true;
  2698.                                 ShowLinkDialog("     Use the link below to\n        link to this robot.", "http://incredibots2.com/?robotID=" + robotID);
  2699.                         } else {
  2700.                                 m_fader.visible = true;
  2701.                                 ShowDialog3("You need to save your robot publicly first!");
  2702.                                 m_progressDialog.ShowOKButton();
  2703.                                 m_progressDialog.StopTimer();
  2704.                         }
  2705.                 }
  2706.                
  2707.                 public function rateReplayButton(e:MouseEvent):void {
  2708.                         if (selectingCondition) return;
  2709.                         if (curReplayID != "" && curReplayPublic && !LSOManager.HasRatedReplay(curReplayID)) {
  2710.                                 m_fader.visible = true;
  2711.                                 if (m_rateDialog) removeChild(m_rateDialog);
  2712.                                 m_rateDialog = new RateWindow(this, 1);
  2713.                                 addChild(m_rateDialog);
  2714.                         } else if (curReplayID == "" || !curReplayPublic) {
  2715.                                 m_fader.visible = true;
  2716.                                 ShowDialog3("You need to save your replay publicly first!");
  2717.                                 m_progressDialog.ShowOKButton();
  2718.                                 m_progressDialog.StopTimer();
  2719.                         } else {
  2720.                                 m_fader.visible = true;
  2721.                                 ShowDialog3("You've already rated this replay!");
  2722.                                 m_progressDialog.ShowOKButton();
  2723.                                 m_progressDialog.StopTimer();
  2724.                         }
  2725.                 }
  2726.                
  2727.                 public virtual override function commentReplayButton(e:MouseEvent, replayID:String = "", replayPublic:Boolean = false):void {
  2728.                         if (replayID == "") {
  2729.                                 replayID = curReplayID;
  2730.                                 replayPublic = curReplayPublic;
  2731.                         }
  2732.                         if (replayID != "" && replayPublic) {
  2733.                                 Database.CommentOnReplay(replayID, finishCommenting);
  2734.                                 m_fader.visible = true;
  2735.                                 ShowDialog("Connecting to forum...");
  2736.                                 Main.ShowHourglass();
  2737.                                 curAction = -1;
  2738.                         } else {
  2739.                                 m_fader.visible = true;
  2740.                                 ShowDialog3("You need to save your replay publicly first!");
  2741.                                 m_progressDialog.ShowOKButton();
  2742.                                 m_progressDialog.StopTimer();
  2743.                         }
  2744.                 }
  2745.                
  2746.                 public virtual override function embedReplayButton(e:MouseEvent, replayID:String = "", replayPublic:Boolean = false):void {
  2747.                         if (replayID == "") {
  2748.                                 replayID = curReplayID;
  2749.                                 replayPublic = curReplayPublic;
  2750.                         }
  2751.                         if (replayID != "" && replayPublic) {
  2752.                                 m_fader.visible = true;
  2753.                                 ShowLinkDialog("Copy the HTML below into your\n  website to embed this replay.", null, true, replayID);
  2754.                         } else {
  2755.                                 m_fader.visible = true;
  2756.                                 ShowDialog3("You need to save your replay publicly first!");
  2757.                                 m_progressDialog.ShowOKButton();
  2758.                                 m_progressDialog.StopTimer();
  2759.                         }
  2760.                 }
  2761.  
  2762.                 public virtual override function linkReplayButton(e:MouseEvent, replayID:String = "", replayPublic:Boolean = false):void {
  2763.                         if (replayID == "") {
  2764.                                 replayID = curReplayID;
  2765.                                 replayPublic = curReplayPublic;
  2766.                         }
  2767.                         if (replayID != "" && replayPublic) {
  2768.                                 m_fader.visible = true;
  2769.                                 ShowLinkDialog("     Use the link below to\n       link to this replay.", "http://incredibots2.com/?replayID=" + replayID);
  2770.                         } else {
  2771.                                 m_fader.visible = true;
  2772.                                 ShowDialog3("You need to save your replay publicly first!");
  2773.                                 m_progressDialog.ShowOKButton();
  2774.                                 m_progressDialog.StopTimer();
  2775.                         }
  2776.                 }
  2777.  
  2778.                 public function rateChallengeButton(e:MouseEvent):void {
  2779.                         if (selectingCondition) return;
  2780.                         if (curChallengeID != "" && curChallengePublic && !LSOManager.HasRatedChallenge(curChallengeID)) {
  2781.                                 m_fader.visible = true;
  2782.                                 if (m_rateDialog) removeChild(m_rateDialog);
  2783.                                 m_rateDialog = new RateWindow(this, 2);
  2784.                                 addChild(m_rateDialog);
  2785.                         } else if (curChallengeID == "" || !curChallengePublic) {
  2786.                                 m_fader.visible = true;
  2787.                                 ShowDialog3("You need to save your challenge publicly first!");
  2788.                                 m_progressDialog.ShowOKButton();
  2789.                                 m_progressDialog.StopTimer();
  2790.                         } else {
  2791.                                 m_fader.visible = true;
  2792.                                 ShowDialog3("You've already rated this challenge!");
  2793.                                 m_progressDialog.ShowOKButton();
  2794.                                 m_progressDialog.StopTimer();
  2795.                         }
  2796.                 }
  2797.  
  2798.                 public virtual override function commentChallengeButton(e:MouseEvent, challengeID:String = "", challengePublic:Boolean = false):void {
  2799.                         if (selectingCondition) return;
  2800.                         if (challengeID == "") {
  2801.                                 challengeID = curChallengeID;
  2802.                                 challengePublic = curChallengePublic;
  2803.                         }
  2804.                         if (challengeID != "" && challengePublic) {
  2805.                                 Database.CommentOnChallenge(challengeID, finishCommenting);
  2806.                                 m_fader.visible = true;
  2807.                                 ShowDialog("Connecting to forum...");
  2808.                                 Main.ShowHourglass();
  2809.                                 curAction = -1;
  2810.                         } else {
  2811.                                 m_fader.visible = true;
  2812.                                 ShowDialog3("You need to save your challenge publicly first!");
  2813.                                 m_progressDialog.ShowOKButton();
  2814.                                 m_progressDialog.StopTimer();
  2815.                         }
  2816.                 }
  2817.                
  2818.                 public virtual override function embedChallengeButton(e:MouseEvent, challengeID:String = "", challengePublic:Boolean = false):void {
  2819.                         if (selectingCondition) return;
  2820.                         if (challengeID == "") {
  2821.                                 challengeID = curChallengeID;
  2822.                                 challengePublic = curChallengePublic;
  2823.                         }
  2824.                         if (challengeID != "" && challengePublic) {
  2825.                                 m_fader.visible = true;
  2826.                                 ShowLinkDialog("Copy the HTML below into your\n  website to embed this challenge.", null, false, challengeID, true);
  2827.                         } else {
  2828.                                 m_fader.visible = true;
  2829.                                 ShowDialog3("You need to save your challenge publicly first!");
  2830.                                 m_progressDialog.ShowOKButton();
  2831.                                 m_progressDialog.StopTimer();
  2832.                         }
  2833.                 }
  2834.  
  2835.                 public virtual override function linkChallengeButton(e:MouseEvent, challengeID:String = "", challengePublic:Boolean = false):void {
  2836.                         if (selectingCondition) return;
  2837.                         if (challengeID == "") {
  2838.                                 challengeID = curChallengeID;
  2839.                                 challengePublic = curChallengePublic;
  2840.                         }
  2841.                         if (challengeID != "" && challengePublic) {
  2842.                                 m_fader.visible = true;
  2843.                                 ShowLinkDialog("     Use the link below to\n       link to this challenge.", "http://incredibots2.com/?challengeID=" + challengeID);
  2844.                         } else {
  2845.                                 m_fader.visible = true;
  2846.                                 ShowDialog3("You need to save your challenge publicly first!");
  2847.                                 m_progressDialog.ShowOKButton();
  2848.                                 m_progressDialog.StopTimer();
  2849.                         }
  2850.                 }
  2851.                
  2852.                 public virtual function tutorialButton(e:MouseEvent):void {
  2853.                         if (m_tutorialDialog) {
  2854.                                 m_tutorialDialog.visible = true;
  2855.                                 m_tutorialDialog.ResetPosition();
  2856.                         }
  2857.                 }
  2858.                
  2859.                 public virtual function rotateButton(e:MouseEvent):void {
  2860.                         if (!curRobotEditable) return;
  2861.                         for (var i:int = selectedParts.length - 1; i >= 0; i--) {
  2862.                                 if (selectedParts[i] is TextPart) {
  2863.                                         selectedParts = Util.RemoveFromArray(selectedParts[i], selectedParts);
  2864.                                 }
  2865.                         }
  2866.                         if (selectedParts.length == 0) return;
  2867.                         curAction = ROTATE;
  2868.                         rotatingPart = null;
  2869.                         for (i = 0; i < selectedParts.length; i++) {
  2870.                                 if ((selectedParts[i] is ShapePart && (!rotatingPart || (rotatingPart is Thrusters) || selectedParts[i].GetMass() > rotatingPart.GetMass())) || (selectedParts[i] is Thrusters && !rotatingPart)) {
  2871.                                         rotatingPart = selectedParts[i];
  2872.                                 }
  2873.                         }
  2874.                         if (rotatingPart != null) {
  2875.                                 rotatingParts = new Array();
  2876.                                 if (selectedParts.length == 1 && rotatingPart is Thrusters) {
  2877.                                         rotatingParts.push(rotatingPart);
  2878.                                 } else {
  2879.                                         for (i = 0; i < selectedParts.length; i++) {
  2880.                                                 rotatingParts = rotatingParts.concat(selectedParts[i].GetAttachedParts());
  2881.                                         }
  2882.                                         rotatingParts = Util.RemoveDuplicates(rotatingParts);
  2883.                                 }
  2884.                                 for (i = 0; i < rotatingParts.length; i++) {
  2885.                                         if (rotatingParts[i] is ShapePart || rotatingParts[i] is Thrusters) {
  2886.                                                 rotatingParts[i].rotateAngle = Math.atan2(rotatingParts[i].centerY - rotatingPart.centerY, rotatingParts[i].centerX - rotatingPart.centerX);
  2887.                                                 rotatingParts[i].rotateOrientation = rotatingParts[i].angle;
  2888.                                         } else {
  2889.                                                 rotatingParts[i].rotateAngle = Math.atan2(rotatingParts[i].anchorY - rotatingPart.centerY, rotatingParts[i].anchorX - rotatingPart.centerX);
  2890.                                                 if (rotatingParts[i] is PrismaticJoint) {
  2891.                                                         rotatingParts[i].rotateOrientation = Util.GetAngle(rotatingParts[i].axis);
  2892.                                                 }
  2893.                                         }
  2894.                                 }
  2895.                                 initRotatingAngle = Math.atan2(mouseYWorldPhys - rotatingPart.centerY, mouseXWorldPhys - rotatingPart.centerX);
  2896.                         }
  2897.                 }
  2898.                
  2899.                 public function mirrorHorizontal(e:MouseEvent):void {
  2900.                         if (/*Main.premiumMode*/ true) {
  2901.                                 if (!curRobotEditable || selectingCondition) return;
  2902.                                 if (simStarted) return;
  2903.                                 if (selectedParts.length == 0) return;
  2904.                                 var newParts:Array = new Array();
  2905.                                 var centerX:Number = (selectedParts[0] is JointPart ? selectedParts[0].anchorX : (selectedParts[0] is TextPart ? selectedParts[0].x + selectedParts[0].w / 2 : selectedParts[0].centerX));
  2906.                                 var centerY:Number = (selectedParts[0] is JointPart ? selectedParts[0].anchorY : (selectedParts[0] is TextPart ? selectedParts[0].y + selectedParts[0].h / 2 : selectedParts[0].centerY));
  2907.                                 var partMapping:Array = new Array();
  2908.                                 for (var i:int = 0; i < selectedParts.length; i++) {
  2909.                                         if (selectedParts[i] is Circle) {
  2910.                                                 var c:Circle = new Circle(centerX - (selectedParts[i].centerX - centerX), selectedParts[i].centerY, selectedParts[i].radius);
  2911.                                                 c.angle = Math.PI - selectedParts[i].angle;
  2912.                                                 c.isStatic = selectedParts[i].isStatic;
  2913.                                                 c.density = selectedParts[i].density;
  2914.                                                 c.collide = selectedParts[i].collide;
  2915.                                                 c.red = selectedParts[i].red;
  2916.                                                 c.green = selectedParts[i].green;
  2917.                                                 c.blue = selectedParts[i].blue;
  2918.                                                 c.opacity = selectedParts[i].opacity;
  2919.                                                 c.outline = selectedParts[i].outline;
  2920.                                                 c.terrain = selectedParts[i].terrain;
  2921.                                                 c.undragable = selectedParts[i].undragable;
  2922.                                                 newParts.push(c);
  2923.                                                 partMapping.push(c);
  2924.                                         } else if (selectedParts[i] is Rectangle) {
  2925.                                                 var r:Rectangle = new Rectangle(centerX - (selectedParts[i].x - centerX), selectedParts[i].y, -selectedParts[i].w, selectedParts[i].h);
  2926.                                                 r.angle = Math.PI - selectedParts[i].angle;
  2927.                                                 r.isStatic = selectedParts[i].isStatic;
  2928.                                                 r.density = selectedParts[i].density;
  2929.                                                 r.collide = selectedParts[i].collide;
  2930.                                                 r.red = selectedParts[i].red;
  2931.                                                 r.green = selectedParts[i].green;
  2932.                                                 r.blue = selectedParts[i].blue;
  2933.                                                 r.opacity = selectedParts[i].opacity;
  2934.                                                 r.outline = selectedParts[i].outline;
  2935.                                                 r.terrain = selectedParts[i].terrain;
  2936.                                                 r.undragable = selectedParts[i].undragable;
  2937.                                                 newParts.push(r);
  2938.                                                 partMapping.push(r);
  2939.                                         } else if (selectedParts[i] is Triangle) {
  2940.                                                 var verts:Array = selectedParts[i].GetVertices();
  2941.                                                 var t:Triangle = new Triangle(centerX - (verts[0].x - centerX), verts[0].y, centerX - (verts[1].x - centerX), verts[1].y, centerX - (verts[2].x - centerX), verts[2].y);
  2942.                                                 t.isStatic = selectedParts[i].isStatic;
  2943.                                                 t.density = selectedParts[i].density;
  2944.                                                 t.collide = selectedParts[i].collide;
  2945.                                                 t.red = selectedParts[i].red;
  2946.                                                 t.green = selectedParts[i].green;
  2947.                                                 t.blue = selectedParts[i].blue;
  2948.                                                 t.opacity = selectedParts[i].opacity;
  2949.                                                 t.outline = selectedParts[i].outline;
  2950.                                                 t.terrain = selectedParts[i].terrain;
  2951.                                                 t.undragable = selectedParts[i].undragable;
  2952.                                                 newParts.push(t);
  2953.                                                 partMapping.push(t);
  2954.                                         } else if (selectedParts[i] is Cannon) {
  2955.                                                 var ca:Cannon = new Cannon(centerX - (selectedParts[i].x - centerX) - selectedParts[i].w, selectedParts[i].y, selectedParts[i].w);
  2956.                                                 ca.angle = Math.PI - selectedParts[i].angle;
  2957.                                                 ca.isStatic = selectedParts[i].isStatic;
  2958.                                                 ca.density = selectedParts[i].density;
  2959.                                                 ca.collide = selectedParts[i].collide;
  2960.                                                 ca.red = selectedParts[i].red;
  2961.                                                 ca.green = selectedParts[i].green;
  2962.                                                 ca.blue = selectedParts[i].blue;
  2963.                                                 ca.opacity = selectedParts[i].opacity;
  2964.                                                 ca.outline = selectedParts[i].outline;
  2965.                                                 ca.terrain = selectedParts[i].terrain;
  2966.                                                 ca.undragable = selectedParts[i].undragable;
  2967.                                                 ca.fireKey = selectedParts[i].fireKey;
  2968.                                                 ca.strength = selectedParts[i].strength;
  2969.                                                 newParts.push(ca);
  2970.                                                 partMapping.push(ca);
  2971.                                         } else if (selectedParts[i] is TextPart) {
  2972.                                                 var te:TextPart = new TextPart(this, centerX - (selectedParts[i].x + selectedParts[i].w / 2 - centerX), selectedParts[i].y, selectedParts[i].w, selectedParts[i].h, selectedParts[i].text, selectedParts[i].inFront);
  2973.                                                 te.red = selectedParts[i].red;
  2974.                                                 te.green = selectedParts[i].green;
  2975.                                                 te.blue = selectedParts[i].blue;
  2976.                                                 te.size = selectedParts[i].size;
  2977.                                                 te.alwaysVisible = selectedParts[i].alwaysVisible;
  2978.                                                 te.inFront = selectedParts[i].inFront;
  2979.                                                 te.scaleWithZoom = selectedParts[i].scaleWithZoom;
  2980.                                                 te.displayKey = selectedParts[i].displayKey;
  2981.                                                 newParts.push(te);
  2982.                                                 partMapping.push(-1);
  2983.                                         } else if (selectedParts[i] is JointPart || selectedParts[i] is Thrusters) {
  2984.                                                 partMapping.push(-1);
  2985.                                         }
  2986.                                 }
  2987.                                 for (i = 0; i < selectedParts.length; i++) {
  2988.                                         var index1:int = -1, index2:int = -1;
  2989.                                         if (selectedParts[i] is JointPart) {
  2990.                                                 for (var j:int = 0; j < selectedParts.length; j++) {
  2991.                                                         if (selectedParts[j] == selectedParts[i].part1) index1 = j;
  2992.                                                         if (selectedParts[j] == selectedParts[i].part2) index2 = j;
  2993.                                                 }
  2994.                                                 if (index1 == -1 || index2 == -1) continue;
  2995.                                         } else if (selectedParts[i] is Thrusters) {
  2996.                                                 for (j = 0; j < selectedParts.length; j++) {
  2997.                                                         if (selectedParts[j] == selectedParts[i].shape) index1 = j;
  2998.                                                 }
  2999.                                                 if (index1 == -1) continue;
  3000.                                         }
  3001.                                         if (selectedParts[i] is FixedJoint) {
  3002.                                                 var fj:FixedJoint = new FixedJoint(partMapping[index1], partMapping[index2], centerX - (selectedParts[i].anchorX - centerX), selectedParts[i].anchorY);
  3003.                                                 newParts.push(fj);
  3004.                                         } else if (selectedParts[i] is RevoluteJoint) {
  3005.                                                 var rj:RevoluteJoint = new RevoluteJoint(partMapping[index1], partMapping[index2], centerX - (selectedParts[i].anchorX - centerX), selectedParts[i].anchorY);
  3006.                                                 rj.enableMotor = selectedParts[i].enableMotor;
  3007.                                                 rj.motorCWKey = selectedParts[i].motorCCWKey;
  3008.                                                 rj.motorCCWKey = selectedParts[i].motorCWKey;
  3009.                                                 rj.motorStrength = selectedParts[i].motorStrength;
  3010.                                                 rj.motorSpeed = selectedParts[i].<