package Game{ import Actions.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.Math.*; import Box2D.Dynamics.*; import Box2D.Dynamics.Contacts.*; import Box2D.Dynamics.Joints.*; import Game.Challenges.*; import Game.Graphics.*; import Game.Tutorials.*; import General.*; import Gui.*; import Parts.*; import flash.display.*; import flash.errors.IllegalOperationError; import flash.events.*; import flash.geom.Matrix; import flash.media.*; import flash.text.*; import flash.utils.getTimer; public class ControllerGame extends Controller { //====================== // Member Data //====================== static public const INIT_PHYS_SCALE:Number = 30; protected static const MIN_ZOOM_VAL:Number = 0.01; protected static const MAX_ZOOM_VAL:Number = 20000; static public const ZOOM_FOCUS_X:Number = 400; static public const ZOOM_FOCUS_Y:Number = 310; public static const REPLAY_SYNC_FRAMES:int = 3; 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"]; static public var playingReplay:Boolean = false; static public var viewingUnsavedReplay:Boolean = false; static public var replay:Replay; static public var replayDirectlyLinked:Boolean = false; private var replaySplineXs:Array; private var replaySplineYs:Array; private var replaySplineAngles:Array; static public var collisionGroup:int = 0x0001; public var degree:Number; public var newAngle:Number; public var radian:Number; public var newdegree:Number; public var initrotang:Number; public var rect:ShapePart; public var m_world:b2World = null; public var m_mouseJoint:b2MouseJoint = null; public var m_iterations:int = 10; public var m_timeStep:Number = 1.0/30; public var m_physScale:Number = INIT_PHYS_SCALE; // world mouse position static public var wasMouseDown:Boolean = false; static public var mouseXWorldPhys:Number; static public var mouseYWorldPhys:Number; static public var mouseXWorld:Number; static public var mouseYWorld:Number; static public var prevMouseXWorld:Number; static public var prevMouseYWorld:Number; // Sprite to draw in to public var m_canvas:Sprite; public var m_buildAreas:Array = new Array(); public var m_badBuildAreas:Array = new Array(); public var m_selectedBuildAreas:Array = new Array(); public var m_guiMenu:DropDownMenu; public var m_guiPanel:MainEditPanel; public var m_sidePanel:PartEditWindow; public var m_chooserWindow:SaveLoadWindow = null; public var m_loginWindow:LoginWindow = null; public var m_newUserWindow:NewUserWindow = null; public var m_scoreWindow:ScoreWindow = null; public var m_progressDialog:DialogWindow = null; public var m_linkDialog:LinkWindow = null; public var m_tutorialDialog:TutorialWindow = null; public var m_postReplayWindow:PostReplayWindow = null; public var m_rateDialog:RateWindow = null; public var m_restrictionsDialog:RestrictionsWindow = null; public var m_conditionsDialog:ConditionsWindow = null; public var m_sandboxWindow:AdvancedSandboxWindow = null; public var m_challengeWindow:ChooseChallengeWindow = null; public var m_reportWindow:ReportWindow = null; public var m_loadWindow:LoadWindow = null; public var m_exportDialog:ExportWindow = null; public var m_importDialog:ImportWindow = null; public var m_fader:Sprite; public static var minDensity:Number = 0.01; public static var maxDensity:Number = 100; public static var maxRJStrength:Number = 100; public static var maxRJSpeed:Number = 100; public static var maxSJStrength:Number = 100; public static var maxSJSpeed:Number = 100; public static var maxThrusterStrength:Number = 100; protected var hasPanned:Boolean = true; protected var hasZoomed:Boolean = true; protected var redrawBuildArea:Boolean = true; protected var redrawRobot:Boolean = true; public var paused:Boolean = true; public var simStarted:Boolean = false; public var wonChallenge:Boolean = false; public var canSaveReplay:Boolean = true; protected var autoPanning:Boolean = true; protected var cameraPart:ShapePart = null; public static var initX:Number = Number.MAX_VALUE; public static var initY:Number = Number.MAX_VALUE; public static var initZoom:Number = Number.MAX_VALUE; public static var defaultR:Number = 150; public static var defaultG:Number = 150; public static var defaultB:Number = 150; public static var defaultO:Number = 255; public static var clickedBox:Boolean = false; public static var adStarted:Boolean = false; public static var snapToCenter:Boolean = true; public static var showJoints:Boolean = true; public static var showOutlines:Boolean = true; public static var showGraphics:Boolean = true; public static var showColours:Boolean = true; public static var centerOnSelected:Boolean = false; public static var failedChallenge:Boolean = false; public static var justLoadedRobotWithChallenge:Boolean = false; private var initRotatingAngle:Number; private var initDragX:Number; private var initDragY:Number; protected var curAction:int = -1; private var actionStep:int = 0; private var firstClickX:Number; private var firstClickY:Number; private var secondClickX:Number; private var secondClickY:Number; private var savedDrawXOff:Number; private var savedDrawYOff:Number; private var mostRecentScaleFactor:Number public var draw:Draw; public var sSky:Sky; public var allParts:Array; public static var cannonballs:Array = null; public var actions:Array; public var cameraMovements:Array; public var keyPresses:Array; public var syncPoints:Array; public var frameCounter:int; public var lastAction:int = -1; protected var partsFit:Boolean = true; private var draggingTutorial:Boolean = false; private var selectingCondition:Boolean = false; private var delayedSelection:Boolean = false; public var ignoreAClick:Boolean = false; public var backToSaveWindow:Boolean = false; public var clickedReport:Boolean = false; public var clickedSave:Boolean = false; public var clickedSaveReplay:Boolean = false; public var clickedSaveChallenge:Boolean = false; public var clickedSubmitScore:Boolean = false; public static var showTutorial:Boolean = true; private var redirectAfterRating:int = 0; public static var ratedCurRobot:Boolean = false; public static var ratedCurReplay:Boolean = false; public static var ratedCurChallenge:Boolean = false; public var saveAfterRestrictions:Boolean = false; public static var loadAndInsert:Boolean = false; public static var potentialRobotID:String = ""; public static var potentialRobotEditable:Boolean = false; public static var potentialRobotPublic:Boolean = false; public static var potentialRobotFeatured:Boolean = false; public static var potentialChallengeID:String = ""; public static var potentialChallengeEditable:Boolean = false; public static var potentialChallengePublic:Boolean = false; public static var potentialChallengeFeatured:Boolean = false; public static var potentialReplayID:String = ""; public static var potentialReplayPublic:Boolean = false; public static var potentialReplayFeatured:Boolean = false; public static var curRobotID:String = ""; public static var curRobotEditable:Boolean = true; public static var curRobotPublic:Boolean = false; public static var curRobotFeatured:Boolean = false; public static var curChallengeID:String = ""; public static var curChallengePublic:Boolean = false; public static var curChallengeFeatured:Boolean = false; public static var curReplayID:String = ""; public static var curReplayPublic:Boolean = false; public static var curReplayFeatured:Boolean = false; public static var userName:String = "_Public"; public static var password:String = ""; public static var sessionID:String = ""; public var selectedParts:Array = new Array(); public var selectedBuildArea:b2AABB; public var rotatingPart:Object = null; public var rotatingParts:Array = null; public var draggingPart:Part = null; public var draggingParts:Array = null; public static var clipboardParts:Array = new Array(); public var jointPart:ShapePart = null; private var lastSelectedShape:ShapePart = null; private var lastSelectedJoint:JointPart = null; private var lastSelectedText:TextPart = null; private var lastSelectedThrusters:Thrusters = null; public var copiedJoint:JointPart = null; public var copiedThrusters:Thrusters = null; public static var replayParts:Array = new Array(); public static var loadedParts:Array = null; protected var removedGraphics:Array = new Array(); protected var uneditableText:TextField; protected var rotatingText:TextField; protected var scalingText:TextField; protected var boxText:TextField; protected var horizLineText:TextField; protected var vertLineText:TextField; protected var shapeText:TextField; private var newText:Object = null; private var oldText:String = ""; public var potentialJointPart1:ShapePart = null; public var potentialJointPart2:ShapePart = null; public var candidateJointX:Number; public var candidateJointY:Number; public var candidateJointType:int; public var candidateJointParts:Array; public static var shapeSound1:Sound = new Resource.cShape1(); public static var shapeSound2:Sound = new Resource.cShape2(); public static var shapeSound3:Sound = new Resource.cShape3(); public static var shapeSound4:Sound = new Resource.cShape4(); public static var shapeSound5:Sound = new Resource.cShape5(); public static var jointSound1:Sound = new Resource.cJoint1(); public static var jointSound2:Sound = new Resource.cJoint2(); public static var jointSound3:Sound = new Resource.cJoint3(); public static var jointSound4:Sound = new Resource.cJoint4(); public static var jointSound5:Sound = new Resource.cJoint5(); public static var winSound:Sound = new Resource.cWin(); public static var loseSound:Sound = new Resource.cLose(); public static var channel:SoundChannel = null; public static var musicChannel:SoundChannel = null; public static var introVolume:Number = 0.5; public static const NEW_CIRCLE:int = 0; public static const NEW_RECT:int = 1; public static const NEW_TRIANGLE:int = 2; public static const NEW_FIXED_JOINT:int = 3; public static const NEW_REVOLUTE_JOINT:int = 4; public static const NEW_PRISMATIC_JOINT:int = 5; public static const ROTATE:int = 6; public static const PASTE:int = 7; public static const BOX_SELECTING:int = 8; public static const FINALIZING_JOINT:int = 9; public static const NEW_TEXT:int = 10; public static const RESIZING_TEXT:int = 11; public static const RESIZING_SHAPES:int = 12; public static const NEW_THRUSTERS:int = 13; public static const DRAWING_BOX:int = 14; public static const DRAWING_HORIZONTAL_LINE:int = 15; public static const DRAWING_VERTICAL_LINE:int = 16; public static const SELECTING_SHAPE:int = 17; public static const DRAWING_BUILD_BOX:int = 18; public static const NEW_CANNON:int = 19; public function ControllerGame() { allParts = new Array(); cannonballs = new Array(); actions = new Array(); Input.m_currController = this; Action.m_controller = this; m_canvas = new Sprite(); m_guiPanel = new MainEditPanel(this); m_guiMenu = new DropDownMenu(this); m_sidePanel = new PartEditWindow(this); m_fader = new Sprite(); m_fader.graphics.beginFill(0, 0.2); m_fader.graphics.lineStyle(0, 0, 0.2); m_fader.graphics.moveTo(0, 0); m_fader.graphics.lineTo(800, 0); m_fader.graphics.lineTo(800, 600); m_fader.graphics.lineTo(0, 600); m_fader.graphics.lineTo(0, 0); m_fader.graphics.endFill(); m_fader.visible = false; uneditableText = new TextField(); uneditableText.x = 0; uneditableText.y = 102; uneditableText.width = 800; uneditableText.text = "The current robot is uneditable. Some features, including saving and submitting scores, will be disabled."; uneditableText.selectable = false; uneditableText.visible = false; var format:TextFormat = new TextFormat(); format.align = TextFormatAlign.CENTER; format.font = Main.GLOBAL_FONT; format.size = 12; uneditableText.setTextFormat(format); rotatingText = new TextField(); rotatingText.x = 0; rotatingText.y = 102; rotatingText.width = 800; rotatingText.text = "Move the mouse around to rotate the shape - hold shift to increment by 45 degrees, and click when you're done."; rotatingText.selectable = false; rotatingText.visible = false; rotatingText.setTextFormat(format); scalingText = new TextField(); scalingText.x = 0; scalingText.y = 102; scalingText.width = 800; scalingText.text = "Move the mouse to the right to increase the shape's size, and left to decrease it."; scalingText.selectable = false; scalingText.visible = false; scalingText.setTextFormat(format); boxText = new TextField(); boxText.x = 0; boxText.y = 102; boxText.width = 800; boxText.text = "Use the mouse to click and drag a box for the given condition. You can use the arrow keys to scroll."; boxText.selectable = false; boxText.visible = false; boxText.setTextFormat(format); horizLineText = new TextField(); horizLineText.x = 0; horizLineText.y = 102; horizLineText.width = 800; horizLineText.text = "Use the mouse to draw a horizontal line for the given condition. You can use the arrow keys to scroll."; horizLineText.selectable = false; horizLineText.visible = false; horizLineText.setTextFormat(format); vertLineText = new TextField(); vertLineText.x = 0; vertLineText.y = 102; vertLineText.width = 800; vertLineText.text = "Use the mouse to draw a vertical line for the given condition. You can use the arrow keys to scroll."; vertLineText.selectable = false; vertLineText.visible = false; vertLineText.setTextFormat(format); shapeText = new TextField(); shapeText.x = 0; shapeText.y = 102; shapeText.width = 800; shapeText.text = "Select a shape for the given condition. You can use the arrow keys to scroll."; shapeText.selectable = false; shapeText.visible = false; shapeText.setTextFormat(format); // set debug draw draw = new Draw(); draw.m_sprite = m_canvas; draw.m_drawScale = m_physScale; draw.m_drawYOff = -100; if (showColours) draw.m_fillAlpha = 1.0; else draw.m_fillAlpha = 0.5; draw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit; if (playingReplay) { replay.cont = this; } else { viewingUnsavedReplay = false; } addEventListener(Event.ADDED_TO_STAGE, Init); } public virtual function Init(e:Event):void { addChild(m_canvas); addChild(uneditableText); addChild(rotatingText); addChild(scalingText); addChild(boxText); addChild(horizLineText); addChild(vertLineText); addChild(shapeText); addChild(m_guiPanel); addChild(m_sidePanel); addChild(m_guiMenu); addChild(m_fader); if (playingReplay) { allParts = allParts.concat(replayParts); for (var i:int = 0; i < allParts.length; i++) { if (allParts[i] is TextPart) { var newTextPart:TextPart = new TextPart(this, allParts[i].x, allParts[i].y, allParts[i].w, allParts[i].h, allParts[i].text); newTextPart.alwaysVisible = allParts[i].alwaysVisible; newTextPart.displayKey = allParts[i].displayKey; newTextPart.red = allParts[i].red; newTextPart.green = allParts[i].green; newTextPart.blue = allParts[i].blue; newTextPart.size = allParts[i].size; allParts[i] = newTextPart; } } } if (loadedParts) { if (this is ControllerChallenge && ControllerChallenge.playChallengeMode && !justLoadedRobotWithChallenge) { for (i = 0; i < loadedParts.length; i++) { loadedParts[i].isEditable = false; } } if (justLoadedRobotWithChallenge) { allParts = allParts.concat(ControllerChallenge.challenge.allParts); for (i = 0; i < allParts.length; i++) { allParts[i].isEditable = false; } } justLoadedRobotWithChallenge = false; allParts = allParts.concat(loadedParts); for (i = 0; i < allParts.length; i++) { if (allParts[i] is TextPart) { newTextPart = new TextPart(this, allParts[i].x, allParts[i].y, allParts[i].w, allParts[i].h, allParts[i].text); newTextPart.alwaysVisible = allParts[i].alwaysVisible; newTextPart.displayKey = allParts[i].displayKey; newTextPart.red = allParts[i].red; newTextPart.green = allParts[i].green; newTextPart.blue = allParts[i].blue; newTextPart.size = allParts[i].size; if (!allParts[i].isEditable) newTextPart.isEditable = false; allParts[i] = newTextPart; } } loadedParts = null; if (initX != Number.MAX_VALUE) { draw.m_drawXOff = initX; draw.m_drawYOff = initY; m_physScale = initZoom; } else if (!(this is ControllerChallenge)) { CenterOnLoadedRobot(); } } else if (!playingReplay) { curRobotID = ""; curRobotEditable = true; curRobotPublic = false; } initX = Number.MAX_VALUE; initY = Number.MAX_VALUE; initZoom = Number.MAX_VALUE; if (this is ControllerChallenge) { minDensity = (ControllerChallenge.challenge.minDensity == -Number.MAX_VALUE ? 1 : ControllerChallenge.challenge.minDensity); maxDensity = (ControllerChallenge.challenge.maxDensity == Number.MAX_VALUE ? 30 : ControllerChallenge.challenge.maxDensity); maxRJStrength = (ControllerChallenge.challenge.maxRJStrength == Number.MAX_VALUE ? 30 : ControllerChallenge.challenge.maxRJStrength); maxRJSpeed = (ControllerChallenge.challenge.maxRJSpeed == Number.MAX_VALUE ? 30 : ControllerChallenge.challenge.maxRJSpeed); maxSJStrength = (ControllerChallenge.challenge.maxSJStrength == Number.MAX_VALUE ? 30 : ControllerChallenge.challenge.maxSJStrength); maxSJSpeed = (ControllerChallenge.challenge.maxSJSpeed == Number.MAX_VALUE ? 30 : ControllerChallenge.challenge.maxSJSpeed); maxThrusterStrength = (ControllerChallenge.challenge.maxThrusterStrength == Number.MAX_VALUE ? 30 : ControllerChallenge.challenge.maxThrusterStrength); } else { minDensity = 1; maxDensity = 30; maxRJStrength = 30; maxRJSpeed = 30; maxSJStrength = 30; maxSJSpeed = 30; maxThrusterStrength = 30; } PrismaticJoint.jbTutorial = false; if (Main.inIFrame) { curRobotEditable = false; uneditableText.text = ""; } } public function BuildBuildArea():void { for (var i:int = 0; i < m_buildAreas.length; i++) { removeChild(m_buildAreas[i]); removeChild(m_badBuildAreas[i]); removeChild(m_selectedBuildAreas[i]); } m_buildAreas = new Array(); m_badBuildAreas = new Array(); m_selectedBuildAreas = new Array(); var childIndex:int = sSky.lastCloudIndex + 1; for (i = 0; i < NumBuildingAreas(); i++) { var m_buildArea:Sprite = new Sprite(); m_buildArea.graphics.lineStyle(6, 0xDEB05D); var m:Matrix = new Matrix(); m.createGradientBox(700, 550, Math.PI / 2); m_buildArea.graphics.beginGradientFill(GradientType.LINEAR, [0xFF8F17, 0xFFC150], [0.15, 0.15], [0, 255], m); m_buildArea.graphics.drawRect(0, 0, 700, 550); m_buildArea.graphics.endFill(); addChildAt(m_buildArea, childIndex); m_buildAreas.push(m_buildArea); var m_badBuildArea:Sprite = new Sprite(); m_badBuildArea.graphics.lineStyle(6, 0xDE6A5D); m = new Matrix(); m.createGradientBox(700, 550, Math.PI / 2); m_badBuildArea.graphics.beginGradientFill(GradientType.LINEAR, [0xFF4D17, 0xFF8F50], [0.15, 0.15], [0, 255], m); m_badBuildArea.graphics.drawRect(0, 0, 700, 550); m_badBuildArea.graphics.endFill(); addChildAt(m_badBuildArea, childIndex); m_badBuildAreas.push(m_badBuildArea); var m_selectedBuildArea:Sprite = new Sprite(); m_selectedBuildArea.graphics.lineStyle(6, 0xFECA5D); m = new Matrix(); m.createGradientBox(700, 550, Math.PI / 2); m_selectedBuildArea.graphics.beginGradientFill(GradientType.LINEAR, [0xFF4D17, 0xFF8F50], [0.15, 0.15], [0, 255], m); m_selectedBuildArea.graphics.drawRect(0, 0, 700, 550); m_selectedBuildArea.graphics.endFill(); addChildAt(m_selectedBuildArea, childIndex); m_selectedBuildAreas.push(m_selectedBuildArea); } } public function PlayShapeSound():void { if (Main.enableSound) { var soundNum:int = int(Util.RangedRandom(0, 5)); var sound:Sound = (soundNum == 0 ? shapeSound1 : (soundNum == 1 ? shapeSound2 : (soundNum == 2 ? shapeSound3 : (soundNum == 3 ? shapeSound4 : shapeSound5)))); channel = sound.play(); var st:SoundTransform = new SoundTransform(0.7); channel.soundTransform = st; } } public function PlayJointSound():void { if (Main.enableSound) { var soundNum:int = int(Util.RangedRandom(0, 5)); var sound:Sound = (soundNum == 0 ? jointSound1 : (soundNum == 1 ? jointSound2 : (soundNum == 2 ? jointSound3 : (soundNum == 3 ? jointSound4 : jointSound5)))); channel = sound.play(); var st:SoundTransform = new SoundTransform(0.7); channel.soundTransform = st; } } public override function GetPhysScale():Number { return m_physScale; } public virtual override function GetMinX():Number { return -Number.MAX_VALUE; } public virtual override function GetMaxX():Number { return Number.MAX_VALUE; } public virtual override function GetMinY():Number { return -Number.MAX_VALUE; } public virtual override function GetMaxY():Number { return Number.MAX_VALUE; } public virtual override function Update():void { if (ControllerMainMenu.channel) { introVolume -= 0.005; var st:SoundTransform = new SoundTransform(introVolume); ControllerMainMenu.channel.soundTransform = st; if (introVolume <= 0) { ControllerMainMenu.channel.stop(); ControllerMainMenu.channel = null; } } if (!m_fader.visible) { if (showColours) draw.m_fillAlpha = 1.0; else draw.m_fillAlpha = 0.5; if (playingReplay && !simStarted) playButton(new MouseEvent("")); // update mouse position mouseXWorldPhys = ((Input.mouseX) + draw.m_drawXOff)/m_physScale; mouseYWorldPhys = ((Input.mouseY) + draw.m_drawYOff)/m_physScale; prevMouseXWorld = mouseXWorld; prevMouseYWorld = mouseYWorld; mouseXWorld = (Input.mouseX); mouseYWorld = (Input.mouseY); Main.ShowMouse(); if (!paused && autoPanning) { HandleCamera(); } MouseDrag(); HandleKey(); for (var i:int = 0; i < allParts.length; i++) { if (allParts[i] is RevoluteJoint || allParts[i] is PrismaticJoint) allParts[i].CheckForBreakage(m_world); } m_guiMenu.Update(); m_guiPanel.Update(curAction); uneditableText.visible = (!curRobotEditable && !playingReplay && !simStarted); rotatingText.visible = (curAction == ROTATE); scalingText.visible = (curAction == RESIZING_SHAPES); if (newText && lastSelectedText is TextPart) { lastSelectedText.text = newText.text; lastSelectedText.m_textField.text = newText.text; newText = null; } // Update physics var physStart:uint = getTimer(); if (!paused) { if (!playingReplay) { if (frameCounter % REPLAY_SYNC_FRAMES == 0) AddSyncPoint(); m_world.Step(1/60, 5); m_world.Step(1/60, m_iterations); } frameCounter++; m_guiPanel.SetTimer(frameCounter); if (frameCounter >= 9000 || cannonballs.length > 500) canSaveReplay = false; } } draw.m_drawScale = m_physScale; draw.drawColours = showColours; if (!simStarted) { for (i = 0; i < m_buildAreas.length; i++) { var box:b2AABB = GetBuildingAreaNumber(i); if (hasPanned || hasZoomed || redrawBuildArea) { m_buildAreas[i].x = World2ScreenX(box.lowerBound.x); m_buildAreas[i].y = World2ScreenY(box.lowerBound.y); m_badBuildAreas[i].x = World2ScreenX(box.lowerBound.x); m_badBuildAreas[i].y = World2ScreenY(box.lowerBound.y); m_selectedBuildAreas[i].x = World2ScreenX(box.lowerBound.x); m_selectedBuildAreas[i].y = World2ScreenY(box.lowerBound.y); } if (hasZoomed || redrawBuildArea) { m_buildAreas[i].width = World2ScreenX(box.upperBound.x) - World2ScreenX(box.lowerBound.x); m_buildAreas[i].height = World2ScreenY(box.upperBound.y) - World2ScreenY(box.lowerBound.y); m_badBuildAreas[i].width = World2ScreenX(box.upperBound.x) - World2ScreenX(box.lowerBound.x); m_badBuildAreas[i].height = World2ScreenY(box.upperBound.y) - World2ScreenY(box.lowerBound.y); m_selectedBuildAreas[i].width = World2ScreenX(box.upperBound.x) - World2ScreenX(box.lowerBound.x); m_selectedBuildAreas[i].height = World2ScreenY(box.upperBound.y) - World2ScreenY(box.lowerBound.y); } m_selectedBuildAreas[i].visible = (m_sidePanel.BuildWindowShowing() && selectedBuildArea == ControllerChallenge.challenge.buildAreas[i]); m_buildAreas[i].visible = (!m_selectedBuildAreas[i].visible && partsFit); m_badBuildAreas[i].visible = (!m_selectedBuildAreas[i].visible && !partsFit); } redrawBuildArea = false; } else { for (i = 0; i < m_buildAreas.length; i++) { m_buildAreas[i].visible = false; m_badBuildAreas[i].visible = false; m_selectedBuildAreas[i].visible = false; } } if (hasPanned || hasZoomed || !paused || draggingPart || curAction != -1 || redrawRobot) { m_canvas.graphics.clear(); draw.DrawWorld(allParts, selectedParts, m_world, !simStarted, false, showJoints, showOutlines, ((this is ControllerChallenge) ? ControllerChallenge.challenge : null)); redrawRobot = false; } var snapPart:ShapePart = FindPartToSnapTo(); if (!simStarted) { if (snapToCenter && snapPart && (curAction == NEW_FIXED_JOINT || curAction == NEW_REVOLUTE_JOINT || curAction == NEW_PRISMATIC_JOINT || curAction == NEW_THRUSTERS)) { draw.DrawTempShape(curAction, actionStep, firstClickX, firstClickY, secondClickX, secondClickY, snapPart.centerX, snapPart.centerY); } else if (curAction == FINALIZING_JOINT && candidateJointType == NEW_PRISMATIC_JOINT && actionStep == 1) { draw.DrawTempShape(NEW_PRISMATIC_JOINT, actionStep, firstClickX, firstClickY, secondClickX, secondClickY, candidateJointX, candidateJointY); } else if (curAction == FINALIZING_JOINT && candidateJointType == NEW_THRUSTERS) { draw.DrawTempShape(NEW_THRUSTERS, actionStep, firstClickX, firstClickY, secondClickX, secondClickY, candidateJointX, candidateJointY); } else if (curAction == FINALIZING_JOINT) { draw.DrawTempShape(curAction, actionStep, firstClickX, firstClickY, secondClickX, secondClickY, candidateJointX, candidateJointY); } else { draw.DrawTempShape(curAction, actionStep, firstClickX, firstClickY, secondClickX, secondClickY, mouseXWorldPhys, mouseYWorldPhys); } } //Main.m_fpsCounter.updatePhys(physStart); if (Database.errorOccurred) { m_progressDialog.StopTimer(); m_progressDialog.SetMessage(Database.lastErrorMsg, true); Database.errorOccurred = false; if (Database.versionErrorOccurred) { Database.versionErrorOccurred = false; m_progressDialog.ShowOKAndCancelButton(5); } else { m_progressDialog.ShowOKButton(); } removeChild(m_progressDialog); addChild(m_progressDialog); Main.ShowMouse(); } if (!paused && ChallengeOver()) { wonChallenge = true; pauseButton(new MouseEvent("")); if (!playingReplay || viewingUnsavedReplay) { m_fader.visible = true; if (this is ControllerTutorial || WonChallenge()) { if (m_scoreWindow) { try { removeChild(m_scoreWindow); } catch (type:Error) { } } m_scoreWindow = new ScoreWindow(this, GetScore()); if (Main.enableSound) { musicChannel = winSound.play(); st = new SoundTransform(0.5); musicChannel.soundTransform = st; } addChild(m_scoreWindow); if (this is ControllerTutorial) { LSOManager.SetLevelDone(Main.nextControllerType - 10); } else if (this is ControllerMonkeyBars || this is ControllerClimb || this is ControllerRace || this is ControllerSpaceship) { LSOManager.SetLevelDone(Main.nextControllerType + 8); } } else { failedChallenge = true; ShowDialog3("Sorry, you have failed this challenge!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); if (Main.enableSound) { musicChannel = loseSound.play(); st = new SoundTransform(0.5); musicChannel.soundTransform = st; } } } } } public override function MoveCameraForReplay(cameraMovement:Object):void { if (cameraMovement.x != Number.POSITIVE_INFINITY) { var oldX:Number = draw.m_drawXOff; var oldY:Number = draw.m_drawYOff; draw.m_drawXOff = cameraMovement.x; draw.m_drawYOff = cameraMovement.y; autoPanning = false; if (oldX != draw.m_drawXOff || oldY != draw.m_drawYOff) hasPanned = true; } var oldScale:Number = m_physScale; m_physScale = cameraMovement.scale; if (m_physScale != oldScale) hasZoomed = true; if (autoPanning) HandleCamera(); } public function AddSyncPoint():void { if (syncPoints.length == 0 || frameCounter != syncPoints[syncPoints.length - 1].frame) { var bodiesUsed:Array = new Array(); var syncPoint:ReplaySyncPoint = new ReplaySyncPoint(); syncPoint.frame = frameCounter; for (var i:int = 0; i < allParts.length; i++) { if (allParts[i] is ShapePart && !allParts[i].isStatic && !Util.ObjectInArray(allParts[i].GetBody(), bodiesUsed)) { syncPoint.positions.push(Util.Vector(allParts[i].GetBody().GetPosition().x, allParts[i].GetBody().GetPosition().y)); syncPoint.angles.push(allParts[i].GetBody().GetAngle()); bodiesUsed.push(allParts[i].GetBody()); } } for (i = 0; i < cannonballs.length; i++) { syncPoint.cannonballPositions.push(Util.Vector(cannonballs[i].GetPosition().x, cannonballs[i].GetPosition().y)); } syncPoints.push(syncPoint); } } private function ComputeReplaySplines(type:int):Array { // Compute the h and b var h:Array = new Array(); var b:Array = new Array(); for (var i:int = 0; i < replay.syncPoints.length - 1; i++) { h.push(replay.syncPoints[i + 1].frame - replay.syncPoints[i].frame); var inner:Array = new Array(); for (var j:int = 0; j < replay.syncPoints[0].positions.length; j++) { if (type == 0) inner.push((replay.syncPoints[i + 1].positions[j].x - replay.syncPoints[i].positions[j].x) / h[i]); else if (type == 1) inner.push((replay.syncPoints[i + 1].positions[j].y - replay.syncPoints[i].positions[j].y) / h[i]); else { var deltaAngle:Number = replay.syncPoints[i + 1].angles[j] - replay.syncPoints[i].angles[j]; if (Math.abs(deltaAngle) > 20) { var a1:Number = Util.NormalizeAngle(replay.syncPoints[i].angles[j]); var a2:Number = Util.NormalizeAngle(replay.syncPoints[i + 1].angles[j]); if (Math.abs(a1 - a2) < Math.PI) { deltaAngle = a2 - a1; } else if (a1 > a2) { deltaAngle = a2 + 2 * Math.PI - a1; } else { deltaAngle = a2 - (a1 + 2 * Math.PI); } } inner.push(deltaAngle / h[i]); } } b.push(inner); } // Gaussian Elimination var u:Array = new Array(); var v:Array = new Array(); u.push(0); u.push(2 * (h[0] + h[1])); inner = new Array(); for (j = 0; j < replay.syncPoints[0].positions.length; j++) { inner.push(0); } v.push(inner); inner = new Array(); for (j = 0; j < replay.syncPoints[0].positions.length; j++) { if (b.length < 2) inner.push(0); else inner.push(6 * (b[1][j] - b[0][j])); } v.push(inner); for (i = 2; i < replay.syncPoints.length - 1; i++) { u.push(2 * (h[i - 1] + h[i]) - h[i - 1] * h[i - 1] / u[i - 1]); inner = new Array(); for (j = 0; j < replay.syncPoints[0].positions.length; j++) { inner.push(6 * (b[i][j] - b[i - 1][j]) - h[i - 1] * v[i - 1][j] / u[i - 1]); } v.push(inner); } // Back-substitution var z:Array = new Array(); inner = new Array(); for (j = 0; j < replay.syncPoints[0].positions.length; j++) { inner.push(0); } z[replay.syncPoints.length - 1] = inner; for (i = replay.syncPoints.length - 2; i > 0; i--) { inner = new Array(); for (j = 0; j < replay.syncPoints[0].positions.length; j++) { inner.push((v[i][j] - h[i] * z[i + 1][j]) / u[i]); } z[i] = inner; } inner = new Array(); for (j = 0; j < replay.syncPoints[0].positions.length; j++) { inner.push(0); } z[0] = inner; var S:Array = new Array(); var As:Array = new Array(); var Bs:Array = new Array(); var Cs:Array = new Array(); var Ds:Array = new Array(); for (i = 0; i < replay.syncPoints.length - 1; i++) { var innerA:Array = new Array(); var innerB:Array = new Array(); var innerC:Array = new Array(); var innerD:Array = new Array(); for (j = 0; j < replay.syncPoints[0].positions.length; j++) { innerA.push(type == 0 ? replay.syncPoints[i].positions[j].x : (type == 1 ? replay.syncPoints[i].positions[j].y : replay.syncPoints[i].angles[j])); deltaAngle = replay.syncPoints[i + 1].angles[j] - replay.syncPoints[i].angles[j]; if (Math.abs(deltaAngle) > 20) { a1 = Util.NormalizeAngle(replay.syncPoints[i].angles[j]); a2 = Util.NormalizeAngle(replay.syncPoints[i + 1].angles[j]); if (Math.abs(a1 - a2) < Math.PI) { deltaAngle = a2 - a1; } else if (a1 > a2) { deltaAngle = a2 + 2 * Math.PI - a1; } else { deltaAngle = a2 - (a1 + 2 * Math.PI); } } 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]); innerC.push(z[i][j] / 2); innerD.push((z[i + 1][j] - z[i][j]) / (6 * h[i])); } As.push(innerA); Bs.push(innerB); Cs.push(innerC); Ds.push(innerD); } S.push(As); S.push(Bs); S.push(Cs); S.push(Ds); return S; } public override function SyncReplay(syncPoint:Object):void { var bodiesUsed:Array = new Array(); var curIndex:int = 0; for (var i:int = 0; i < allParts.length; i++) { if (allParts[i] is ShapePart && !allParts[i].isStatic && !Util.ObjectInArray(allParts[i].GetBody(), bodiesUsed)) { allParts[i].GetBody().SetXForm(syncPoint.positions[curIndex], syncPoint.angles[curIndex]); curIndex++; bodiesUsed.push(allParts[i].GetBody()); } } for (i = 0; i < cannonballs.length; i++) { cannonballs[i].SetXForm(syncPoint.cannonballPositions[i], 0); } } public override function SyncReplay2(syncPoint1:Object, syncPoint2:Object):void { var syncPointIndex:int = replay.syncPoints.indexOf(syncPoint1); var bodiesUsed:Array = new Array(); var curIndex:int = 0; for (var i:int = 0; i < allParts.length; i++) { if (allParts[i] is ShapePart && !allParts[i].isStatic && !Util.ObjectInArray(allParts[i].GetBody(), bodiesUsed)) { 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])); 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])); 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])); allParts[i].GetBody().SetXForm(Util.Vector(x, y), angle); curIndex++; bodiesUsed.push(allParts[i].GetBody()); } } for (i = 0; i < cannonballs.length; i++) { if (syncPoint1.cannonballPositions.length > i) { var frameDiff:int = syncPoint2.frame - syncPoint1.frame; var newX:Number = (syncPoint1.cannonballPositions[i].x * (syncPoint2.frame - frameCounter) + syncPoint2.cannonballPositions[i].x * (frameCounter - syncPoint1.frame)) / frameDiff; var newY:Number = (syncPoint1.cannonballPositions[i].y * (syncPoint2.frame - frameCounter) + syncPoint2.cannonballPositions[i].y * (frameCounter - syncPoint1.frame)) / frameDiff; cannonballs[i].SetXForm(Util.Vector(newX, newY), 0); } else { cannonballs[i].SetXForm(syncPoint2.cannonballPositions[i], 0); } } } public override function IsPaused():Boolean { return paused; } public override function World2ScreenX(x:Number):Number { return x * m_physScale - draw.m_drawXOff; } public override function World2ScreenY(y:Number):Number { return y * m_physScale - draw.m_drawYOff; } public function Screen2WorldX(x:Number):Number { return (x + draw.m_drawXOff) / m_physScale; } public function Screen2WorldY(y:Number):Number { return (y + draw.m_drawYOff) / m_physScale; } protected virtual function ChallengeOver():Boolean { throw new IllegalOperationError("abstract function ControllerGame.ChallengeOver() called"); } protected virtual function WonChallenge():Boolean { return false; } protected virtual function LostChallenge():Boolean { return false; } public virtual function GetScore():int { throw new IllegalOperationError("abstract function ControllerGame.GetScore() called"); } public virtual function ContactAdded(point:b2ContactPoint):void { } protected virtual function GetBuildingArea():b2AABB { throw new IllegalOperationError("abstract function ControllerGame.GetBuildingArea() called"); } protected virtual function GetBuildingAreaNumber(i:int):b2AABB { return GetBuildingArea(); } protected virtual function NumBuildingAreas():int { return 1; } public function GetBoxForConditions():void { boxText.visible = true; curAction = DRAWING_BOX; actionStep = 0; selectingCondition = true; } public function GetHorizontalLineForConditions():void { horizLineText.visible = true; curAction = DRAWING_HORIZONTAL_LINE; actionStep = 0; selectingCondition = true; } public function GetVerticalLineForConditions():void { vertLineText.visible = true; curAction = DRAWING_VERTICAL_LINE; actionStep = 0; selectingCondition = true; } public function GetShapeForConditions():void { if (!m_conditionsDialog.shape1) selectedParts = new Array(); shapeText.visible = true; curAction = SELECTING_SHAPE; selectingCondition = true; } protected function CheckIfPartsFit():void { var partsToCheck:Array = allParts.filter(PartIsEditable); var numAreas:int = NumBuildingAreas(); partsFit = true; if (this is ControllerSandbox && !(this is ControllerChallenge)) return; if (this is ControllerChallenge && !ControllerChallenge.playChallengeMode) return; if (numAreas == 0) return; // Make sure the parts fit in the allowed building area var minX:Number; var maxX:Number; var minY:Number; var maxY:Number; for (var i:int = 0; i < partsToCheck.length; i++) { var partFits:Boolean = false; for (var j:int = 0; j < numAreas; j++) { var buildingArea:b2AABB = GetBuildingAreaNumber(j); if (partsToCheck[i] is Circle) { minX = partsToCheck[i].centerX - partsToCheck[i].radius; maxX = partsToCheck[i].centerX + partsToCheck[i].radius; minY = partsToCheck[i].centerY - partsToCheck[i].radius; maxY = partsToCheck[i].centerY + partsToCheck[i].radius; } else if (partsToCheck[i] is Rectangle || partsToCheck[i] is Triangle || partsToCheck[i] is Cannon) { var verts:Array = partsToCheck[i].GetVertices(); minX = Number.MAX_VALUE; minY = Number.MAX_VALUE; maxX = -Number.MAX_VALUE; maxY = -Number.MAX_VALUE; for (var k:int = 0; k < verts.length; k++) { minX = Math.min(minX, verts[k].x); maxX = Math.max(maxX, verts[k].x); minY = Math.min(minY, verts[k].y); maxY = Math.max(maxY, verts[k].y); } } else { minX = Number.MAX_VALUE; minY = Number.MAX_VALUE; maxX = -Number.MAX_VALUE; maxY = -Number.MAX_VALUE; } if (minX >= buildingArea.lowerBound.x && minY >= buildingArea.lowerBound.y && maxX < buildingArea.upperBound.x && maxY < buildingArea.upperBound.y) { partFits = true; break; } } if (!partFits) { partsFit = false; break; } } } protected virtual function HandleKey():void { // keyboard input for motors/pistons if (!paused) { if (playingReplay) { if (replay.Update(frameCounter)) { pauseButton(new MouseEvent("")); } } for (var i:int = 0; i < allParts.length; i++) { allParts[i].Update(m_world); } } else if (!simStarted && !m_sidePanel.EnteringInput()) { if (Input.isKeyDown(37)) { draw.m_drawXOff -= 10; hasPanned = true; } if (Input.isKeyDown(39)) { draw.m_drawXOff += 10; hasPanned = true; } if (Input.isKeyDown(38)) { draw.m_drawYOff -= 10; hasPanned = true; } if (Input.isKeyDown(40)) { draw.m_drawYOff += 10; hasPanned = true; } } } protected function CenterOnLoadedRobot():void { var cameraPart:ShapePart = null; for (var i:int = 0; i < allParts.length; i++) { if (allParts[i] is ShapePart && allParts[i].isCameraFocus) cameraPart = allParts[i]; } if (!cameraPart) { for (i = 0; i < allParts.length; i++) { allParts[i].checkedCollisionGroup = false; } for (i = 0; i < allParts.length; i++) { if (allParts[i] is ShapePart) allParts[i].SetCollisionGroup(-(i + 1)); } cameraPart = FindCenterOfRobot(); } if (cameraPart) { var oldX:Number = draw.m_drawXOff; var oldY:Number = draw.m_drawYOff; draw.m_drawXOff = cameraPart.centerX * m_physScale - ZOOM_FOCUS_X; draw.m_drawYOff = cameraPart.centerY * m_physScale - ZOOM_FOCUS_Y; if (oldX != draw.m_drawXOff || oldY != draw.m_drawYOff) hasPanned = true; } } protected virtual function HandleCamera():void { if (cameraPart) { var oldX:Number = draw.m_drawXOff; var oldY:Number = draw.m_drawYOff; draw.m_drawXOff = cameraPart.GetBody().GetWorldCenter().x * m_physScale - ZOOM_FOCUS_X; draw.m_drawYOff = cameraPart.GetBody().GetWorldCenter().y * m_physScale - ZOOM_FOCUS_Y; if (isNaN(draw.m_drawXOff) || isNaN(draw.m_drawYOff)) { draw.m_drawXOff = oldX; draw.m_drawYOff = oldY; } if (oldX != draw.m_drawXOff || oldY != draw.m_drawYOff) hasPanned = true; } } public function MouseDrag():void { if (!simStarted) { // mouse press 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) { if (!m_tutorialDialog || !m_tutorialDialog.MouseOver(mouseXWorld, mouseYWorld)) { var shapeOrJoint:Part = GetPartAtMouse(); if (!wasMouseDown && curRobotEditable && shapeOrJoint is ShapePart) { var part:ShapePart = (shapeOrJoint as ShapePart); // rotation if (draggingPart == null && (curAction == -1 || curAction == SELECTING_SHAPE)) { if (MouseOverSelectedPart()) { delayedSelection = true; } else { if (!Util.ObjectInArray(part, selectedParts)) { if (!Input.isKeyDown(16)) { selectedParts = new Array(); } selectedParts.push(part); } else if (Input.isKeyDown(16)) { selectedParts = Util.RemoveFromArray(part, selectedParts); } redrawRobot = true; } draggingPart = selectedParts[0]; initDragX = mouseXWorldPhys; initDragY = mouseYWorldPhys; draggingParts = new Array(); for (var i:int = 0; i < selectedParts.length; i++) { draggingParts = Util.RemoveDuplicates(draggingParts.concat(selectedParts[i].GetAttachedParts())); } for (i = 0; i < draggingParts.length; i++) { if (draggingParts[i] is ShapePart || draggingParts[i] is Thrusters) { draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].centerX; draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].centerY; } else if (draggingParts[i] is JointPart) { draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].anchorX; draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].anchorY; } else { draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].x; draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].y; } } } } else if (!wasMouseDown && curRobotEditable && shapeOrJoint is JointPart && draggingPart == null && (curAction == -1 || curAction == SELECTING_SHAPE)) { if (MouseOverSelectedPart()) { delayedSelection = true; } else { if (!Util.ObjectInArray(shapeOrJoint, selectedParts)) { if (!Input.isKeyDown(16)) { selectedParts = new Array(); } selectedParts.push(shapeOrJoint); } else if (Input.isKeyDown(16)) { selectedParts = Util.RemoveFromArray(shapeOrJoint, selectedParts); } redrawRobot = true; } draggingPart = shapeOrJoint; initDragX = mouseXWorldPhys; initDragY = mouseYWorldPhys; draggingParts = new Array(); for (i = 0; i < selectedParts.length; i++) { draggingParts = Util.RemoveDuplicates(draggingParts.concat(selectedParts[i].GetAttachedParts())); } for (i = 0; i < draggingParts.length; i++) { if (draggingParts[i] is ShapePart || draggingParts[i] is Thrusters) { draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].centerX; draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].centerY; } else if (draggingParts[i] is JointPart) { draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].anchorX; draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].anchorY; } else { draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].x; draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].y; } } } else if (!wasMouseDown && curRobotEditable && shapeOrJoint is TextPart && draggingPart == null && (curAction == -1 || curAction == SELECTING_SHAPE)) { if (MouseOverSelectedPart()) { delayedSelection = true; } else { if (!Util.ObjectInArray(shapeOrJoint, selectedParts)) { if (!Input.isKeyDown(16)) { selectedParts = new Array(); } selectedParts.push(shapeOrJoint); } else if (Input.isKeyDown(16)) { selectedParts = Util.RemoveFromArray(shapeOrJoint, selectedParts); } redrawRobot = true; } draggingPart = shapeOrJoint; initDragX = mouseXWorldPhys; initDragY = mouseYWorldPhys; if ((shapeOrJoint as TextPart).InsideMoveBox(mouseXWorldPhys, mouseYWorldPhys, m_physScale, true)) { curAction = RESIZING_TEXT; } else { draggingParts = new Array(); for (i = 0; i < selectedParts.length; i++) { draggingParts = Util.RemoveDuplicates(draggingParts.concat(selectedParts[i].GetAttachedParts())); } for (i = 0; i < draggingParts.length; i++) { if (draggingParts[i] is ShapePart || draggingParts[i] is Thrusters) { draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].centerX; draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].centerY; } else if (draggingParts[i] is JointPart) { draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].anchorX; draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].anchorY; } else { draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].x; draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].y; } } } } else if (!wasMouseDown && curRobotEditable && shapeOrJoint is Thrusters && draggingPart == null && (curAction == -1 || curAction == SELECTING_SHAPE)) { if (MouseOverSelectedPart()) { delayedSelection = true; } else { if (!Util.ObjectInArray(shapeOrJoint, selectedParts)) { if (!Input.isKeyDown(16)) { selectedParts = new Array(); } selectedParts.push(shapeOrJoint); } else if (Input.isKeyDown(16)) { selectedParts = Util.RemoveFromArray(shapeOrJoint, selectedParts); } redrawRobot = true; } draggingPart = shapeOrJoint; initDragX = mouseXWorldPhys; initDragY = mouseYWorldPhys; draggingParts = new Array(); for (i = 0; i < selectedParts.length; i++) { draggingParts = Util.RemoveDuplicates(draggingParts.concat(selectedParts[i].GetAttachedParts())); } for (i = 0; i < draggingParts.length; i++) { if (draggingParts[i] is ShapePart || draggingParts[i] is Thrusters) { draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].centerX; draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].centerY; } else if (draggingParts[i] is JointPart) { draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].anchorX; draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].anchorY; } else { draggingParts[i].dragXOff = mouseXWorldPhys - draggingParts[i].x; draggingParts[i].dragYOff = mouseYWorldPhys - draggingParts[i].y; } } } else if (draggingPart == null && rotatingPart == null && (curAction == -1 || curAction == SELECTING_SHAPE)) { if (Input.isKeyDown(16) && curRobotEditable) { curAction = BOX_SELECTING; firstClickX = mouseXWorldPhys; firstClickY = mouseYWorldPhys; } else { // dragging the world around var oldX:Number = draw.m_drawXOff; var oldY:Number = draw.m_drawYOff; draw.m_drawXOff -= (mouseXWorld - prevMouseXWorld); draw.m_drawYOff -= (mouseYWorld - prevMouseYWorld); if (oldX != draw.m_drawXOff || oldY != draw.m_drawYOff) hasPanned = true; } selectedParts = new Array(); redrawRobot = true; } } } 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) { if (!m_tutorialDialog || !m_tutorialDialog.MouseOver(mouseXWorld, mouseYWorld)) { RefreshSidePanel(); } } if (!Input.mouseDown) draggingTutorial = false; if (draggingTutorial) { m_tutorialDialog.x = mouseXWorld - initDragX; m_tutorialDialog.y = mouseYWorld - initDragY; } // drag a part if (draggingPart != null && curAction != RESIZING_TEXT) { for (i = 0; i < draggingParts.length; i++) { draggingParts[i].Move(mouseXWorldPhys - draggingParts[i].dragXOff, mouseYWorldPhys - draggingParts[i].dragYOff); } curRobotID = ""; } // rotate a part if (curAction == ROTATE && rotatingPart != null) { if (Input.isKeyDown(16) == false) { newAngle = Math.atan2(mouseYWorldPhys - rotatingPart.centerY, mouseXWorldPhys - rotatingPart.centerX); // Radians to Degrees degree = (newAngle * 180 / Math.PI); newdegree = Math.round(degree / 15) * 15; // Degrees to Radians initrotang = initRotatingAngle; newAngle = initrotang + (newdegree * Math.PI / 180); for (i = 0; i < rotatingParts.length; i++) { rotatingParts[i].RotateAround(rotatingPart.centerX, rotatingPart.centerY, newAngle - initRotatingAngle); } } else { newAngle = Math.atan2(mouseYWorldPhys - rotatingPart.centerY, mouseXWorldPhys - rotatingPart.centerX); // Radians to Degrees degree = (newAngle * 180 / Math.PI); newdegree = Math.round(degree / 45) * 45; // Degrees to Radians initrotang = initRotatingAngle; newAngle = initrotang + (newdegree * Math.PI / 180); for (i = 0; i < rotatingParts.length; i++) { rotatingParts[i].RotateAround(rotatingPart.centerX, rotatingPart.centerY, newAngle - initRotatingAngle); } } } if (curAction == SELECTING_SHAPE && selectedParts.length == 1 && selectedParts[0] is ShapePart && selectedParts[0] != m_conditionsDialog.shape1) { m_conditionsDialog.visible = true; m_fader.visible = true; curAction = -1; m_sidePanel.visible = false; shapeText.visible = false; selectingCondition = false; m_conditionsDialog.FinishSelectingForCondition(selectedParts[0]); } // scale parts? if (curAction == RESIZING_SHAPES) { // determine scale factor var scaleFactor:Number = (mouseXWorld - firstClickX); if (scaleFactor >= 0) { scaleFactor /= 75; scaleFactor += 1; } else { scaleFactor /= 25; scaleFactor -= 1; scaleFactor = -1 / scaleFactor; } for (i = 0; i < draggingParts.length; i++) { if (draggingParts[i] is Circle) { if (draggingParts[i].initRadius * scaleFactor > Circle.MAX_RADIUS) scaleFactor = Circle.MAX_RADIUS / draggingParts[i].initRadius; if (draggingParts[i].initRadius * scaleFactor < Circle.MIN_RADIUS) scaleFactor = Circle.MIN_RADIUS / draggingParts[i].initRadius; } else if (draggingParts[i] is Rectangle) { if (draggingParts[i].initW * scaleFactor > Rectangle.MAX_WIDTH) scaleFactor = Rectangle.MAX_WIDTH / draggingParts[i].initW; if (draggingParts[i].initW * scaleFactor < Rectangle.MIN_WIDTH) scaleFactor = Rectangle.MIN_WIDTH / draggingParts[i].initW; if (draggingParts[i].initH * scaleFactor > Rectangle.MAX_WIDTH) scaleFactor = Rectangle.MAX_WIDTH / draggingParts[i].initH; if (draggingParts[i].initH * scaleFactor < Rectangle.MIN_WIDTH) scaleFactor = Rectangle.MIN_WIDTH / draggingParts[i].initH; } else if (draggingParts[i] is Triangle) { var length1:Number = Util.GetDist(draggingParts[i].initX1, draggingParts[i].initY1, draggingParts[i].initX2, draggingParts[i].initY2); if (length1 * scaleFactor > Triangle.MAX_SIDE_LENGTH) scaleFactor = Triangle.MAX_SIDE_LENGTH / length1; if (length1 * scaleFactor < Triangle.MIN_SIDE_LENGTH) scaleFactor = Triangle.MIN_SIDE_LENGTH / length1; var length2:Number = Util.GetDist(draggingParts[i].initX1, draggingParts[i].initY1, draggingParts[i].initX3, draggingParts[i].initY3); if (length2 * scaleFactor > Triangle.MAX_SIDE_LENGTH) scaleFactor = Triangle.MAX_SIDE_LENGTH / length2; if (length2 * scaleFactor < Triangle.MIN_SIDE_LENGTH) scaleFactor = Triangle.MIN_SIDE_LENGTH / length2; var length3:Number = Util.GetDist(draggingParts[i].initX2, draggingParts[i].initY2, draggingParts[i].initX3, draggingParts[i].initY3); if (length3 * scaleFactor > Triangle.MAX_SIDE_LENGTH) scaleFactor = Triangle.MAX_SIDE_LENGTH / length3; if (length3 * scaleFactor < Triangle.MIN_SIDE_LENGTH) scaleFactor = Triangle.MIN_SIDE_LENGTH / length3; } else if (draggingParts[i] is Cannon) { if (draggingParts[i].initW * scaleFactor > Cannon.MAX_WIDTH) scaleFactor = Cannon.MAX_WIDTH / draggingParts[i].initW; if (draggingParts[i].initW * scaleFactor < Cannon.MIN_WIDTH) scaleFactor = Cannon.MIN_WIDTH / draggingParts[i].initW; } } // scale the parts for (i = 0; i < draggingParts.length; i++) { if (draggingParts[i] is Circle) { draggingParts[i].radius = draggingParts[i].initRadius * scaleFactor; draggingParts[i].Move(initDragX + draggingParts[i].dragXOff * scaleFactor, initDragY + draggingParts[i].dragYOff * scaleFactor); } else if (draggingParts[i] is Rectangle) { draggingParts[i].w = draggingParts[i].initW * scaleFactor; draggingParts[i].h = draggingParts[i].initH * scaleFactor; draggingParts[i].Move(initDragX + draggingParts[i].dragXOff * scaleFactor, initDragY + draggingParts[i].dragYOff * scaleFactor); } else if (draggingParts[i] is Triangle) { draggingParts[i].centerX = initDragX + draggingParts[i].dragXOff * scaleFactor; draggingParts[i].centerY = initDragY + draggingParts[i].dragYOff * scaleFactor; draggingParts[i].x1 = draggingParts[i].centerX + draggingParts[i].initX1 * scaleFactor; draggingParts[i].y1 = draggingParts[i].centerY + draggingParts[i].initY1 * scaleFactor; draggingParts[i].x2 = draggingParts[i].centerX + draggingParts[i].initX2 * scaleFactor; draggingParts[i].y2 = draggingParts[i].centerY + draggingParts[i].initY2 * scaleFactor; draggingParts[i].x3 = draggingParts[i].centerX + draggingParts[i].initX3 * scaleFactor; draggingParts[i].y3 = draggingParts[i].centerY + draggingParts[i].initY3 * scaleFactor; } else if (draggingParts[i] is Cannon) { draggingParts[i].w = draggingParts[i].initW * scaleFactor; draggingParts[i].Move(initDragX + draggingParts[i].dragXOff * scaleFactor, initDragY + draggingParts[i].dragYOff * scaleFactor); } else if (draggingParts[i] is JointPart) { draggingParts[i].Move(initDragX + draggingParts[i].dragXOff * scaleFactor, initDragY + draggingParts[i].dragYOff * scaleFactor); if (draggingParts[i] is PrismaticJoint) { draggingParts[i].initLength = draggingParts[i].initInitLength * scaleFactor; } } else if (draggingParts[i] is TextPart) { draggingParts[i].w = draggingParts[i].initW * scaleFactor; draggingParts[i].h = draggingParts[i].initH * scaleFactor; draggingParts[i].x = initDragX + draggingParts[i].dragXOff * scaleFactor - draggingParts[i].w / 2; draggingParts[i].y = initDragY + draggingParts[i].dragYOff * scaleFactor - draggingParts[i].h / 2; } else if (draggingParts[i] is Thrusters) { draggingParts[i].Move(initDragX + draggingParts[i].dragXOff * scaleFactor, initDragY + draggingParts[i].dragYOff * scaleFactor); } } mostRecentScaleFactor = scaleFactor; } // finalize a joint if (curAction == FINALIZING_JOINT && Util.GetDist(candidateJointX, candidateJointY, mouseXWorldPhys, mouseYWorldPhys) > 0.5 * 30 / m_physScale) { if (candidateJointType == NEW_REVOLUTE_JOINT) { var rjoint:RevoluteJoint = new RevoluteJoint(potentialJointPart1, potentialJointPart2, candidateJointX, candidateJointY); if (copiedJoint is RevoluteJoint) rjoint.SetJointProperties(copiedJoint as RevoluteJoint); allParts.push(rjoint); AddAction(new CreateAction(rjoint)); m_sidePanel.ShowJointPanel(rjoint); selectedParts = new Array(); selectedParts.push(rjoint); curAction = -1; potentialJointPart1.highlightForJoint = false; potentialJointPart2.highlightForJoint = false; curRobotID = ""; if (centerOnSelected) CenterOnSelected(); redrawRobot = true; PlayJointSound(); } else if (candidateJointType == NEW_FIXED_JOINT) { var fjoint:JointPart = new FixedJoint(potentialJointPart1, potentialJointPart2, candidateJointX, candidateJointY); allParts.push(fjoint); AddAction(new CreateAction(fjoint)); m_sidePanel.ShowJointPanel(fjoint); selectedParts = new Array(); selectedParts.push(fjoint); curAction = -1; potentialJointPart1.highlightForJoint = false; potentialJointPart2.highlightForJoint = false; curRobotID = ""; if (centerOnSelected) CenterOnSelected(); redrawRobot = true; PlayJointSound(); } else if (candidateJointType == NEW_THRUSTERS) { var t:Thrusters = new Thrusters(potentialJointPart1, candidateJointX, candidateJointY); if (copiedThrusters) { t.strength = copiedThrusters.strength; t.angle = copiedThrusters.angle; t.thrustKey = copiedThrusters.thrustKey; t.autoOn = copiedThrusters.autoOn; } allParts.push(t); AddAction(new CreateAction(t)); m_sidePanel.ShowThrustersPanel(t); selectedParts = new Array(); selectedParts.push(t); curAction = -1; potentialJointPart1.highlightForJoint = false; curRobotID = ""; if (centerOnSelected) CenterOnSelected(); redrawRobot = true; PlayJointSound(); } else if (candidateJointType == NEW_PRISMATIC_JOINT && actionStep == 0) { jointPart = potentialJointPart1; firstClickX = candidateJointX; firstClickY = candidateJointY; curAction = NEW_PRISMATIC_JOINT; actionStep++; PlayJointSound(); } else if (candidateJointType == NEW_PRISMATIC_JOINT) { var pjoint:PrismaticJoint = new PrismaticJoint(jointPart, potentialJointPart1, firstClickX, firstClickY, candidateJointX, candidateJointY); if (copiedJoint is PrismaticJoint) pjoint.SetJointProperties(copiedJoint as PrismaticJoint); allParts.push(pjoint); AddAction(new CreateAction(pjoint)); m_sidePanel.ShowJointPanel(pjoint); selectedParts = new Array(); selectedParts.push(pjoint); curAction = -1; jointPart.highlightForJoint = false; potentialJointPart1.highlightForJoint = false; curRobotID = ""; if (centerOnSelected) CenterOnSelected(); redrawRobot = true; PlayJointSound(); } } // resize text if (curAction == RESIZING_TEXT) { (draggingPart as TextPart).Resize(mouseXWorldPhys - initDragX, mouseYWorldPhys - initDragY); redrawRobot = true; } } else if (!paused && (((this is ControllerSandbox) && !(this is ControllerChallenge)) || ((this is ControllerChallenge) && ControllerChallenge.challenge.mouseDragAllowed))) { // mouse press if (Input.mouseDown && !m_mouseJoint) { var body:b2Body = GetBodyAtMouse(); if (!playingReplay && body) { var md:b2MouseJointDef = new b2MouseJointDef(); md.body1 = m_world.m_groundBody; md.body2 = body; md.target.Set(mouseXWorldPhys, mouseYWorldPhys); md.maxForce = 300.0 * body.m_mass; md.timeStep = m_timeStep; m_mouseJoint = m_world.CreateJoint(md) as b2MouseJoint; body.WakeUp(); } } // mouse move if (m_mouseJoint) { var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys); m_mouseJoint.SetTarget(p2); } // mouse release if (!Input.mouseDown) { if (m_mouseJoint) { m_world.DestroyJoint(m_mouseJoint); m_mouseJoint = null; } } } 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) { if ((!m_tutorialDialog || !m_tutorialDialog.MouseOver(mouseXWorld, mouseYWorld)) && !draggingTutorial) { // dragging the world around var change:Boolean = (mouseXWorld != prevMouseXWorld || mouseYWorld != prevMouseYWorld); draw.m_drawXOff -= (mouseXWorld - prevMouseXWorld); draw.m_drawYOff -= (mouseYWorld - prevMouseYWorld); autoPanning = false; if (change) { hasPanned = true; cameraMovements.push(new CameraMovement(frameCounter, draw.m_drawXOff, draw.m_drawYOff, m_physScale)); } } } // make sure they haven't gone beyond the boundaries var minY:Number = Screen2WorldY(85); var maxY:Number = Screen2WorldY(600); if (minY < GetMinY()) { draw.m_drawYOff += World2ScreenY(GetMinY()) - World2ScreenY(minY); } else if (maxY > GetMaxY()) { draw.m_drawYOff -= World2ScreenY(maxY) - World2ScreenY(GetMaxY()); } var minX:Number = Screen2WorldX(0); var maxX:Number = Screen2WorldX(800); if (minX < GetMinX()) { draw.m_drawXOff += World2ScreenX(GetMinX()) - World2ScreenX(minX); hasPanned = true; } else if (maxX > GetMaxX()) { draw.m_drawXOff -= World2ScreenX(maxX) - World2ScreenX(GetMaxX()); hasPanned = true; } wasMouseDown = Input.mouseDown; } public override function keyInput(key:int, up:Boolean):void { var recorded:Boolean = false; for (var i:int = 0; i < allParts.length; i++) { allParts[i].KeyInput(key, up, playingReplay); if (!recorded && up && !playingReplay && ((allParts[i] is TextPart && key == allParts[i].displayKey) || (allParts[i] is Cannon && key == allParts[i].fireKey))) { recorded = true; keyPresses.push(new KeyPress(frameCounter, key)); } } } public function keyPress(key:int, up:Boolean):void { if (!paused && !playingReplay) { keyInput(key, up); } if (!simStarted && !m_sidePanel.EnteringInput() && !m_fader.visible) { if (up && key == 49) { circleButton(new MouseEvent("")); } else if (up && key == 50) { rectButton(new MouseEvent("")); } else if (up && key == 51) { triangleButton(new MouseEvent("")); } else if (up && key == 52) { fjButton(new MouseEvent("")); } else if (up && key == 53) { rjButton(new MouseEvent("")); } else if (up && key == 54) { pjButton(new MouseEvent("")); } else if (up && key == 55) { textButton(new MouseEvent("")); } else if (up && key == 82) { rotateButton(new MouseEvent("")); } else if (up && key == 88) { cutButton(new MouseEvent("")); } else if (up && key == 67) { copyButton(new MouseEvent("")); } else if (up && key == 86) { pasteButton(new MouseEvent("")); } else if (up && (key == 8 || key == 46)) { if (selectedParts.length == 1 && !selectedParts[0] is TextPart) deleteButton(new MouseEvent("")); else multiDeleteButton(new MouseEvent("")); } else if (up && key == 89) { redoButton(new MouseEvent("")); } else if (up && key == 90) { undoButton(new MouseEvent("")); } else if (up && (key == 107 || key == 187)) { zoomInButton(new MouseEvent("")); } else if (up && (key == 109 || key == 189)) { zoomOutButton(new MouseEvent("")); } else if (up && key == 80) { playButton(new MouseEvent("")); } } if (up && key == 27) { if (m_chooserWindow && m_chooserWindow.visible && !m_chooserWindow.fader.visible) { m_chooserWindow.visible = false; m_fader.visible = false; } if (m_challengeWindow && m_challengeWindow.visible && !m_challengeWindow.fader.visible) { m_challengeWindow.visible = false; m_fader.visible = false; } if (m_sidePanel.visible && !m_fader.visible) { m_sidePanel.visible = false; } if (m_scoreWindow && m_scoreWindow.visible) { m_scoreWindow.visible = false; m_fader.visible = false; } if (m_progressDialog && m_progressDialog.visible) { m_progressDialog.visible = false; if (m_chooserWindow && m_chooserWindow.visible) { m_chooserWindow.HideFader(); } else if (m_challengeWindow && m_challengeWindow.visible) { m_challengeWindow.HideFader(); } else if (m_loginWindow && m_loginWindow.visible) { m_loginWindow.HideFader(); } else if (m_newUserWindow && m_newUserWindow.visible) { m_newUserWindow.HideFader(); } else { m_fader.visible = false; } } if (m_tutorialDialog && m_tutorialDialog.visible) { m_tutorialDialog.closeWindow(new MouseEvent("")); } if (m_linkDialog && m_linkDialog.visible) { m_linkDialog.visible = false; if (m_chooserWindow && m_chooserWindow.visible) { m_chooserWindow.HideFader(); } else { m_fader.visible = false; } } if (m_loginWindow && m_loginWindow.visible && !m_loginWindow.fader.visible) { m_loginWindow.cancelButtonPressed(new MouseEvent("")); } if (m_newUserWindow && m_newUserWindow.visible) { m_newUserWindow.cancelButtonPressed(new MouseEvent("")); } } } public function mouseMove(x:int, y:int):void { Main.mouseCursor.x = x; Main.mouseCursor.y = y; Main.mouseHourglass.x = x; Main.mouseHourglass.y = y; } public function mouseClick(up:Boolean):void { m_guiMenu.MouseClick(up, mouseXWorld, mouseYWorld); var part:ShapePart; if (up && delayedSelection) { delayedSelection = false; if (mouseXWorldPhys == initDragX && mouseYWorldPhys == initDragY) { var p:Part = GetPartAtMouse(); if (!Util.ObjectInArray(p, selectedParts)) { if (!Input.isKeyDown(16)) { selectedParts = new Array(); } selectedParts.push(p); } else if (Input.isKeyDown(16)) { selectedParts = Util.RemoveFromArray(p, selectedParts); } redrawRobot = true; RefreshSidePanel(); } } if (up && rotatingPart != null) { curAction = -1; AddAction(new RotateAction((rotatingPart as Part), rotatingParts, Util.NormalizeAngle(Math.atan2(mouseYWorldPhys - rotatingPart.centerY, mouseXWorldPhys - rotatingPart.centerX) - initRotatingAngle))); CheckIfPartsFit(); rotatingPart = null; } else if (up && draggingPart != null) { if (!ignoreAClick) { if (curAction != PASTE && curAction != RESIZING_TEXT && (mouseXWorldPhys != initDragX || mouseYWorldPhys != initDragY)) AddAction(new MoveAction(draggingPart, draggingParts, mouseXWorldPhys - initDragX, mouseYWorldPhys - initDragY)); if (curAction == RESIZING_TEXT) { var tPart:TextPart = (draggingPart as TextPart); AddAction(new ResizeTextAction(tPart, tPart.x - tPart.initX, tPart.y - tPart.initY, tPart.w - tPart.initW, tPart.h - tPart.initH)); } CheckIfPartsFit(); if (curAction == PASTE) { var hasShape:Boolean = false; for (var i:int = 0; i < draggingParts.length; i++) { if (draggingParts[i] is ShapePart) { hasShape = true; break; } } if (hasShape) PlayShapeSound(); } if (curAction < 14) curAction = -1; draggingPart = null; } else { ignoreAClick = false; } } else if (!up && curAction == RESIZING_SHAPES) { if (!ignoreAClick) { curAction = -1; AddAction(new ResizeShapesAction(draggingParts, mostRecentScaleFactor)); draggingParts = new Array(); CheckIfPartsFit(); } else { ignoreAClick = false; } } 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))) { firstClickX = mouseXWorldPhys; firstClickY = mouseYWorldPhys; actionStep++; } else if ((curAction == DRAWING_BOX || curAction == DRAWING_HORIZONTAL_LINE || curAction == DRAWING_VERTICAL_LINE) && actionStep == 1) { if (Math.abs(firstClickX - mouseXWorldPhys) > 0.1 || Math.abs(firstClickY - mouseYWorldPhys) > 0.1) { curAction = -1; m_conditionsDialog.visible = true; m_fader.visible = true; selectingCondition = false; m_conditionsDialog.FinishDrawingCondition(firstClickX, firstClickY, mouseXWorldPhys, mouseYWorldPhys); boxText.visible = false; horizLineText.visible = false; vertLineText.visible = false; redrawRobot = true; } } else if (curAction == DRAWING_BUILD_BOX && actionStep == 1) { if (Math.abs(firstClickX - mouseXWorldPhys) > 0.5 || Math.abs(firstClickY - mouseYWorldPhys) > 0.5) { curAction = -1; var buildArea:b2AABB = new b2AABB(); buildArea.lowerBound = Util.Vector(Math.min(firstClickX, mouseXWorldPhys), Math.min(firstClickY, mouseYWorldPhys)); buildArea.upperBound = Util.Vector(Math.max(firstClickX, mouseXWorldPhys), Math.max(firstClickY, mouseYWorldPhys)); ControllerChallenge.challenge.buildAreas.push(buildArea); selectedBuildArea = ControllerChallenge.challenge.buildAreas[ControllerChallenge.challenge.buildAreas.length - 1]; m_sidePanel.ShowBuildBoxPanel(); BuildBuildArea(); redrawRobot = true; redrawBuildArea = true; } } if (!up && !draggingTutorial && m_tutorialDialog && m_tutorialDialog.MouseOver(mouseXWorld, mouseYWorld)) { draggingTutorial = true; initDragX = mouseXWorld - m_tutorialDialog.x; initDragY = mouseYWorld - m_tutorialDialog.y; return; } 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; if (up && selectedParts.length == 1 && centerOnSelected) { CenterOnSelected(); } else if (selectedParts.length == 0 && curAction == -1 && this is ControllerChallenge && !ControllerChallenge.playChallengeMode) { for (i = 0; i < ControllerChallenge.challenge.buildAreas.length; i++) { 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) { selectedBuildArea = ControllerChallenge.challenge.buildAreas[i]; m_sidePanel.ShowBuildBoxPanel(); break; } } } if (curAction == NEW_CIRCLE) { if (!up && actionStep == 0) { firstClickX = mouseXWorldPhys; firstClickY = mouseYWorldPhys; actionStep++; } else if (up && actionStep == 1) { var radius:Number = Util.GetDist(firstClickX, firstClickY, mouseXWorldPhys, mouseYWorldPhys); if (radius > 0) { curAction = -1; var circ:ShapePart = new Circle(firstClickX, firstClickY, radius); allParts.push(circ); selectedParts = new Array(); selectedParts.push(circ); AddAction(new CreateAction(circ)); CheckIfPartsFit(); m_sidePanel.ShowObjectPanel(circ); curRobotID = ""; if (centerOnSelected) CenterOnSelected(); redrawRobot = true; PlayShapeSound(); } } } else if (curAction == NEW_RECT) { if (!up && actionStep == 0) { firstClickX = mouseXWorldPhys; firstClickY = mouseYWorldPhys; actionStep++; } else if (up && actionStep == 1) { if (mouseXWorldPhys != firstClickX || mouseYWorldPhys != firstClickY) { curAction = -1; rect = new Rectangle(firstClickX, firstClickY, mouseXWorldPhys - firstClickX, mouseYWorldPhys - firstClickY); allParts.push(rect); selectedParts = new Array(); selectedParts.push(rect); AddAction(new CreateAction(rect)); CheckIfPartsFit(); m_sidePanel.ShowObjectPanel(rect); curRobotID = ""; if (centerOnSelected) CenterOnSelected(); redrawRobot = true; PlayShapeSound(); } } } else if (curAction == NEW_CANNON) { if (!up && actionStep == 0) { firstClickX = mouseXWorldPhys; firstClickY = mouseYWorldPhys; actionStep++; } else if (up && actionStep == 1) { if (mouseXWorldPhys != firstClickX || mouseYWorldPhys != firstClickY) { curAction = -1; var positive:Boolean = (mouseXWorldPhys >= firstClickX || mouseYWorldPhys >= firstClickY); var w:Number = (positive ? Math.max(mouseXWorldPhys - firstClickX, 2 * (mouseYWorldPhys - firstClickY)) : Math.min(mouseXWorldPhys - firstClickX, 2 * (mouseYWorldPhys - firstClickY))); var cannon:ShapePart = new Cannon(firstClickX, firstClickY, w); allParts.push(cannon); selectedParts = new Array(); selectedParts.push(cannon); AddAction(new CreateAction(cannon)); CheckIfPartsFit(); m_sidePanel.ShowCannonPanel((cannon as Cannon)); curRobotID = ""; if (centerOnSelected) CenterOnSelected(); redrawRobot = true; PlayShapeSound(); } } } else if (curAction == NEW_TRIANGLE) { if (!up && actionStep == 0) { firstClickX = mouseXWorldPhys; firstClickY = mouseYWorldPhys; actionStep++; } else if (up && actionStep == 1) { if (mouseXWorldPhys != firstClickX || mouseYWorldPhys != firstClickY) { var x2:Number = mouseXWorldPhys; var y2:Number = mouseYWorldPhys; var sideLen:Number = Util.GetDist(firstClickX, firstClickY, mouseXWorldPhys, mouseYWorldPhys); var angle:Number; if (sideLen < Triangle.MIN_SIDE_LENGTH) { angle = Math.atan2(firstClickY - mouseYWorldPhys, mouseXWorldPhys - firstClickX); x2 = firstClickX + Triangle.MIN_SIDE_LENGTH * Math.cos(angle); y2 = firstClickY - Triangle.MIN_SIDE_LENGTH * Math.sin(angle); } else if (sideLen > Triangle.MAX_SIDE_LENGTH) { angle = Math.atan2(firstClickY - mouseYWorldPhys, mouseXWorldPhys - firstClickX); x2 = firstClickX + Triangle.MAX_SIDE_LENGTH * Math.cos(angle); y2 = firstClickY - Triangle.MAX_SIDE_LENGTH * Math.sin(angle); } secondClickX = x2; secondClickY = y2; actionStep++; PlayShapeSound(); } } else if (up && actionStep == 2) { if ((mouseXWorldPhys != firstClickX || mouseYWorldPhys != firstClickY) && (mouseXWorldPhys != secondClickX || mouseYWorldPhys != secondClickY)) { var sideLen1:Number = Util.GetDist(firstClickX, firstClickY, mouseXWorldPhys, mouseYWorldPhys); var sideLen2:Number = Util.GetDist(secondClickX, secondClickY, mouseXWorldPhys, mouseYWorldPhys); var sideLen0:Number = Util.GetDist(firstClickX, firstClickY, secondClickX, secondClickY); var angle1:Number = Util.NormalizeAngle(Math.acos((sideLen0 * sideLen0 + sideLen1 * sideLen1 - sideLen2 * sideLen2) / (2 * sideLen0 * sideLen1))); var angle2:Number = Util.NormalizeAngle(Math.acos((sideLen0 * sideLen0 + sideLen2 * sideLen2 - sideLen1 * sideLen1) / (2 * sideLen0 * sideLen2))); var angle3:Number = Util.NormalizeAngle(Math.acos((sideLen1 * sideLen1 + sideLen2 * sideLen2 - sideLen0 * sideLen0) / (2 * sideLen1 * sideLen2))); 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) { curAction = -1; var tri:ShapePart = new Triangle(firstClickX, firstClickY, secondClickX, secondClickY, mouseXWorldPhys, mouseYWorldPhys); allParts.push(tri); selectedParts = new Array(); selectedParts.push(tri); AddAction(new CreateAction(tri)); CheckIfPartsFit(); m_sidePanel.ShowObjectPanel(tri); curRobotID = ""; if (centerOnSelected) CenterOnSelected(); redrawRobot = true; PlayShapeSound(); } } } } else if (up && actionStep == 0 && curAction == NEW_PRISMATIC_JOINT) { MaybeStartCreatingPrismaticJoint(); } else if (up && actionStep == 1 && curAction == NEW_PRISMATIC_JOINT) { if (Util.GetDist(firstClickX, firstClickY, mouseXWorldPhys, mouseYWorldPhys) > 0.3) MaybeFinishCreatingPrismaticJoint(); } else if (up && actionStep == 0 && (curAction == NEW_REVOLUTE_JOINT || curAction == NEW_FIXED_JOINT)) { MaybeCreateJoint(); } else if (up && curAction == BOX_SELECTING) { selectedParts = new Array(); for (i = 0; i < allParts.length; i++) { if (allParts[i].isEditable && allParts[i].IntersectsBox(Math.min(firstClickX, mouseXWorldPhys), Math.min(firstClickY, mouseYWorldPhys), Math.abs(firstClickX - mouseXWorldPhys), Math.abs(firstClickY - mouseYWorldPhys))) { selectedParts.push(allParts[i]); } } if (selectedParts.length == 0) { m_sidePanel.visible = false; } else if (selectedParts.length == 1 && selectedParts[0] is Cannon) { m_sidePanel.ShowCannonPanel(selectedParts[0]); } else if (selectedParts.length == 1 && selectedParts[0] is ShapePart) { m_sidePanel.ShowObjectPanel(selectedParts[0]); } else if (selectedParts.length == 1 && selectedParts[0] is JointPart) { m_sidePanel.ShowJointPanel(selectedParts[0]); } else if (selectedParts.length == 1 && selectedParts[0] is TextPart) { m_sidePanel.ShowTextPanel(selectedParts[0]); } else if (selectedParts.length == 1 && selectedParts[0] is Thrusters) { m_sidePanel.ShowThrustersPanel(selectedParts[0]); } else { m_sidePanel.ShowMultiSelectPanel(selectedParts); } curAction = -1; redrawRobot = true; } else if (up && curAction == FINALIZING_JOINT) { if (candidateJointType == NEW_PRISMATIC_JOINT || candidateJointType == NEW_THRUSTERS) { potentialJointPart1.highlightForJoint = false; var index:int = -1; for (i = 0; i < candidateJointParts.length; i++) { if (potentialJointPart1 == candidateJointParts[i]) index = i; } index++; if (index == candidateJointParts.length) index = 0; potentialJointPart1 = candidateJointParts[index]; potentialJointPart1.highlightForJoint = true; } else { potentialJointPart1.highlightForJoint = false; potentialJointPart2.highlightForJoint = false; var index1:int = -1, index2:int = -1; for (i = 0; i < candidateJointParts.length; i++) { if (potentialJointPart1 == candidateJointParts[i]) index1 = i; if (potentialJointPart2 == candidateJointParts[i]) index2 = i; } if (index1 == candidateJointParts.length - 2 && index2 == candidateJointParts.length - 1) { index1 = 0; index2 = 1; } else { index2++; if (index2 == candidateJointParts.length) { index1++; index2 = index1 + 1; } } potentialJointPart1 = candidateJointParts[index1]; potentialJointPart2 = candidateJointParts[index2]; potentialJointPart1.highlightForJoint = true; potentialJointPart2.highlightForJoint = true; } } else if (!up && curAction == NEW_TEXT && actionStep == 0) { firstClickX = mouseXWorldPhys; firstClickY = mouseYWorldPhys; actionStep++; } else if (up && curAction == NEW_TEXT && actionStep == 1) { var finalClickX:Number = mouseXWorldPhys; var finalClickY:Number = mouseYWorldPhys; if (Math.abs(finalClickX - firstClickX) < 1 || Math.abs(finalClickY - firstClickY) < 0.5) { var avgX:Number = (firstClickX + finalClickX) / 2.0; var avgY:Number = (firstClickY + finalClickY) / 2.0; firstClickX = avgX - 2; firstClickY = avgY - 1; finalClickX = avgX + 2; finalClickY = avgY + 1; } 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"); selectedParts.push(text); allParts.push(text); AddAction(new CreateAction(text)); curAction = -1; curRobotID = ""; m_sidePanel.ShowTextPanel(text); redrawRobot = true; } else if (up && curAction == NEW_THRUSTERS) { MaybeCreateThrusters(); } else if (up && curAction == RESIZING_TEXT) { curAction = -1; } } public function RefreshSidePanel():void { if (selectedParts.length == 0 || selectingCondition) { m_sidePanel.visible = false; } else if (selectedParts.length == 1 && selectedParts[0] is Cannon) { m_sidePanel.ShowCannonPanel(selectedParts[0] as Cannon); lastSelectedShape = null; } else if (selectedParts.length == 1 && selectedParts[0] is ShapePart) { m_sidePanel.ShowObjectPanel(selectedParts[0] as ShapePart); lastSelectedShape = null; } else if (selectedParts.length == 1 && selectedParts[0] is TextPart) { m_sidePanel.ShowTextPanel(selectedParts[0] as TextPart); lastSelectedText = null; } else if (selectedParts.length == 1 && selectedParts[0] is JointPart) { m_sidePanel.ShowJointPanel(selectedParts[0] as JointPart); lastSelectedJoint = null; } else if (selectedParts.length == 1 && selectedParts[0] is Thrusters) { m_sidePanel.ShowThrustersPanel(selectedParts[0] as Thrusters); lastSelectedThrusters = null; } else { m_sidePanel.ShowMultiSelectPanel(selectedParts); } } public function AddAction(a:Action):void { while (lastAction + 1 != actions.length) { actions.pop(); } lastAction = actions.length; actions.push(a); } public function CenterOnSelected():void { if (selectedParts.length == 1) { var centerX:Number, centerY:Number; if (selectedParts[0] is ShapePart || selectedParts[0] is Thrusters) { centerX = selectedParts[0].centerX; centerY = selectedParts[0].centerY; } else if (selectedParts[0] is JointPart) { centerX = selectedParts[0].anchorX; centerY = selectedParts[0].anchorY; } else if (selectedParts[0] is TextPart) { centerX = selectedParts[0].x + selectedParts[0].w / 2; centerY = selectedParts[0].y + selectedParts[0].h / 2; } var oldX:Number = draw.m_drawXOff; var oldY:Number = draw.m_drawYOff; draw.m_drawXOff += World2ScreenX(centerX) - ZOOM_FOCUS_X; draw.m_drawYOff += World2ScreenY(centerY) - ZOOM_FOCUS_Y; if (oldX != draw.m_drawXOff || oldY != draw.m_drawYOff) { hasPanned = true; } } } // BUTTON LISTENERS public virtual function circleButton(e:MouseEvent):void { if (!curRobotEditable || selectingCondition) return; if (curAction == NEW_CIRCLE) { curAction = -1; redrawRobot = true; } else { curAction = NEW_CIRCLE; actionStep = 0; selectedParts = new Array(); m_sidePanel.visible = false; } } public virtual function rectButton(e:MouseEvent):void { if (!curRobotEditable || selectingCondition) return; if (curAction == NEW_RECT) { curAction = -1; redrawRobot = true; } else { curAction = NEW_RECT; actionStep = 0; selectedParts = new Array(); m_sidePanel.visible = false; } } public virtual function triangleButton(e:MouseEvent):void { if (!curRobotEditable || selectingCondition) return; if (curAction == NEW_TRIANGLE) { curAction = -1; redrawRobot = true; } else { curAction = NEW_TRIANGLE; actionStep = 0; selectedParts = new Array(); m_sidePanel.visible = false; } } public virtual function fjButton(e:MouseEvent):void { if (!curRobotEditable || selectingCondition) return; if (curAction == NEW_FIXED_JOINT) { curAction = -1; redrawRobot = true; } else { curAction = NEW_FIXED_JOINT; actionStep = 0; selectedParts = new Array(); m_sidePanel.visible = false; potentialJointPart1 = null; potentialJointPart2 = null; copiedJoint = null; } } public virtual function rjButton(e:MouseEvent):void { if (!curRobotEditable || selectingCondition) return; if (curAction == NEW_REVOLUTE_JOINT) { curAction = -1; redrawRobot = true; } else { curAction = NEW_REVOLUTE_JOINT; actionStep = 0; selectedParts = new Array(); m_sidePanel.visible = false; potentialJointPart1 = null; potentialJointPart2 = null; copiedJoint = null; } } public virtual function pjButton(e:MouseEvent):void { if (!curRobotEditable || selectingCondition) return; if (curAction == NEW_PRISMATIC_JOINT) { curAction = -1; redrawRobot = true; } else { curAction = NEW_PRISMATIC_JOINT; actionStep = 0; selectedParts = new Array(); m_sidePanel.visible = false; potentialJointPart1 = null; potentialJointPart2 = null; copiedJoint = null; } } public virtual function textButton(e:MouseEvent):void { if (!curRobotEditable || selectingCondition) return; if (curAction == NEW_TEXT) { curAction = -1; redrawRobot = true; } else { curAction = NEW_TEXT; actionStep = 0; selectedParts = new Array(); m_sidePanel.visible = false; } } public virtual function thrustersButton(e:MouseEvent):void { if (/*Main.premiumMode*/ true) { if (!curRobotEditable || selectingCondition) return; curAction = NEW_THRUSTERS; actionStep = 0; selectedParts = new Array(); m_sidePanel.visible = false; copiedThrusters = null; } else { m_fader.visible = true; ShowConfirmDialog("That feature is only available to IncrediBots supporters. Become an IncrediBots supporter?", 8); } } public virtual function cannonButton(e:MouseEvent):void { if (/*Main.premiumMode*/ true) { if (!curRobotEditable || selectingCondition) return; curAction = NEW_CANNON; actionStep = 0; selectedParts = new Array(); m_sidePanel.visible = false; } else { m_fader.visible = true; ShowConfirmDialog("That feature is only available to IncrediBots supporters. Become an IncrediBots supporter?", 8); } } private function mochiAdStarted():void { adStarted = true; } private function mochiAdFinished():void { adStarted = false; playButton(new MouseEvent(""), false); } public virtual function playButton(e:MouseEvent, maybeShowAd:Boolean = true):void { if (selectingCondition) return; /*var time:int = getTimer(); if (!Main.DEBUG_VERSION && !Main.premiumMode && maybeShowAd && time > Main.lastAdTime + 30 * 60 * 1000) { MochiAd.showInterLevelAd({clip:root, id:"1913f89f65e17063", res:"800x600", ad_started:mochiAdStarted, ad_finished:mochiAdFinished}); Main.lastAdTime = time; }*/ if (!adStarted) { CheckIfPartsFit(); var tooManyShapes:Boolean = TooManyShapes(); if ((partsFit && !tooManyShapes) || playingReplay) { m_guiPanel.ShowGamePanel(); m_sidePanel.visible = false; selectedParts = new Array(); curAction = -1; paused = false; if (!simStarted) { frameCounter = 0; m_guiPanel.SetTimer(frameCounter); cameraMovements = new Array(); cameraMovements.push(new CameraMovement(0, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, m_physScale)); keyPresses = new Array(); syncPoints = new Array(); cannonballs = new Array(); if (playingReplay) { replay.syncPointIndex = 0; replay.cameraMovementIndex = 0; replay.keyPressIndex = 0; if (replay.syncPoints.length > 0) { replaySplineXs = ComputeReplaySplines(0); replaySplineYs = ComputeReplaySplines(1); replaySplineAngles = ComputeReplaySplines(2); } } simStarted = true; autoPanning = true; canSaveReplay = true; for (var i:int = 0; i < allParts.length; i++) { allParts[i].checkedCollisionGroup = false; } for (i = 0; i < allParts.length; i++) { if (allParts[i] is ShapePart) allParts[i].SetCollisionGroup(-(i + 1)); } CreateWorld(); for (i = allParts.length; i >= 0; i--) { if (allParts[i] is ShapePart || allParts[i] is TextPart) allParts[i].Init(m_world); } collisionGroup = 0x0001; for (i = 0; i < allParts.length; i++) { if (allParts[i] is PrismaticJoint) collisionGroup *= 2; if (allParts[i] is JointPart || allParts[i] is Thrusters) allParts[i].Init(m_world); } cameraPart = null; for (i = 0; i < allParts.length; i++) { if (allParts[i] is ShapePart && allParts[i].isCameraFocus && allParts[i].isEnabled) cameraPart = allParts[i]; } if (!cameraPart) cameraPart = FindCenterOfRobot(); savedDrawXOff = Screen2WorldX(ZOOM_FOCUS_X); savedDrawYOff = Screen2WorldY(ZOOM_FOCUS_Y); } } else { m_fader.visible = true; if (!partsFit) ShowDialog3("You must fit your robot inside the starting box first!"); else if (tooManyShapes) ShowDialog3("Your robot contains too many shapes! (Limit 500)"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } } public virtual function editButton(e:MouseEvent, confirmed:Boolean = false):void { } public function pauseButton(e:MouseEvent):void { if (playingReplay && replay.Update(frameCounter)) ShowPostReplayWindow(); m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } public virtual function resetButton(e:MouseEvent, rateRobot:Boolean = true):void { if (playingReplay) { for (var i:int = 0; i < allParts.length; i++) { allParts[i].UnInit(m_world); } simStarted = false; playButton(e, false); } else { m_guiPanel.ShowEditPanel(); paused = true; simStarted = false; playingReplay = false; for (i = 0; i < allParts.length; i++) { allParts[i].UnInit(m_world); } draw.m_drawXOff = savedDrawXOff * m_physScale - ZOOM_FOCUS_X; draw.m_drawYOff = savedDrawYOff * m_physScale - ZOOM_FOCUS_Y; hasPanned = true; if (rateRobot) { if (curChallengeID != "" && curChallengePublic && !ratedCurChallenge && !LSOManager.HasRatedChallenge(curChallengeID)) { ratedCurChallenge = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 2, 0, true); addChild(m_rateDialog); m_fader.visible = true; } else if (curRobotID != "" && curRobotPublic && !ratedCurRobot && !LSOManager.HasRatedRobot(curRobotID)) { ratedCurRobot = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 0, 0, true); addChild(m_rateDialog); m_fader.visible = true; paused = true; } } } wonChallenge = false; redrawBuildArea = true; } public virtual function rewindButton(e:MouseEvent, makeThemRate:Boolean = true):void { if (!playingReplay) { resetButton(e, false); playButton(e); } else if (viewingUnsavedReplay) { paused = true; simStarted = false; playingReplay = false; wonChallenge = false; viewingUnsavedReplay = false; m_guiPanel.ShowEditPanel(true); for (var i:int = 0; i < allParts.length; i++) { allParts[i].UnInit(m_world); } draw.m_drawXOff = savedDrawXOff * m_physScale - ZOOM_FOCUS_X; draw.m_drawYOff = savedDrawYOff * m_physScale - ZOOM_FOCUS_Y; hasPanned = true; redrawBuildArea = true; } else { if (makeThemRate && curReplayID != "" && !ratedCurReplay && curReplayPublic && !LSOManager.HasRatedReplay(curReplayID)) { ratedCurReplay = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 1, 5); addChild(m_rateDialog); m_fader.visible = true; } else { Main.changeControllers = true; playingReplay = false; showTutorial = false; replayParts = new Array(); curRobotID = ""; curRobotEditable = true; curReplayID = ""; } } } public function reportButton(e:MouseEvent):void { if (selectingCondition) return; if (playingReplay && curReplayID != "" && curReplayPublic) { if (userName == "_Public") { clickedReport = true; loginButton(e, true, false); } else { if (m_reportWindow) removeChild(m_reportWindow); m_reportWindow = new ReportWindow(this, 1, curReplayID); addChild(m_reportWindow); m_fader.visible = true; m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } } else if (curChallengeID != "" && curChallengePublic) { if (userName == "_Public") { clickedReport = true; loginButton(e, true, false); } else { if (m_reportWindow) removeChild(m_reportWindow); m_reportWindow = new ReportWindow(this, 2, curChallengeID); addChild(m_reportWindow); m_fader.visible = true; m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } } else if (curRobotID != "" && curRobotPublic) { if (userName == "_Public") { clickedReport = true; loginButton(e, true, false); } else { if (m_reportWindow) removeChild(m_reportWindow); m_reportWindow = new ReportWindow(this, 0, curRobotID); addChild(m_reportWindow); m_fader.visible = true; m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } } else { m_fader.visible = true; ShowDialog3("You can only report publicly saved robots."); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } public function finishReporting(e:Event):void { var threadID:int = Database.FinishReporting(e); if (threadID != -1) { ShowDialog3("Thank you, the moderators have been notified."); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); Main.ShowMouse(); } } public function featureButton(e:MouseEvent):void { if (selectingCondition) return; if (playingReplay && curReplayID != "" && curReplayPublic) { Database.FeatureReplay(curReplayID, !curReplayFeatured, finishFeaturing); m_fader.visible = true; ShowDialog("Featuring..."); Main.ShowHourglass(); } else if (curChallengeID != "" && curChallengePublic) { Database.FeatureChallenge(curChallengeID, !curChallengeFeatured, finishFeaturing); m_fader.visible = true; ShowDialog("Featuring..."); Main.ShowHourglass(); } else if (curRobotID != "" && curRobotPublic) { Database.FeatureRobot(curRobotID, !curRobotFeatured, finishFeaturing); m_fader.visible = true; ShowDialog("Featuring..."); Main.ShowHourglass(); } else { m_fader.visible = true; ShowDialog3("You can only feature publicly saved robots."); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } private function finishFeaturing(e:Event):void { var retVal:Boolean = Database.FinishFeaturing(e); if (retVal) { m_progressDialog.SetMessage("Success!"); m_progressDialog.HideInXSeconds(1); m_fader.visible = false; Main.ShowMouse(); if (playingReplay) curReplayFeatured = !curReplayFeatured; else if (curChallengeID != "") curChallengeFeatured = !curChallengeFeatured; else curRobotFeatured = !curRobotFeatured; } } public function rateButton(e:MouseEvent):void { if (selectingCondition) return; if (curRobotID != "" && curRobotPublic && !LSOManager.HasRatedRobot(curRobotID)) { m_fader.visible = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 0); addChild(m_rateDialog); } else if (curRobotID == "" || !curRobotPublic) { m_fader.visible = true; ShowDialog3("You need to save your robot publicly first!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } else { m_fader.visible = true; ShowDialog3("You've already rated this robot!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } public function rateWindowClosed(rating:int, redirect:int):void { m_rateDialog.visible = false; if (playingReplay && curReplayID != "" && curReplayPublic) { Database.RateReplay(curReplayID, rating, finishRatingReplay); } else if (curChallengeID != "" && curChallengePublic) { Database.RateChallenge(curChallengeID, rating, finishRatingChallenge); } else { Database.RateRobot(curRobotID, rating, finishRatingRobot); } redirectAfterRating = redirect; m_fader.visible = true; ShowDialog("Rating..."); Main.ShowHourglass(); curAction = -1; } public function conditionsButton(e:MouseEvent):void { curAction = -1; boxText.visible = false; horizLineText.visible = false; vertLineText.visible = false; shapeText.visible = false; m_sidePanel.visible = false; if (m_conditionsDialog) removeChild(m_conditionsDialog); m_conditionsDialog = new ConditionsWindow(this as ControllerChallenge); addChild(m_conditionsDialog); m_fader.visible = true; } public function restrictionsButton(e:MouseEvent):void { if (selectingCondition) return; m_sidePanel.visible = false; if (m_restrictionsDialog) removeChild(m_restrictionsDialog); m_restrictionsDialog = new RestrictionsWindow(this as ControllerChallenge); addChild(m_restrictionsDialog); m_fader.visible = true; saveAfterRestrictions = false; } public function buildBoxButton(e:MouseEvent):void { if (selectingCondition) return; /*if (ControllerChallenge.challenge.buildAreas.length != 0) { m_fader.visible = true; if (m_progressDialog) removeChild(m_progressDialog); m_progressDialog = new DialogWindow(this, "One or more build boxes already exists. Would you like to keep them or delete them?", true, false, true); m_progressDialog.ShowBuildBoxButtons(); addChild(m_progressDialog); }*/ curAction = DRAWING_BUILD_BOX; actionStep = 0; } public function sandboxSettingsButton(e:MouseEvent):void { if (!curRobotEditable || selectingCondition) return; if (!simStarted) { if (this is ControllerSandbox && (!(this is ControllerChallenge) || !ControllerChallenge.playOnlyMode)) { m_sandboxWindow = new AdvancedSandboxWindow(this, ControllerSandbox.settings); m_fader.visible = true; addChild(m_sandboxWindow); } else { m_fader.visible = true; ShowDialog3("That feature is only available in Sandbox mode!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } } public virtual override function commentButton(e:MouseEvent, robotID:String = "", robotPublic:Boolean = false):void { if (selectingCondition) return; if (robotID == "") { robotID = curRobotID; robotPublic = curRobotPublic; } if (robotID != "" && robotPublic) { Database.CommentOnRobot(robotID, finishCommenting); m_fader.visible = true; ShowDialog("Connecting to forum..."); Main.ShowHourglass(); curAction = -1; } else { m_fader.visible = true; ShowDialog3("You need to save your robot publicly first!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } public function finishCommenting(e:Event):void { if (!Database.waitingForResponse || (Database.curTransactionType != Database.ACTION_COMMENT_ROBOT && Database.curTransactionType != Database.ACTION_COMMENT_REPLAY)) return; var threadID:int = Database.FinishCommenting(e); if (threadID != -1) { if (m_chooserWindow && m_chooserWindow.visible) m_chooserWindow.HideFader(); else m_fader.visible = false; m_progressDialog.visible = false; Main.BrowserRedirect("http://www.incredibots.com/forums/posting.php?mode=reply&t=" + threadID + (userName == "_Public" ? "" : "&sid=" + sessionID), true); Main.ShowMouse(); } } public function finishRatingRobot(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_RATE_ROBOT) return; var retVal:Boolean = Database.FinishRating(e); if (retVal) { LSOManager.SetRobotRated(curRobotID); m_progressDialog.SetMessage("Success!"); m_progressDialog.HideInXSeconds(1); if (m_postReplayWindow && m_postReplayWindow.visible) m_postReplayWindow.HideFader(); else m_fader.visible = false; m_rateDialog.visible = false; Main.ShowMouse(); } if (redirectAfterRating == 1) { loadButton(new MouseEvent("")); } else if (redirectAfterRating == 2) { loadRobotButton(new MouseEvent("")); } else if (redirectAfterRating == 3) { loadReplayButton(new MouseEvent("")); } else if (redirectAfterRating == 4) { loadChallengeButton(new MouseEvent("")); } else if (redirectAfterRating == 5) { rewindButton(new MouseEvent("")); } redirectAfterRating = 0; } public function finishRatingReplay(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_RATE_REPLAY) return; var retVal:Boolean = Database.FinishRating(e); if (retVal) { LSOManager.SetReplayRated(curReplayID); m_progressDialog.SetMessage("Success!"); m_progressDialog.HideInXSeconds(1); if (m_postReplayWindow && m_postReplayWindow.visible) m_postReplayWindow.HideFader(); else m_fader.visible = false; m_rateDialog.visible = false; Main.ShowMouse(); } if (redirectAfterRating == 1) { loadButton(new MouseEvent("")); } else if (redirectAfterRating == 2) { loadRobotButton(new MouseEvent("")); } else if (redirectAfterRating == 3) { loadReplayButton(new MouseEvent("")); } else if (redirectAfterRating == 4) { loadChallengeButton(new MouseEvent("")); } else if (redirectAfterRating == 5) { rewindButton(new MouseEvent("")); } redirectAfterRating = 0; } public function finishRatingChallenge(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_RATE_CHALLENGE) return; var retVal:Boolean = Database.FinishRating(e); if (retVal) { LSOManager.SetChallengeRated(curChallengeID); m_progressDialog.SetMessage("Success!"); m_progressDialog.HideInXSeconds(1); if (m_postReplayWindow && m_postReplayWindow.visible) m_postReplayWindow.HideFader(); else m_fader.visible = false; m_rateDialog.visible = false; Main.ShowMouse(); } if (redirectAfterRating == 1) { loadButton(new MouseEvent("")); } else if (redirectAfterRating == 2) { loadRobotButton(new MouseEvent("")); } else if (redirectAfterRating == 3) { loadReplayButton(new MouseEvent("")); } else if (redirectAfterRating == 4) { loadChallengeButton(new MouseEvent("")); } else if (redirectAfterRating == 5) { rewindButton(new MouseEvent("")); } redirectAfterRating = 0; } public virtual override function embedButton(e:MouseEvent, robotID:String = "", robotPublic:Boolean = false):void { if (selectingCondition) return; if (robotID == "") { robotID = curRobotID; robotPublic = curRobotPublic; } if (robotID != "" && robotPublic) { m_fader.visible = true; ShowLinkDialog("Copy the HTML below into your\n website to embed this robot.", null, false, robotID); } else { m_fader.visible = true; ShowDialog3("You need to save your robot publicly first!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } public virtual override function linkButton(e:MouseEvent, robotID:String = "", robotPublic:Boolean = false):void { if (selectingCondition) return; if (robotID == "") { robotID = curRobotID; robotPublic = curRobotPublic; } if (robotID != "" && robotPublic) { m_fader.visible = true; ShowLinkDialog(" Use the link below to\n link to this robot.", "http://incredibots2.com/?robotID=" + robotID); } else { m_fader.visible = true; ShowDialog3("You need to save your robot publicly first!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } public function rateReplayButton(e:MouseEvent):void { if (selectingCondition) return; if (curReplayID != "" && curReplayPublic && !LSOManager.HasRatedReplay(curReplayID)) { m_fader.visible = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 1); addChild(m_rateDialog); } else if (curReplayID == "" || !curReplayPublic) { m_fader.visible = true; ShowDialog3("You need to save your replay publicly first!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } else { m_fader.visible = true; ShowDialog3("You've already rated this replay!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } public virtual override function commentReplayButton(e:MouseEvent, replayID:String = "", replayPublic:Boolean = false):void { if (replayID == "") { replayID = curReplayID; replayPublic = curReplayPublic; } if (replayID != "" && replayPublic) { Database.CommentOnReplay(replayID, finishCommenting); m_fader.visible = true; ShowDialog("Connecting to forum..."); Main.ShowHourglass(); curAction = -1; } else { m_fader.visible = true; ShowDialog3("You need to save your replay publicly first!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } public virtual override function embedReplayButton(e:MouseEvent, replayID:String = "", replayPublic:Boolean = false):void { if (replayID == "") { replayID = curReplayID; replayPublic = curReplayPublic; } if (replayID != "" && replayPublic) { m_fader.visible = true; ShowLinkDialog("Copy the HTML below into your\n website to embed this replay.", null, true, replayID); } else { m_fader.visible = true; ShowDialog3("You need to save your replay publicly first!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } public virtual override function linkReplayButton(e:MouseEvent, replayID:String = "", replayPublic:Boolean = false):void { if (replayID == "") { replayID = curReplayID; replayPublic = curReplayPublic; } if (replayID != "" && replayPublic) { m_fader.visible = true; ShowLinkDialog(" Use the link below to\n link to this replay.", "http://incredibots2.com/?replayID=" + replayID); } else { m_fader.visible = true; ShowDialog3("You need to save your replay publicly first!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } public function rateChallengeButton(e:MouseEvent):void { if (selectingCondition) return; if (curChallengeID != "" && curChallengePublic && !LSOManager.HasRatedChallenge(curChallengeID)) { m_fader.visible = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 2); addChild(m_rateDialog); } else if (curChallengeID == "" || !curChallengePublic) { m_fader.visible = true; ShowDialog3("You need to save your challenge publicly first!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } else { m_fader.visible = true; ShowDialog3("You've already rated this challenge!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } public virtual override function commentChallengeButton(e:MouseEvent, challengeID:String = "", challengePublic:Boolean = false):void { if (selectingCondition) return; if (challengeID == "") { challengeID = curChallengeID; challengePublic = curChallengePublic; } if (challengeID != "" && challengePublic) { Database.CommentOnChallenge(challengeID, finishCommenting); m_fader.visible = true; ShowDialog("Connecting to forum..."); Main.ShowHourglass(); curAction = -1; } else { m_fader.visible = true; ShowDialog3("You need to save your challenge publicly first!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } public virtual override function embedChallengeButton(e:MouseEvent, challengeID:String = "", challengePublic:Boolean = false):void { if (selectingCondition) return; if (challengeID == "") { challengeID = curChallengeID; challengePublic = curChallengePublic; } if (challengeID != "" && challengePublic) { m_fader.visible = true; ShowLinkDialog("Copy the HTML below into your\n website to embed this challenge.", null, false, challengeID, true); } else { m_fader.visible = true; ShowDialog3("You need to save your challenge publicly first!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } public virtual override function linkChallengeButton(e:MouseEvent, challengeID:String = "", challengePublic:Boolean = false):void { if (selectingCondition) return; if (challengeID == "") { challengeID = curChallengeID; challengePublic = curChallengePublic; } if (challengeID != "" && challengePublic) { m_fader.visible = true; ShowLinkDialog(" Use the link below to\n link to this challenge.", "http://incredibots2.com/?challengeID=" + challengeID); } else { m_fader.visible = true; ShowDialog3("You need to save your challenge publicly first!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } public virtual function tutorialButton(e:MouseEvent):void { if (m_tutorialDialog) { m_tutorialDialog.visible = true; m_tutorialDialog.ResetPosition(); } } public virtual function rotateButton(e:MouseEvent):void { if (!curRobotEditable) return; for (var i:int = selectedParts.length - 1; i >= 0; i--) { if (selectedParts[i] is TextPart) { selectedParts = Util.RemoveFromArray(selectedParts[i], selectedParts); } } if (selectedParts.length == 0) return; curAction = ROTATE; rotatingPart = null; for (i = 0; i < selectedParts.length; i++) { if ((selectedParts[i] is ShapePart && (!rotatingPart || (rotatingPart is Thrusters) || selectedParts[i].GetMass() > rotatingPart.GetMass())) || (selectedParts[i] is Thrusters && !rotatingPart)) { rotatingPart = selectedParts[i]; } } if (rotatingPart != null) { rotatingParts = new Array(); if (selectedParts.length == 1 && rotatingPart is Thrusters) { rotatingParts.push(rotatingPart); } else { for (i = 0; i < selectedParts.length; i++) { rotatingParts = rotatingParts.concat(selectedParts[i].GetAttachedParts()); } rotatingParts = Util.RemoveDuplicates(rotatingParts); } for (i = 0; i < rotatingParts.length; i++) { if (rotatingParts[i] is ShapePart || rotatingParts[i] is Thrusters) { rotatingParts[i].rotateAngle = Math.atan2(rotatingParts[i].centerY - rotatingPart.centerY, rotatingParts[i].centerX - rotatingPart.centerX); rotatingParts[i].rotateOrientation = rotatingParts[i].angle; } else { rotatingParts[i].rotateAngle = Math.atan2(rotatingParts[i].anchorY - rotatingPart.centerY, rotatingParts[i].anchorX - rotatingPart.centerX); if (rotatingParts[i] is PrismaticJoint) { rotatingParts[i].rotateOrientation = Util.GetAngle(rotatingParts[i].axis); } } } initRotatingAngle = Math.atan2(mouseYWorldPhys - rotatingPart.centerY, mouseXWorldPhys - rotatingPart.centerX); } } public function mirrorHorizontal(e:MouseEvent):void { if (/*Main.premiumMode*/ true) { if (!curRobotEditable || selectingCondition) return; if (simStarted) return; if (selectedParts.length == 0) return; var newParts:Array = new Array(); var centerX:Number = (selectedParts[0] is JointPart ? selectedParts[0].anchorX : (selectedParts[0] is TextPart ? selectedParts[0].x + selectedParts[0].w / 2 : selectedParts[0].centerX)); var centerY:Number = (selectedParts[0] is JointPart ? selectedParts[0].anchorY : (selectedParts[0] is TextPart ? selectedParts[0].y + selectedParts[0].h / 2 : selectedParts[0].centerY)); var partMapping:Array = new Array(); for (var i:int = 0; i < selectedParts.length; i++) { if (selectedParts[i] is Circle) { var c:Circle = new Circle(centerX - (selectedParts[i].centerX - centerX), selectedParts[i].centerY, selectedParts[i].radius); c.angle = Math.PI - selectedParts[i].angle; c.isStatic = selectedParts[i].isStatic; c.density = selectedParts[i].density; c.collide = selectedParts[i].collide; c.red = selectedParts[i].red; c.green = selectedParts[i].green; c.blue = selectedParts[i].blue; c.opacity = selectedParts[i].opacity; c.outline = selectedParts[i].outline; c.terrain = selectedParts[i].terrain; c.undragable = selectedParts[i].undragable; newParts.push(c); partMapping.push(c); } else if (selectedParts[i] is Rectangle) { var r:Rectangle = new Rectangle(centerX - (selectedParts[i].x - centerX), selectedParts[i].y, -selectedParts[i].w, selectedParts[i].h); r.angle = Math.PI - selectedParts[i].angle; r.isStatic = selectedParts[i].isStatic; r.density = selectedParts[i].density; r.collide = selectedParts[i].collide; r.red = selectedParts[i].red; r.green = selectedParts[i].green; r.blue = selectedParts[i].blue; r.opacity = selectedParts[i].opacity; r.outline = selectedParts[i].outline; r.terrain = selectedParts[i].terrain; r.undragable = selectedParts[i].undragable; newParts.push(r); partMapping.push(r); } else if (selectedParts[i] is Triangle) { var verts:Array = selectedParts[i].GetVertices(); 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); t.isStatic = selectedParts[i].isStatic; t.density = selectedParts[i].density; t.collide = selectedParts[i].collide; t.red = selectedParts[i].red; t.green = selectedParts[i].green; t.blue = selectedParts[i].blue; t.opacity = selectedParts[i].opacity; t.outline = selectedParts[i].outline; t.terrain = selectedParts[i].terrain; t.undragable = selectedParts[i].undragable; newParts.push(t); partMapping.push(t); } else if (selectedParts[i] is Cannon) { var ca:Cannon = new Cannon(centerX - (selectedParts[i].x - centerX) - selectedParts[i].w, selectedParts[i].y, selectedParts[i].w); ca.angle = Math.PI - selectedParts[i].angle; ca.isStatic = selectedParts[i].isStatic; ca.density = selectedParts[i].density; ca.collide = selectedParts[i].collide; ca.red = selectedParts[i].red; ca.green = selectedParts[i].green; ca.blue = selectedParts[i].blue; ca.opacity = selectedParts[i].opacity; ca.outline = selectedParts[i].outline; ca.terrain = selectedParts[i].terrain; ca.undragable = selectedParts[i].undragable; ca.fireKey = selectedParts[i].fireKey; ca.strength = selectedParts[i].strength; newParts.push(ca); partMapping.push(ca); } else if (selectedParts[i] is TextPart) { 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); te.red = selectedParts[i].red; te.green = selectedParts[i].green; te.blue = selectedParts[i].blue; te.size = selectedParts[i].size; te.alwaysVisible = selectedParts[i].alwaysVisible; te.inFront = selectedParts[i].inFront; te.scaleWithZoom = selectedParts[i].scaleWithZoom; te.displayKey = selectedParts[i].displayKey; newParts.push(te); partMapping.push(-1); } else if (selectedParts[i] is JointPart || selectedParts[i] is Thrusters) { partMapping.push(-1); } } for (i = 0; i < selectedParts.length; i++) { var index1:int = -1, index2:int = -1; if (selectedParts[i] is JointPart) { for (var j:int = 0; j < selectedParts.length; j++) { if (selectedParts[j] == selectedParts[i].part1) index1 = j; if (selectedParts[j] == selectedParts[i].part2) index2 = j; } if (index1 == -1 || index2 == -1) continue; } else if (selectedParts[i] is Thrusters) { for (j = 0; j < selectedParts.length; j++) { if (selectedParts[j] == selectedParts[i].shape) index1 = j; } if (index1 == -1) continue; } if (selectedParts[i] is FixedJoint) { var fj:FixedJoint = new FixedJoint(partMapping[index1], partMapping[index2], centerX - (selectedParts[i].anchorX - centerX), selectedParts[i].anchorY); newParts.push(fj); } else if (selectedParts[i] is RevoluteJoint) { var rj:RevoluteJoint = new RevoluteJoint(partMapping[index1], partMapping[index2], centerX - (selectedParts[i].anchorX - centerX), selectedParts[i].anchorY); rj.enableMotor = selectedParts[i].enableMotor; rj.motorCWKey = selectedParts[i].motorCCWKey; rj.motorCCWKey = selectedParts[i].motorCWKey; rj.motorStrength = selectedParts[i].motorStrength; rj.motorSpeed = selectedParts[i].motorSpeed; rj.motorLowerLimit = -selectedParts[i].motorUpperLimit; rj.motorUpperLimit = -selectedParts[i].motorLowerLimit; rj.isStiff = selectedParts[i].isStiff; rj.autoCW = selectedParts[i].autoCCW; rj.autoCCW = selectedParts[i].autoCW; newParts.push(rj); } else if (selectedParts[i] is PrismaticJoint) { var pj:PrismaticJoint = new PrismaticJoint(partMapping[index1], partMapping[index2], 0, 0, 1, 1); pj.anchorX = centerX - (selectedParts[i].anchorX - centerX); pj.anchorY = selectedParts[i].anchorY; var axisAngle:Number = Math.atan2(selectedParts[i].axis.y, selectedParts[i].axis.x); axisAngle = Util.NormalizeAngle(Math.PI - axisAngle); pj.axis = new b2Vec2(Math.cos(axisAngle), Math.sin(axisAngle)); pj.axis.Normalize(); pj.initLength = selectedParts[i].initLength; pj.enablePiston = selectedParts[i].enablePiston; pj.pistonUpKey = selectedParts[i].pistonUpKey; pj.pistonDownKey = selectedParts[i].pistonDownKey; pj.pistonStrength = selectedParts[i].pistonStrength; pj.pistonSpeed = selectedParts[i].pistonSpeed; pj.isStiff = selectedParts[i].isStiff; pj.autoOscillate = selectedParts[i].autoOscillate; pj.red = selectedParts[i].red; pj.green = selectedParts[i].green; pj.blue = selectedParts[i].blue; pj.opacity = selectedParts[i].opacity; pj.outline = selectedParts[i].outline; pj.collide = selectedParts[i].collide; newParts.push(pj); } else if (selectedParts[i] is Thrusters) { var th:Thrusters = new Thrusters(partMapping[index1], centerX - (selectedParts[i].centerX - centerX), selectedParts[i].centerY); th.angle = Math.PI - selectedParts[i].angle; th.strength = selectedParts[i].strength; th.thrustKey = selectedParts[i].thrustKey; th.autoOn = selectedParts[i].autoOn; newParts.push(th); } } if (newParts.length > 0) { selectedParts = new Array(); draggingParts = new Array(); for (i = 0; i < newParts.length; i++) { newParts[i].dragXOff = centerX - (newParts[i] is JointPart ? newParts[i].anchorX : (newParts[i] is TextPart ? newParts[i].x - newParts[i].w / 2 : newParts[i].centerX)); newParts[i].dragYOff = centerY - (newParts[i] is JointPart ? newParts[i].anchorY : (newParts[i] is TextPart ? newParts[i].y - newParts[i].h / 2 : newParts[i].centerY)); selectedParts.push(newParts[i]); draggingParts.push(newParts[i]); allParts.push(newParts[i]); } initDragX = mouseXWorldPhys; initDragY = mouseYWorldPhys; draggingPart = selectedParts[0]; draggingPart.Move(mouseXWorldPhys, mouseYWorldPhys); RefreshSidePanel(); AddAction(new MassCreateAction(selectedParts)); curAction = PASTE; curRobotID = ""; } } else { m_fader.visible = true; ShowConfirmDialog("That feature is only available to IncrediBots supporters. Become an IncrediBots supporter?", 8); } } public function mirrorVertical(e:MouseEvent):void { if (/*Main.premiumMode*/ true) { if (!curRobotEditable || selectingCondition) return; if (simStarted) return; if (selectedParts.length == 0) return; var newParts:Array = new Array(); var centerX:Number = (selectedParts[0] is JointPart ? selectedParts[0].anchorX : (selectedParts[0] is TextPart ? selectedParts[0].x + selectedParts[0].w / 2 : selectedParts[0].centerX)); var centerY:Number = (selectedParts[0] is JointPart ? selectedParts[0].anchorY : (selectedParts[0] is TextPart ? selectedParts[0].y + selectedParts[0].h / 2 : selectedParts[0].centerY)); var partMapping:Array = new Array(); for (var i:int = 0; i < selectedParts.length; i++) { if (selectedParts[i] is Circle) { var c:Circle = new Circle(selectedParts[i].centerX, centerY - (selectedParts[i].centerY - centerY), selectedParts[i].radius); c.angle = 2 * Math.PI - selectedParts[i].angle; c.isStatic = selectedParts[i].isStatic; c.density = selectedParts[i].density; c.collide = selectedParts[i].collide; c.red = selectedParts[i].red; c.green = selectedParts[i].green; c.blue = selectedParts[i].blue; c.opacity = selectedParts[i].opacity; c.outline = selectedParts[i].outline; c.terrain = selectedParts[i].terrain; c.undragable = selectedParts[i].undragable; newParts.push(c); partMapping.push(c); } else if (selectedParts[i] is Rectangle) { var r:Rectangle = new Rectangle(selectedParts[i].x, centerY - (selectedParts[i].y - centerY), selectedParts[i].w, -selectedParts[i].h); r.angle = 2 * Math.PI - selectedParts[i].angle; r.isStatic = selectedParts[i].isStatic; r.density = selectedParts[i].density; r.collide = selectedParts[i].collide; r.red = selectedParts[i].red; r.green = selectedParts[i].green; r.blue = selectedParts[i].blue; r.opacity = selectedParts[i].opacity; r.outline = selectedParts[i].outline; r.terrain = selectedParts[i].terrain; r.undragable = selectedParts[i].undragable; newParts.push(r); partMapping.push(r); } else if (selectedParts[i] is Triangle) { var verts:Array = selectedParts[i].GetVertices(); var t:Triangle = new Triangle(verts[0].x, centerY - (verts[0].y - centerY), verts[1].x, centerY - (verts[1].y - centerY), verts[2].x, centerY - (verts[2].y - centerY)); t.isStatic = selectedParts[i].isStatic; t.density = selectedParts[i].density; t.collide = selectedParts[i].collide; t.red = selectedParts[i].red; t.green = selectedParts[i].green; t.blue = selectedParts[i].blue; t.opacity = selectedParts[i].opacity; t.outline = selectedParts[i].outline; t.terrain = selectedParts[i].terrain; t.undragable = selectedParts[i].undragable; newParts.push(t); partMapping.push(t); } else if (selectedParts[i] is Cannon) { var ca:Cannon = new Cannon(selectedParts[i].x, centerY - (selectedParts[i].y - centerY) - selectedParts[i].w / 2, selectedParts[i].w); ca.angle = 2 * Math.PI - selectedParts[i].angle; ca.isStatic = selectedParts[i].isStatic; ca.density = selectedParts[i].density; ca.collide = selectedParts[i].collide; ca.red = selectedParts[i].red; ca.green = selectedParts[i].green; ca.blue = selectedParts[i].blue; ca.opacity = selectedParts[i].opacity; ca.outline = selectedParts[i].outline; ca.terrain = selectedParts[i].terrain; ca.undragable = selectedParts[i].undragable; ca.fireKey = selectedParts[i].fireKey; ca.strength = selectedParts[i].strength; newParts.push(ca); partMapping.push(ca); } else if (selectedParts[i] is TextPart) { var te:TextPart = new TextPart(this, selectedParts[i].x, centerY - (selectedParts[i].y + selectedParts[i].h / 2 - centerY), selectedParts[i].w, selectedParts[i].h, selectedParts[i].text, selectedParts[i].inFront); te.red = selectedParts[i].red; te.green = selectedParts[i].green; te.blue = selectedParts[i].blue; te.size = selectedParts[i].size; te.alwaysVisible = selectedParts[i].alwaysVisible; te.inFront = selectedParts[i].inFront; te.scaleWithZoom = selectedParts[i].scaleWithZoom; te.displayKey = selectedParts[i].displayKey; newParts.push(te); partMapping.push(-1); } else if (selectedParts[i] is JointPart || selectedParts[i] is Thrusters) { partMapping.push(-1); } } for (i = 0; i < selectedParts.length; i++) { var index1:int = -1, index2:int = -1; if (selectedParts[i] is JointPart) { for (var j:int = 0; j < selectedParts.length; j++) { if (selectedParts[j] == selectedParts[i].part1) index1 = j; if (selectedParts[j] == selectedParts[i].part2) index2 = j; } if (index1 == -1 || index2 == -1) continue; } else if (selectedParts[i] is Thrusters) { for (j = 0; j < selectedParts.length; j++) { if (selectedParts[j] == selectedParts[i].shape) index1 = j; } if (index1 == -1) continue; } if (selectedParts[i] is FixedJoint) { var fj:FixedJoint = new FixedJoint(partMapping[index1], partMapping[index2], selectedParts[i].anchorX, centerY - (selectedParts[i].anchorY - centerY)); newParts.push(fj); } else if (selectedParts[i] is RevoluteJoint) { var rj:RevoluteJoint = new RevoluteJoint(partMapping[index1], partMapping[index2], selectedParts[i].anchorX, centerY - (selectedParts[i].anchorY - centerY)); rj.enableMotor = selectedParts[i].enableMotor; rj.motorCWKey = selectedParts[i].motorCCWKey; rj.motorCCWKey = selectedParts[i].motorCWKey; rj.motorStrength = selectedParts[i].motorStrength; rj.motorSpeed = selectedParts[i].motorSpeed; rj.motorLowerLimit = -selectedParts[i].motorUpperLimit; rj.motorUpperLimit = -selectedParts[i].motorLowerLimit; rj.isStiff = selectedParts[i].isStiff; rj.autoCW = selectedParts[i].autoCCW; rj.autoCCW = selectedParts[i].autoCW; newParts.push(rj); } else if (selectedParts[i] is PrismaticJoint) { var pj:PrismaticJoint = new PrismaticJoint(partMapping[index1], partMapping[index2], 0, 0, 1, 1); pj.anchorX = selectedParts[i].anchorX; pj.anchorY = centerY - (selectedParts[i].anchorY - centerY); var axisAngle:Number = Math.atan2(selectedParts[i].axis.y, selectedParts[i].axis.x); axisAngle = Util.NormalizeAngle(2 * Math.PI - axisAngle); pj.axis = new b2Vec2(Math.cos(axisAngle), Math.sin(axisAngle)); pj.axis.Normalize(); pj.initLength = selectedParts[i].initLength; pj.enablePiston = selectedParts[i].enablePiston; pj.pistonUpKey = selectedParts[i].pistonUpKey; pj.pistonDownKey = selectedParts[i].pistonDownKey; pj.pistonStrength = selectedParts[i].pistonStrength; pj.pistonSpeed = selectedParts[i].pistonSpeed; pj.isStiff = selectedParts[i].isStiff; pj.autoOscillate = selectedParts[i].autoOscillate; pj.red = selectedParts[i].red; pj.green = selectedParts[i].green; pj.blue = selectedParts[i].blue; pj.opacity = selectedParts[i].opacity; pj.outline = selectedParts[i].outline; pj.collide = selectedParts[i].collide; newParts.push(pj); } else if (selectedParts[i] is Thrusters) { var th:Thrusters = new Thrusters(partMapping[index1], selectedParts[i].centerX, centerY - (selectedParts[i].centerY - centerY)); th.angle = 2 * Math.PI - selectedParts[i].angle; th.strength = selectedParts[i].strength; th.thrustKey = selectedParts[i].thrustKey; th.autoOn = selectedParts[i].autoOn; newParts.push(th); } } if (newParts.length > 0) { selectedParts = new Array(); draggingParts = new Array(); for (i = 0; i < newParts.length; i++) { newParts[i].dragXOff = centerX - (newParts[i] is JointPart ? newParts[i].anchorX : (newParts[i] is TextPart ? newParts[i].x - newParts[i].w / 2 : newParts[i].centerX)); newParts[i].dragYOff = centerY - (newParts[i] is JointPart ? newParts[i].anchorY : (newParts[i] is TextPart ? newParts[i].y - newParts[i].h / 2 : newParts[i].centerY)); selectedParts.push(newParts[i]); draggingParts.push(newParts[i]); allParts.push(newParts[i]); } initDragX = mouseXWorldPhys; initDragY = mouseYWorldPhys; draggingPart = selectedParts[0]; draggingPart.Move(mouseXWorldPhys, mouseYWorldPhys); RefreshSidePanel(); AddAction(new MassCreateAction(selectedParts)); curAction = PASTE; curRobotID = ""; } } else { m_fader.visible = true; ShowConfirmDialog("That feature is only available to IncrediBots supporters. Become an IncrediBots supporter?", 8); } } public function scaleButton(e:MouseEvent):void { if (/*Main.premiumMode*/ true) { if (!curRobotEditable || selectingCondition) return; if (simStarted) return; if (selectedParts.length == 0) return; initDragX = (selectedParts[0] is JointPart ? selectedParts[0].anchorX : (selectedParts[0] is TextPart ? selectedParts[0].x + selectedParts[0].w / 2 : selectedParts[0].centerX)); initDragY = (selectedParts[0] is JointPart ? selectedParts[0].anchorY : (selectedParts[0] is TextPart ? selectedParts[0].y + selectedParts[0].h / 2 : selectedParts[0].centerY)); firstClickX = mouseXWorld; firstClickY = mouseYWorld; draggingParts = new Array(); for (var i:int = 0; i < selectedParts.length; i++) { draggingParts = Util.RemoveDuplicates(draggingParts.concat(selectedParts[i].GetAttachedParts())); } for (i = 0; i < draggingParts.length; i++) { draggingParts[i].dragXOff = (draggingParts[i] is JointPart ? draggingParts[i].anchorX : (draggingParts[i] is TextPart ? draggingParts[i].x + draggingParts[i].w / 2 : draggingParts[i].centerX)) - initDragX; draggingParts[i].dragYOff = (draggingParts[i] is JointPart ? draggingParts[i].anchorY : (draggingParts[i] is TextPart ? draggingParts[i].y + draggingParts[i].h / 2 : draggingParts[i].centerY)) - initDragY; draggingParts[i].PrepareForResizing(); } curAction = RESIZING_SHAPES; } else { m_fader.visible = true; ShowConfirmDialog("That feature is only available to IncrediBots supporters. Become an IncrediBots supporter?", 8); } } public function deleteButton(e:MouseEvent):void { if (!curRobotEditable) return; if (simStarted) return; if (selectedParts.length == 1) { DeletePart(selectedParts[0]); curAction = -1; m_sidePanel.visible = false; curRobotID = ""; redrawRobot = true; } } public function deleteBuildBoxButton(e:MouseEvent):void { if (!curRobotEditable) return; if (simStarted) return; if (selectedBuildArea) { ControllerChallenge.challenge.buildAreas = Util.RemoveFromArray(selectedBuildArea, ControllerChallenge.challenge.buildAreas); BuildBuildArea(); redrawBuildArea = true; } m_sidePanel.visible = false; } public virtual function multiDeleteButton(e:MouseEvent):void { if (!curRobotEditable) return; if (simStarted) return; var affectedJoints:Array = new Array(); for (var i:int = 0; i < selectedParts.length; i++) { if (selectedParts[i] is ShapePart) { affectedJoints = affectedJoints.concat(selectedParts[i].GetActiveJoints()); affectedJoints = affectedJoints.concat(selectedParts[i].GetActiveThrusters()); } DeletePart(selectedParts[i], false, false); } if (selectedParts.length != 0) { var deletedParts:Array = Util.RemoveDuplicates(selectedParts.concat(affectedJoints)); AddAction(new ClearAction(deletedParts)); for (i = 0; i < deletedParts.length; i++) { selectedParts = Util.RemoveFromArray(deletedParts[i], selectedParts); } CheckIfPartsFit(); m_sidePanel.visible = false; curRobotID = ""; redrawRobot = true; } } public function densitySlider(e:Event):void { if (selectedParts.length == 1 && selectedParts[0] is ShapePart) { var oldDensity:Number = (selectedParts[0] as ShapePart).density; (selectedParts[0] as ShapePart).density = e.target.value; curRobotID = ""; m_sidePanel.SetDensity(e.target.value); if (oldDensity != e.target.value) AddAction(new ChangeSliderAction(selectedParts[0], ChangeSliderAction.DENSITY_TYPE, e.target.value - oldDensity)); } } public function densityText(e:Event):void { if (lastSelectedShape is ShapePart) { var oldDensity:Number = (lastSelectedShape as ShapePart).density; var density:Number = Number(e.target.text); if (density < minDensity) density = minDensity; if (density > maxDensity) density = maxDensity; if (isNaN(density)) { if (minDensity > 15.0) { density = minDensity; } else if (maxDensity < 15.0) { density = maxDensity; } else { density = 15.0; } } lastSelectedShape.density = density; curRobotID = ""; m_sidePanel.SetDensity(density); if (oldDensity != density) AddAction(new ChangeSliderAction(selectedParts[0], ChangeSliderAction.DENSITY_TYPE, density - oldDensity)); } m_sidePanel.TextAreaLostFocus(); } public function strengthText(e:Event):void { if (lastSelectedJoint is JointPart) { var oldStrength:Number; if (lastSelectedJoint is RevoluteJoint) oldStrength = (lastSelectedJoint as RevoluteJoint).motorStrength; if (lastSelectedJoint is PrismaticJoint) oldStrength = (lastSelectedJoint as PrismaticJoint).pistonStrength; var strength:Number = Number(e.target.text); if (lastSelectedJoint is RevoluteJoint) { if (strength < 1.0) strength = 1.0; if (strength > maxRJStrength) strength = maxRJStrength; if (isNaN(strength)) strength = Math.min(15.0, maxRJStrength); } if (lastSelectedJoint is PrismaticJoint) { if (strength < 1.0) strength = 1.0; if (strength > maxSJStrength) strength = maxSJStrength; if (isNaN(strength)) strength = Math.min(15.0, maxSJStrength); } if (lastSelectedJoint is RevoluteJoint) (lastSelectedJoint as RevoluteJoint).motorStrength = strength; if (lastSelectedJoint is PrismaticJoint) (lastSelectedJoint as PrismaticJoint).pistonStrength = strength; curRobotID = ""; m_sidePanel.SetStrength(strength); if (oldStrength != strength) AddAction(new ChangeSliderAction(lastSelectedJoint, ChangeSliderAction.STRENGTH_TYPE, strength - oldStrength)); } m_sidePanel.TextAreaLostFocus(); } public function speedText(e:Event):void { if (lastSelectedJoint is JointPart) { var oldSpeed:Number; if (lastSelectedJoint is RevoluteJoint) oldSpeed = (lastSelectedJoint as RevoluteJoint).motorSpeed; if (lastSelectedJoint is PrismaticJoint) oldSpeed = (lastSelectedJoint as PrismaticJoint).pistonSpeed; var speed:Number = Number(e.target.text); if (lastSelectedJoint is RevoluteJoint) { if (speed < 1.0) speed = 1.0; if (speed > maxRJSpeed) speed = maxRJSpeed; if (isNaN(speed)) speed = Math.min(15.0, maxRJSpeed); } if (lastSelectedJoint is PrismaticJoint) { if (speed < 1.0) speed = 1.0; if (speed > maxSJSpeed) speed = maxSJSpeed; if (isNaN(speed)) speed = Math.min(15.0, maxSJSpeed); } if (lastSelectedJoint is RevoluteJoint) (lastSelectedJoint as RevoluteJoint).motorSpeed = speed; if (lastSelectedJoint is PrismaticJoint) (lastSelectedJoint as PrismaticJoint).pistonSpeed = speed; curRobotID = ""; m_sidePanel.SetSpeed(speed); if (oldSpeed != speed) AddAction(new ChangeSliderAction(lastSelectedJoint, ChangeSliderAction.SPEED_TYPE, speed - oldSpeed)); } m_sidePanel.TextAreaLostFocus(); } public function thrustText(e:Event):void { if (lastSelectedThrusters is Thrusters) { var oldStrength:Number; oldStrength = lastSelectedThrusters.strength; var strength:Number = Number(e.target.text); if (strength < 1.0) strength = 1.0; if (strength > maxThrusterStrength) strength = maxThrusterStrength; if (isNaN(strength)) strength = Math.min(15.0, maxThrusterStrength); lastSelectedThrusters.strength = strength; curRobotID = ""; m_sidePanel.SetThrust(strength); if (oldStrength != strength) AddAction(new ChangeSliderAction(lastSelectedThrusters, ChangeSliderAction.SPEED_TYPE, strength - oldStrength)); } m_sidePanel.TextAreaLostFocus(); } public function cannonText(e:Event):void { if (lastSelectedShape is Cannon) { var oldStrength:Number; oldStrength = (lastSelectedShape as Cannon).strength; var strength:Number = Number(e.target.text); if (strength < 1.0) strength = 1.0; if (strength > 30) strength = 30; if (isNaN(strength)) strength = 15; (lastSelectedShape as Cannon).strength = strength; curRobotID = ""; m_sidePanel.SetCannon(strength); if (oldStrength != strength) AddAction(new ChangeSliderAction(lastSelectedShape, ChangeSliderAction.STRENGTH_TYPE, strength - oldStrength)); } m_sidePanel.TextAreaLostFocus(); } public function cameraBox(e:Event):void { if (selectedParts.length == 1 && selectedParts[0] is ShapePart) { (selectedParts[0] as ShapePart).isCameraFocus = e.target.selected; curRobotID = ""; var oldCameraPart:ShapePart = null; if (e.target.selected) { for (var i:int = 0; i < allParts.length; i++) { if (allParts[i] is ShapePart && allParts[i] != selectedParts[0]) { if (allParts[i].isCameraFocus) { allParts[i].isCameraFocus = false; oldCameraPart = allParts[i]; } } } } AddAction(new CameraAction(selectedParts[0], e.target.selected, oldCameraPart)); } } public function collisionBox(e:Event):void { if (selectedParts.length == 1 && selectedParts[0] is ShapePart) { (selectedParts[0] as ShapePart).collide = e.target.selected; curRobotID = ""; AddAction(new ShapeCheckboxAction(selectedParts[0], ShapeCheckboxAction.COLLIDE_TYPE, e.target.selected)); } else if (selectedParts.length == 1 && selectedParts[0] is PrismaticJoint) { (selectedParts[0] as PrismaticJoint).collide = e.target.selected; curRobotID = ""; AddAction(new ShapeCheckboxAction(selectedParts[0], ShapeCheckboxAction.COLLIDE_TYPE, e.target.selected)); } else if (selectedParts.length > 1) { var affectedParts:Array = new Array(); for (var i:int = 0; i < selectedParts.length; i++) { if ((selectedParts[i] is ShapePart || selectedParts[i] is PrismaticJoint) && selectedParts[i].collide != e.target.selected) { selectedParts[i].collide = e.target.selected; affectedParts.push(selectedParts[i]); } } if (affectedParts.length > 0) { curRobotID = ""; redrawRobot = true; AddAction(new MultiCollideAction(affectedParts, e.target.selected)); } } } public function fixateBox(e:Event):void { if (selectedParts.length == 1 && selectedParts[0] is ShapePart) { (selectedParts[0] as ShapePart).isStatic = e.target.selected; curRobotID = ""; redrawRobot = true; AddAction(new ShapeCheckboxAction(selectedParts[0], ShapeCheckboxAction.FIXATE_TYPE, e.target.selected)); } else if (selectedParts.length > 1) { var affectedParts:Array = new Array(); for (var i:int = 0; i < selectedParts.length; i++) { if (selectedParts[i] is ShapePart && selectedParts[i].isStatic != e.target.selected) { selectedParts[i].isStatic = e.target.selected; affectedParts.push(selectedParts[i]); } } if (affectedParts.length > 0) { curRobotID = ""; redrawRobot = true; AddAction(new MultiFixateAction(affectedParts, e.target.selected)); } } } public function outlineBox(e:Event):void { if (selectedParts.length == 1 && (selectedParts[0] is ShapePart || selectedParts[0] is PrismaticJoint)) { selectedParts[0].outline = e.target.selected; curRobotID = ""; redrawRobot = true; AddAction(new ShapeCheckboxAction(selectedParts[0], ShapeCheckboxAction.OUTLINE_TYPE, e.target.selected)); } else if (selectedParts.length > 1) { var affectedParts:Array = new Array(); for (var i:int = 0; i < selectedParts.length; i++) { if ((selectedParts[i] is ShapePart || selectedParts[i] is PrismaticJoint) && selectedParts[i].outline != e.target.selected) { selectedParts[i].outline = e.target.selected; affectedParts.push(selectedParts[i]); } } if (affectedParts.length > 0) { curRobotID = ""; redrawRobot = true; AddAction(new MultiOutlineAction(affectedParts, e.target.selected)); } } } public function terrainBox(e:Event):void { if (selectedParts.length == 1 && selectedParts[0] is ShapePart) { selectedParts[0].terrain = e.target.selected; curRobotID = ""; redrawRobot = true; AddAction(new ShapeCheckboxAction(selectedParts[0], ShapeCheckboxAction.TERRAIN_TYPE, e.target.selected)); } else if (selectedParts.length > 1) { var affectedParts:Array = new Array(); for (var i:int = 0; i < selectedParts.length; i++) { if ((selectedParts[i] is ShapePart) && selectedParts[i].terrain != e.target.selected) { selectedParts[i].terrain = e.target.selected; affectedParts.push(selectedParts[i]); } } if (affectedParts.length > 0) { curRobotID = ""; redrawRobot = true; AddAction(new MultiTerrainAction(affectedParts, e.target.selected)); } } } public function undragableBox(e:Event):void { if (selectedParts.length == 1 && selectedParts[0] is ShapePart) { selectedParts[0].undragable = e.target.selected; curRobotID = ""; AddAction(new ShapeCheckboxAction(selectedParts[0], ShapeCheckboxAction.UNDRAGABLE_TYPE, e.target.selected)); } else if (selectedParts.length > 1) { var affectedParts:Array = new Array(); for (var i:int = 0; i < selectedParts.length; i++) { if ((selectedParts[i] is ShapePart) && selectedParts[i].undragable != e.target.selected) { selectedParts[i].undragable = e.target.selected; affectedParts.push(selectedParts[i]); } } if (affectedParts.length > 0) { curRobotID = ""; redrawRobot = true; AddAction(new MultiUndragableAction(affectedParts, e.target.selected)); } } } public virtual function frontButton(e:MouseEvent):void { if (simStarted) return; if (selectedParts.length == 1 && (selectedParts[0] is ShapePart || selectedParts[0] is PrismaticJoint)) { var oldIndex:int = -1; for (var i:int = 0; i < allParts.length; i++) { if (allParts[i] == selectedParts[0]) oldIndex = i; } allParts = Util.RemoveFromArray(selectedParts[0], allParts); allParts.push(selectedParts[0]); curRobotID = ""; AddAction(new MoveZAction(selectedParts[0], MoveZAction.FRONT_TYPE, oldIndex)); } else if (selectedParts.length == 1 && selectedParts[0] is TextPart) { if (!selectedParts[0].inFront) { selectedParts[0].inFront = true; removeChild(selectedParts[0].m_textField); addChildAt(selectedParts[0].m_textField, getChildIndex(m_canvas) + 1); AddAction(new MoveZAction(selectedParts[0], MoveZAction.FRONT_TYPE)); } } redrawRobot = true; } public virtual function backButton(e:MouseEvent):void { if (simStarted) return; if (selectedParts.length == 1 && (selectedParts[0] is ShapePart || selectedParts[0] is PrismaticJoint)) { var oldIndex:int = -1; var foundIt:Boolean = false; for (var i:int = allParts.length - 1; i > 0; i--) { if (allParts[i] == selectedParts[0]) { oldIndex = i; foundIt = true; } if (foundIt) { if (!allParts[i - 1].isEditable) { break; } allParts[i] = allParts[i - 1]; } } allParts[i] = selectedParts[0]; curRobotID = ""; AddAction(new MoveZAction(selectedParts[0], MoveZAction.BACK_TYPE, oldIndex)); } else if (selectedParts.length == 1 && selectedParts[0] is TextPart) { if (selectedParts[0].inFront) { selectedParts[0].inFront = false; removeChild(selectedParts[0].m_textField); addChildAt(selectedParts[0].m_textField, getChildIndex(m_canvas)); AddAction(new MoveZAction(selectedParts[0], MoveZAction.BACK_TYPE)); } } redrawRobot = true; } public function scaleWithZoomBox(e:Event):void { if (selectedParts.length == 1 && selectedParts[0] is TextPart) { (selectedParts[0] as TextPart).scaleWithZoom = e.target.selected; curRobotID = ""; AddAction(new TextCheckboxAction(selectedParts[0], TextCheckboxAction.SCALE_TYPE, e.target.selected)); } } public function alwaysVisibleBox(e:Event):void { if (selectedParts.length == 1 && selectedParts[0] is TextPart) { (selectedParts[0] as TextPart).alwaysVisible = e.target.selected; curRobotID = ""; m_sidePanel.EnableTextStuff(!e.target.selected); AddAction(new TextCheckboxAction(selectedParts[0], TextCheckboxAction.DISPLAY_TYPE, e.target.selected)); } } public function textKeyBox(e:KeyboardEvent):void { if (e.currentTarget.enabled) { var str:String; if (selectedParts[0] is TextPart) { var oldKey:int = (selectedParts[0] as TextPart).displayKey; (selectedParts[0] as TextPart).displayKey = e.keyCode; if (oldKey != e.keyCode) AddAction(new ControlKeyAction(selectedParts[0], ControlKeyAction.TEXT_TYPE, oldKey, e.keyCode)); } str = Input.getKeyString(e.keyCode); if (str == null) str = "Unk: " + e.keyCode; e.target.text = str; e.target.setSelection(0, 10); curRobotID = ""; } } public function textEntered(e:Event):void { if (selectedParts[0] is ShapePart) { lastSelectedShape = selectedParts[0]; } else if (selectedParts[0] is JointPart) { lastSelectedJoint = selectedParts[0]; } else if (selectedParts[0] is TextPart) { lastSelectedText = selectedParts[0]; } else if (selectedParts[0] is Thrusters) { lastSelectedThrusters = selectedParts[0]; } } public function colourButton(red:int, green:int, blue:int, opacity:int, defaultColour:Boolean):void { var oldRed:int, oldGreen:int, oldBlue:int, oldOpacity:int; if (defaultColour) { defaultR = red; defaultG = green; defaultB = blue; defaultO = opacity; } if (selectedParts.length == 1) { if (selectedParts[0] is ShapePart || selectedParts[0] is PrismaticJoint || selectedParts[0] is TextPart) { oldRed = selectedParts[0].red; oldGreen = selectedParts[0].green; oldBlue = selectedParts[0].blue; selectedParts[0].red = red; selectedParts[0].green = green; selectedParts[0].blue = blue; if (!(selectedParts[0] is TextPart)) { oldOpacity = selectedParts[0].opacity; selectedParts[0].opacity = opacity; } if (oldRed != selectedParts[0].red || oldGreen != selectedParts[0].green || oldBlue != selectedParts[0].blue || (!(selectedParts[0] is TextPart) && oldOpacity != selectedParts[0].opacity)) { AddAction(new ColourChangeAction(selectedParts[0], selectedParts[0].red - oldRed, selectedParts[0].green - oldGreen, selectedParts[0].blue - oldBlue, (selectedParts[0] is TextPart ? 0 : selectedParts[0].opacity - oldOpacity))); curRobotID = ""; redrawRobot = true; } } } else if (selectedParts.length > 1) { var affectedParts:Array = new Array(); var oldReds:Array = new Array(); var oldGreens:Array = new Array(); var oldBlues:Array = new Array(); var oldOpacities:Array = new Array(); for (var i:int = 0; i < selectedParts.length; i++) { if (selectedParts[i] is ShapePart || selectedParts[i] is PrismaticJoint || selectedParts[i] is TextPart) { if (selectedParts[i].red != red || selectedParts[i].green != green || selectedParts[i].blue != blue || (!(selectedParts[i] is TextPart) && selectedParts[i].opacity != opacity)) { oldReds.push(selectedParts[i].red); oldGreens.push(selectedParts[i].green); oldBlues.push(selectedParts[i].blue); oldOpacities.push(selectedParts[i] is TextPart ? 0 : selectedParts[i].opacity); selectedParts[i].red = red; selectedParts[i].green = green; selectedParts[i].blue = blue; if (!(selectedParts[i] is TextPart)) selectedParts[i].opacity = opacity; affectedParts.push(selectedParts[i]); } } } if (affectedParts.length > 0) { curRobotID = ""; redrawRobot = true; AddAction(new MultiColourChangeAction(affectedParts, red, green, blue, opacity, oldReds, oldGreens, oldBlues, oldOpacities)); } } } public function textTextStart(e:Event):void { if (selectedParts.length == 1 && selectedParts[0] is TextPart) { oldText = selectedParts[0].text; } } public function textText(e:Event):void { textEntered(e); if (lastSelectedText is TextPart) { newText = e.target; curRobotID = ""; redrawRobot = true; } } public function textTextFinish(e:Event):void { if (lastSelectedText is TextPart) { AddAction(new EnterTextAction(lastSelectedText, oldText, lastSelectedText.text)); } } public function sizeText(e:Event):void { if (lastSelectedText is TextPart) { var oldSize:int = lastSelectedText.size; lastSelectedText.size = parseInt(e.target.text); if (lastSelectedText.size < 4) lastSelectedText.size = 4; if (lastSelectedText.size > 36) lastSelectedText.size = 36; e.target.text = lastSelectedText.size + ""; curRobotID = ""; redrawRobot = true; if (oldSize != lastSelectedText.size) AddAction(new TextSizeChangeAction(lastSelectedText, lastSelectedText.size - oldSize)); } m_sidePanel.TextAreaLostFocus(); } public function minLimitText(e:Event):void { var limit:Number = Number(e.target.text.replace("\n", "")); if (e.target.text == "") limit = NaN; if (lastSelectedJoint is RevoluteJoint) { if (isNaN(limit)) { limit = -Number.MAX_VALUE; e.target.text = "None"; } else if (limit >= 0.0) { limit = 0; e.target.text = 0; } var oldLimit:Number = (lastSelectedJoint as RevoluteJoint).motorLowerLimit; (lastSelectedJoint as RevoluteJoint).motorLowerLimit = limit; if (limit != oldLimit) AddAction(new LimitChangeAction(lastSelectedJoint, LimitChangeAction.MIN_TYPE, oldLimit, limit)); } m_sidePanel.TextAreaLostFocus(); curRobotID = ""; } public function maxLimitText(e:Event):void { var limit:Number = Number(e.target.text.replace("\n", "")); if (e.target.text == "") limit = NaN; if (lastSelectedJoint is RevoluteJoint) { if (isNaN(limit)) { limit = Number.MAX_VALUE; e.target.text = "None"; } else if (limit <= 0.0) { limit = 0; e.target.text = 0; } var oldLimit:Number = (lastSelectedJoint as RevoluteJoint).motorUpperLimit; (lastSelectedJoint as RevoluteJoint).motorUpperLimit = limit; if (limit != oldLimit) AddAction(new LimitChangeAction(lastSelectedJoint, LimitChangeAction.MAX_TYPE, oldLimit, limit)); } m_sidePanel.TextAreaLostFocus(); curRobotID = ""; } public function controlKeyText1(e:KeyboardEvent):void { if (e.currentTarget.enabled) { var str:String; var oldKey:int; if (selectedParts[0] is RevoluteJoint) { oldKey = (selectedParts[0] as RevoluteJoint).motorCWKey; (selectedParts[0] as RevoluteJoint).motorCWKey = e.keyCode; if (oldKey != e.keyCode) AddAction(new ControlKeyAction(selectedParts[0], ControlKeyAction.CW_TYPE, oldKey, e.keyCode)); } else { oldKey = (selectedParts[0] as PrismaticJoint).pistonUpKey; (selectedParts[0] as PrismaticJoint).pistonUpKey = e.keyCode; if (oldKey != e.keyCode) AddAction(new ControlKeyAction(selectedParts[0], ControlKeyAction.EXPAND_TYPE, oldKey, e.keyCode)); } str = Input.getKeyString(e.keyCode); if (str == null) str = "Unk: " + e.keyCode; e.target.text = str; e.target.setSelection(0, 10); curRobotID = ""; } } public function controlKeyText2(e:KeyboardEvent):void { if (e.currentTarget.enabled) { var str:String; var oldKey:int; if (selectedParts[0] is RevoluteJoint) { oldKey = (selectedParts[0] as RevoluteJoint).motorCCWKey; (selectedParts[0] as RevoluteJoint).motorCCWKey = e.keyCode; if (oldKey != e.keyCode) AddAction(new ControlKeyAction(selectedParts[0], ControlKeyAction.CCW_TYPE, oldKey, e.keyCode)); } else { oldKey = (selectedParts[0] as PrismaticJoint).pistonDownKey; (selectedParts[0] as PrismaticJoint).pistonDownKey = e.keyCode; if (oldKey != e.keyCode) AddAction(new ControlKeyAction(selectedParts[0], ControlKeyAction.CONTRACT_TYPE, oldKey, e.keyCode)); } str = Input.getKeyString(e.keyCode); if (str == null) str = "Unk: " + e.keyCode; e.target.text = str; e.target.setSelection(0, 10); curRobotID = ""; } } public function thrustKeyText(e:KeyboardEvent):void { if (e.currentTarget.enabled) { var str:String; var oldKey:int; if (selectedParts[0] is Thrusters) { oldKey = (selectedParts[0] as Thrusters).thrustKey; (selectedParts[0] as Thrusters).thrustKey = e.keyCode; if (oldKey != e.keyCode) AddAction(new ControlKeyAction(selectedParts[0], ControlKeyAction.THRUSTERS_TYPE, oldKey, e.keyCode)); } str = Input.getKeyString(e.keyCode); if (str == null) str = "Unk: " + e.keyCode; e.target.text = str; e.target.setSelection(0, 10); curRobotID = ""; } } public function fireKeyText(e:KeyboardEvent):void { if (e.currentTarget.enabled) { var str:String; var oldKey:int; if (selectedParts[0] is Cannon) { oldKey = (selectedParts[0] as Cannon).fireKey; (selectedParts[0] as Cannon).fireKey = e.keyCode; if (oldKey != e.keyCode) AddAction(new ControlKeyAction(selectedParts[0], ControlKeyAction.CANNON_TYPE, oldKey, e.keyCode)); } str = Input.getKeyString(e.keyCode); if (str == null) str = "Unk: " + e.keyCode; e.target.text = str; e.target.setSelection(0, 10); curRobotID = ""; } } public function autoBox1(e:MouseEvent):void { if (selectedParts[0] is RevoluteJoint) { var sideEffect:Boolean = (e.target.selected && (selectedParts[0] as RevoluteJoint).autoCCW); (selectedParts[0] as RevoluteJoint).autoCW = e.target.selected; if (e.target.selected) { (selectedParts[0] as RevoluteJoint).autoCCW = false; m_sidePanel.deselectBox2(); } AddAction(new JointCheckboxAction(selectedParts[0], JointCheckboxAction.AUTO_CW_TYPE, e.target.selected, sideEffect)); } else if (selectedParts[0] is PrismaticJoint) { (selectedParts[0] as PrismaticJoint).autoOscillate = e.target.selected; AddAction(new JointCheckboxAction(selectedParts[0], JointCheckboxAction.AUTO_OSCILLATE_TYPE, e.target.selected)); } else if (selectedParts[0] is Thrusters) { (selectedParts[0] as Thrusters).autoOn = e.target.selected; AddAction(new JointCheckboxAction(selectedParts[0], JointCheckboxAction.AUTO_ON_TYPE, e.target.selected)); } curRobotID = ""; } public function autoBox2(e:MouseEvent):void { if (selectedParts[0] is RevoluteJoint) { var sideEffect:Boolean = (e.target.selected && (selectedParts[0] as RevoluteJoint).autoCW); (selectedParts[0] as RevoluteJoint).autoCCW = e.target.selected; if (e.target.selected) { (selectedParts[0] as RevoluteJoint).autoCW = false; m_sidePanel.deselectBox1(); } AddAction(new JointCheckboxAction(selectedParts[0], JointCheckboxAction.AUTO_CCW_TYPE, e.target.selected, sideEffect)); } curRobotID = ""; } public function motorBox(e:MouseEvent):void { if (selectedParts[0] is RevoluteJoint) { (selectedParts[0] as RevoluteJoint).enableMotor = e.target.selected; } else if (selectedParts[0] is PrismaticJoint) { (selectedParts[0] as PrismaticJoint).enablePiston = e.target.selected; } m_sidePanel.EnableMotorStuff(e.target.selected); curRobotID = ""; AddAction(new JointCheckboxAction(selectedParts[0], JointCheckboxAction.ENABLE_TYPE, e.target.selected)); } public function rigidBox(e:MouseEvent):void { if (selectedParts[0] is RevoluteJoint) { (selectedParts[0] as RevoluteJoint).isStiff = !e.target.selected; } else if (selectedParts[0] is PrismaticJoint) { (selectedParts[0] as PrismaticJoint).isStiff = !e.target.selected; } curRobotID = ""; AddAction(new JointCheckboxAction(selectedParts[0], JointCheckboxAction.RIGID_TYPE, e.target.selected)); } public function strengthSlider(e:Event):void { var oldStrength:Number; if (selectedParts[0] is RevoluteJoint) { oldStrength = (selectedParts[0] as RevoluteJoint).motorStrength; (selectedParts[0] as RevoluteJoint).motorStrength = e.target.value; if (oldStrength != e.target.value) AddAction(new ChangeSliderAction(selectedParts[0], ChangeSliderAction.STRENGTH_TYPE, e.target.value - oldStrength)); } else if (selectedParts[0] is PrismaticJoint) { oldStrength = (selectedParts[0] as PrismaticJoint).pistonStrength; (selectedParts[0] as PrismaticJoint).pistonStrength = e.target.value; if (oldStrength != e.target.value) AddAction(new ChangeSliderAction(selectedParts[0], ChangeSliderAction.STRENGTH_TYPE, e.target.value - oldStrength)); } curRobotID = ""; m_sidePanel.SetStrength(e.target.value); } public function speedSlider(e:Event):void { var oldSpeed:Number; if (selectedParts[0] is RevoluteJoint) { oldSpeed = (selectedParts[0] as RevoluteJoint).motorSpeed; (selectedParts[0] as RevoluteJoint).motorSpeed = e.target.value; if (oldSpeed != e.target.value) AddAction(new ChangeSliderAction(selectedParts[0], ChangeSliderAction.SPEED_TYPE, e.target.value - oldSpeed)); } else if (selectedParts[0] is PrismaticJoint) { oldSpeed = (selectedParts[0] as PrismaticJoint).pistonSpeed; (selectedParts[0] as PrismaticJoint).pistonSpeed = e.target.value; if (oldSpeed != e.target.value) AddAction(new ChangeSliderAction(selectedParts[0], ChangeSliderAction.SPEED_TYPE, e.target.value - oldSpeed)); } curRobotID = ""; m_sidePanel.SetSpeed(e.target.value); } public function thrustSlider(e:Event):void { var oldStrength:Number; if (selectedParts[0] is Thrusters) { oldStrength = (selectedParts[0] as Thrusters).strength; (selectedParts[0] as Thrusters).strength = e.target.value; if (oldStrength != e.target.value) AddAction(new ChangeSliderAction(selectedParts[0], ChangeSliderAction.STRENGTH_TYPE, e.target.value - oldStrength)); } curRobotID = ""; m_sidePanel.SetThrust(e.target.value); } public function cannonSlider(e:Event):void { var oldStrength:Number; if (selectedParts[0] is Cannon) { oldStrength = (selectedParts[0] as Cannon).strength; (selectedParts[0] as Cannon).strength = e.target.value; if (oldStrength != e.target.value) AddAction(new ChangeSliderAction(selectedParts[0], ChangeSliderAction.STRENGTH_TYPE, e.target.value - oldStrength)); } curRobotID = ""; m_sidePanel.SetCannon(e.target.value); } public virtual function zoomInButton(e:MouseEvent):void { Zoom(true); } public virtual function zoomOutButton(e:MouseEvent):void { Zoom(false); } public function clearButton(e:MouseEvent):void { if (simStarted) return; if (selectingCondition) return; var deletedParts:Array = allParts.filter(PartIsEditable); for (var i:int = 0; i < deletedParts.length; i++) { if (deletedParts[i] is ShapePart || deletedParts[i] is TextPart) { DeletePart(deletedParts[i], false); } } if (deletedParts.length != 0) { if (curRobotEditable) AddAction(new ClearAction(deletedParts)); CheckIfPartsFit(); curRobotID = ""; redrawRobot = true; } if (!curRobotEditable) curRobotEditable = true; if (m_sidePanel && m_sidePanel.visible) m_sidePanel.visible = false; } public virtual function undoButton(e:MouseEvent):void { if (selectingCondition) return; if (curRobotEditable && lastAction != -1 && !simStarted) { actions[lastAction].UndoAction(); lastAction--; curAction = -1; curRobotID = ""; CheckIfPartsFit(); if (selectedParts.length == 0) m_sidePanel.visible = false; RefreshSidePanel(); redrawRobot = true; } } public virtual function redoButton(e:MouseEvent):void { if (selectingCondition) return; if (curRobotEditable && lastAction < actions.length - 1 && !simStarted) { actions[lastAction + 1].RedoAction(); lastAction++; curAction = -1; curRobotID = ""; CheckIfPartsFit(); if (selectedParts.length == 0) m_sidePanel.visible = false; RefreshSidePanel(); redrawRobot = true; } } public function cutButton(e:MouseEvent):void { if (selectingCondition) return; if (simStarted) return; copiedJoint = null; copiedThrusters = null; if (selectedParts.length == 1) { clipboardParts = new Array(); if (selectedParts[0] is ShapePart || selectedParts[0] is TextPart) { clipboardParts.push(selectedParts[0].MakeCopy()); } else if (selectedParts[0] is JointPart) { copiedJoint = selectedParts[0]; } else if (selectedParts[0] is Thrusters) { copiedThrusters = selectedParts[0]; } DeletePart(selectedParts[0]); m_sidePanel.visible = false; curAction = -1; curRobotID = ""; redrawRobot = true; } else if (selectedParts.length > 1) { clipboardParts = new Array(); var partMapping:Array = new Array(); var affectedJoints:Array = new Array(); for (var i:int = 0; i < selectedParts.length; i++) { if (selectedParts[i] is ShapePart) { var copiedPart:ShapePart = (selectedParts[i] as ShapePart).MakeCopy(); clipboardParts.push(copiedPart); partMapping.push(copiedPart); affectedJoints = affectedJoints.concat(selectedParts[i].GetActiveJoints()); DeletePart(selectedParts[i], false, false); } else if (selectedParts[i] is TextPart) { clipboardParts.push((selectedParts[i] as TextPart).MakeCopy()); partMapping.push(-1); DeletePart(selectedParts[i], false, false); } else { partMapping.push(-1); } } for (i = 0; i < selectedParts.length; i++) { if (selectedParts[i] is JointPart) { var index1:int = -1, index2:int = -1; for (var j:int = 0; j < selectedParts.length; j++) { if (selectedParts[j] == (selectedParts[i] as JointPart).part1) index1 = j; if (selectedParts[j] == (selectedParts[i] as JointPart).part2) index2 = j; } if (index1 != -1 && index2 != -1) clipboardParts.push((selectedParts[i] as JointPart).MakeCopy(partMapping[index1], partMapping[index2])); DeletePart(selectedParts[i], false, false); } else if (selectedParts[i] is Thrusters) { index1 = -1; for (j = 0; j < selectedParts.length; j++) { if (selectedParts[j] == (selectedParts[i] as Thrusters).shape) index1 = j; } if (index1 != -1) clipboardParts.push((selectedParts[i] as Thrusters).MakeCopy(partMapping[index1])); DeletePart(selectedParts[i], false, false); } } var deletedParts:Array = Util.RemoveDuplicates(selectedParts.concat(affectedJoints)); AddAction(new ClearAction(deletedParts)); selectedParts = new Array(); m_sidePanel.visible = false; CheckIfPartsFit(); curAction = -1; curRobotID = ""; redrawRobot = true; } } public virtual function copyButton(e:MouseEvent):void { if (selectingCondition) return; if (simStarted) return; copiedJoint = null; copiedThrusters = null; if (selectedParts.length == 1) { clipboardParts = new Array(); if (selectedParts[0] is ShapePart || selectedParts[0] is TextPart) { clipboardParts.push(selectedParts[0].MakeCopy()); } else if (selectedParts[0] is JointPart) { copiedJoint = selectedParts[0]; } else if (selectedParts[0] is Thrusters) { copiedThrusters = selectedParts[0]; } curAction = -1; } else if (selectedParts.length > 1) { clipboardParts = new Array(); var partMapping:Array = new Array(); for (var i:int = 0; i < selectedParts.length; i++) { if (selectedParts[i] is ShapePart) { var copiedPart:ShapePart = (selectedParts[i] as ShapePart).MakeCopy(); clipboardParts.push(copiedPart); partMapping.push(copiedPart); } else if (selectedParts[i] is TextPart) { clipboardParts.push((selectedParts[i] as TextPart).MakeCopy()); partMapping.push(-1); } else { partMapping.push(-1); } } for (i = 0; i < selectedParts.length; i++) { if (selectedParts[i] is JointPart) { var index1:int = -1, index2:int = -1; for (var j:int = 0; j < selectedParts.length; j++) { if (selectedParts[j] == (selectedParts[i] as JointPart).part1) index1 = j; if (selectedParts[j] == (selectedParts[i] as JointPart).part2) index2 = j; } if (index1 != -1 && index2 != -1) clipboardParts.push((selectedParts[i] as JointPart).MakeCopy(partMapping[index1], partMapping[index2])); } else if (selectedParts[i] is Thrusters) { index1 = -1; for (j = 0; j < selectedParts.length; j++) { if (selectedParts[j] == (selectedParts[i] as Thrusters).shape) index1 = j; } if (index1 != -1) clipboardParts.push((selectedParts[i] as Thrusters).MakeCopy(partMapping[index1])); } } curAction = -1; } } public virtual function pasteButton(e:MouseEvent):void { if (selectingCondition) return; if (!curRobotEditable) return; if (simStarted) return; var hasCircles:Boolean = false; var hasRects:Boolean = false; var hasTriangles:Boolean = false; var hasFJs:Boolean = false; var hasRJs:Boolean = false; var hasSJs:Boolean = false; var hasThrusters:Boolean = false; var hasCannons:Boolean = false; var hasStatic:Boolean = false; for (var i:int = 0; i < clipboardParts.length; i++) { if (clipboardParts[i].isStatic) hasStatic = true; if (clipboardParts[i] is Circle) hasCircles = true; if (clipboardParts[i] is Rectangle) hasRects = true; if (clipboardParts[i] is Triangle) hasTriangles = true; if (clipboardParts[i] is FixedJoint) hasFJs = true; if (clipboardParts[i] is RevoluteJoint) hasRJs = true; if (clipboardParts[i] is PrismaticJoint) hasSJs = true; if (clipboardParts[i] is Thrusters) hasThrusters = true; if (clipboardParts[i] is Cannon) hasCannons = true; } if (this is ControllerChallenge && ControllerChallenge.playChallengeMode && ((hasStatic && !ControllerChallenge.challenge.fixateAllowed) || (hasCircles && !ControllerChallenge.challenge.circlesAllowed) || (hasRects && !ControllerChallenge.challenge.rectanglesAllowed) || (hasTriangles && !ControllerChallenge.challenge.trianglesAllowed) || (hasFJs && !ControllerChallenge.challenge.fixedJointsAllowed) || (hasRJs && !ControllerChallenge.challenge.rotatingJointsAllowed) || (hasSJs && !ControllerChallenge.challenge.slidingJointsAllowed) || (hasThrusters && !ControllerChallenge.challenge.thrustersAllowed) || (hasCannons && !ControllerChallenge.challenge.cannonsAllowed))) { m_fader.visible = true; ShowDialog3("Sorry, some of the copied parts are not allowed in this challenge!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); Main.ShowMouse(); return; } else if (/*!Main.premiumMode && (hasThrusters || copiedThrusters)*/ false) { m_fader.visible = true; ShowDialog3("Sorry, only supporters are allowed to paste thrusters!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); Main.ShowMouse(); return; } else if (/*!Main.premiumMode && hasCannons*/ false) { m_fader.visible = true; ShowDialog3("Sorry, only supporters are allowed to paste cannons!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); Main.ShowMouse(); return; } if (clipboardParts.length == 1 && clipboardParts[0] is ShapePart) { clipboardParts[0].Move(mouseXWorldPhys, mouseYWorldPhys); allParts.push(clipboardParts[0]); selectedParts = new Array(); selectedParts.push(clipboardParts[0]); draggingPart = clipboardParts[0]; initDragX = mouseXWorldPhys; initDragY = mouseYWorldPhys; draggingParts = draggingPart.GetAttachedParts(); draggingPart.dragXOff = 0; draggingPart.dragYOff = 0; if (clipboardParts[0] is Cannon) m_sidePanel.ShowCannonPanel(clipboardParts[0]); else m_sidePanel.ShowObjectPanel(clipboardParts[0]); AddAction(new CreateAction(clipboardParts[0])); clipboardParts[0] = clipboardParts[0].MakeCopy(); curAction = PASTE; curRobotID = ""; } else if (copiedJoint) { if (copiedJoint is FixedJoint) { curAction = NEW_FIXED_JOINT; } else if (copiedJoint is RevoluteJoint) { curAction = NEW_REVOLUTE_JOINT; } else { curAction = NEW_PRISMATIC_JOINT; } actionStep = 0; } else if (copiedThrusters) { curAction = NEW_THRUSTERS; } else { draggingPart = null; m_sidePanel.visible = false; selectedParts = new Array(); draggingParts = new Array(); for (i = 0; i < clipboardParts.length; i++) { if (clipboardParts[i] is ShapePart) { if (!draggingPart || draggingPart is TextPart || clipboardParts[i].GetMass() > (draggingPart as ShapePart).GetMass()) draggingPart = clipboardParts[i]; } else if (clipboardParts[i] is TextPart && !draggingPart) { draggingPart = clipboardParts[i]; } } var oldClipboardParts:Array = new Array(); for (i = 0; i < clipboardParts.length; i++) { oldClipboardParts.push(clipboardParts[i]); } for (i = 0; i < clipboardParts.length; i++) { if (clipboardParts[i] is ShapePart) { clipboardParts[i].dragXOff = (draggingPart as ShapePart).centerX - clipboardParts[i].centerX; clipboardParts[i].dragYOff = (draggingPart as ShapePart).centerY - clipboardParts[i].centerY; allParts.push(clipboardParts[i]); selectedParts.push(clipboardParts[i]); draggingParts = Util.RemoveDuplicates(draggingParts.concat(clipboardParts[i].GetAttachedParts())); clipboardParts[i] = clipboardParts[i].MakeCopy(); if (oldClipboardParts[i] != draggingPart) oldClipboardParts[i].Move(oldClipboardParts[i].centerX - (draggingPart as ShapePart).centerX + mouseXWorldPhys, oldClipboardParts[i].centerY - (draggingPart as ShapePart).centerY + mouseYWorldPhys); } else if (clipboardParts[i] is TextPart) { if (draggingPart is ShapePart) { clipboardParts[i].dragXOff = (draggingPart as ShapePart).centerX - clipboardParts[i].x; clipboardParts[i].dragYOff = (draggingPart as ShapePart).centerY - clipboardParts[i].y; } else { clipboardParts[i].dragXOff = (draggingPart as TextPart).x - clipboardParts[i].x; clipboardParts[i].dragYOff = (draggingPart as TextPart).y - clipboardParts[i].y; } allParts.push(clipboardParts[i]); selectedParts.push(clipboardParts[i]); draggingParts = draggingParts.concat(clipboardParts[i].GetAttachedParts()); clipboardParts[i] = clipboardParts[i].MakeCopy(); if (oldClipboardParts[i] != draggingPart) { if (draggingPart is ShapePart) { oldClipboardParts[i].Move(oldClipboardParts[i].x - (draggingPart as ShapePart).centerX + mouseXWorldPhys, oldClipboardParts[i].y - (draggingPart as ShapePart).centerY + mouseYWorldPhys); } else { oldClipboardParts[i].Move(oldClipboardParts[i].x - (draggingPart as TextPart).x + mouseXWorldPhys, oldClipboardParts[i].y - (draggingPart as TextPart).y + mouseYWorldPhys); } } } } for (i = 0; i < clipboardParts.length; i++) { if (clipboardParts[i] is JointPart) { clipboardParts[i].dragXOff = (draggingPart as ShapePart).centerX - clipboardParts[i].anchorX; clipboardParts[i].dragYOff = (draggingPart as ShapePart).centerY - clipboardParts[i].anchorY; allParts.push(clipboardParts[i]); selectedParts.push(clipboardParts[i]); var index1:int = -1, index2:int = -1; for (var j:int = 0; j < oldClipboardParts.length; j++) { if (oldClipboardParts[j] == (clipboardParts[i] as JointPart).part1) index1 = j; if (oldClipboardParts[j] == (clipboardParts[i] as JointPart).part2) index2 = j; } clipboardParts[i] = clipboardParts[i].MakeCopy(clipboardParts[index1], clipboardParts[index2]); oldClipboardParts[i].Move(oldClipboardParts[i].anchorX - (draggingPart as ShapePart).centerX + mouseXWorldPhys, oldClipboardParts[i].anchorY - (draggingPart as ShapePart).centerY + mouseYWorldPhys); } else if (clipboardParts[i] is Thrusters) { clipboardParts[i].dragXOff = (draggingPart as ShapePart).centerX - clipboardParts[i].centerX; clipboardParts[i].dragYOff = (draggingPart as ShapePart).centerY - clipboardParts[i].centerY; allParts.push(clipboardParts[i]); selectedParts.push(clipboardParts[i]); index1 = -1; for (j = 0; j < oldClipboardParts.length; j++) { if (oldClipboardParts[j] == (clipboardParts[i] as Thrusters).shape) index1 = j; } clipboardParts[i] = clipboardParts[i].MakeCopy(clipboardParts[index1]); oldClipboardParts[i].Move(oldClipboardParts[i].centerX - (draggingPart as ShapePart).centerX + mouseXWorldPhys, oldClipboardParts[i].centerY - (draggingPart as ShapePart).centerY + mouseYWorldPhys); } } if (draggingPart) { initDragX = mouseXWorldPhys; initDragY = mouseYWorldPhys; draggingPart.Move(mouseXWorldPhys, mouseYWorldPhys); m_sidePanel.ShowMultiSelectPanel(selectedParts); AddAction(new MassCreateAction(selectedParts)); curAction = PASTE; curRobotID = ""; } } } public virtual function centerBox(e:MouseEvent):void { snapToCenter = !snapToCenter; } public function jointBox(e:MouseEvent):void { showJoints = !showJoints redrawRobot = true; } public function globalOutlineBox(e:MouseEvent):void { showOutlines = !showOutlines; redrawRobot = true; } public function colourBox(e:MouseEvent):void { showColours = !showColours; if (showColours) draw.m_fillAlpha = 1.0; else draw.m_fillAlpha = 0.5; redrawRobot = true; } public function centerOnSelectedBox(e:MouseEvent):void { centerOnSelected = !centerOnSelected; if (centerOnSelected && selectedParts.length == 1) { CenterOnSelected(); } } public function ConfirmNewRobot(e:MouseEvent):void { Main.changeControllers = true; Main.nextControllerType = -1; playingReplay = false; viewingUnsavedReplay = false; } public virtual override function loginButton(e:MouseEvent, displayMessage:Boolean = false, backToSave:Boolean = false, saveLoadWindowOpen:Boolean = false):void { if (selectingCondition) return; if (Main.inIFrame) { m_fader.visible = true; ShowConfirmDialog("Redirect to incredibots2.com?", 7); } else { m_fader.visible = true; if (m_loginWindow) removeChild(m_loginWindow); m_loginWindow = new LoginWindow(this); if (displayMessage) m_loginWindow.displayMessage(); addChild(m_loginWindow); backToSaveWindow = backToSave; } } public function logoutButton(e:MouseEvent):void { m_fader.visible = true; ShowConfirmDialog("Are you sure you want to log " + userName + " out?", 12); } public override function ConfirmLogout(e:MouseEvent):void { Main.premiumMode = false; userName = "_Public"; m_guiPanel.ShowLogin(); ShowDialog3("You are now logged out."); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); m_fader.visible = true; } public function loginHidden(e:Event, success:Boolean):void { if (clickedSave) { clickedSave = false; saveButton(new MouseEvent("")); } else if (clickedSaveReplay) { clickedSaveReplay = false; saveReplayButton(new MouseEvent("")); } else if (clickedSaveChallenge) { clickedSaveChallenge = false; saveButton(new MouseEvent("")); } else if (clickedSubmitScore) { AddSyncPoint(); if (viewingUnsavedReplay) Database.SaveReplay(userName, password, replay, "_ScoreReplay", "This replay is saved for a score", curRobotID, new Robot(allParts, ControllerSandbox.settings), (ChallengeOver() ? GetScore() : -1), curChallengeID, 1, finishSavingReplay); else Database.SaveReplay(userName, password, new Replay(cameraMovements, syncPoints, keyPresses, frameCounter, Database.VERSION_STRING_FOR_REPLAYS), "_ScoreReplay", "This replay is saved for a score", curRobotID, new Robot(allParts, ControllerSandbox.settings), (ChallengeOver() ? GetScore() : -1), curChallengeID, 1, finishSavingReplay); m_scoreWindow.ShowFader(); ShowDialog("Submitting score..."); Main.ShowHourglass(); } else if (clickedReport) { clickedReport = false; reportButton(new MouseEvent("")); } else if (backToSaveWindow) { m_fader.visible = true; if (m_chooserWindow.visible) { if (success) { m_chooserWindow.reportClicked(new MouseEvent("")); } else { m_chooserWindow.HideFader(); } } else { m_chooserWindow.visible = true; if (m_chooserWindow.dataType == SaveLoadWindow.HIGH_SCORE_TYPE) { Database.GetScoreData(userName, password, Database.highScoresChallenge, m_chooserWindow.m_scoreTypeBox.selectedIndex == 1, m_chooserWindow.m_scoreTypeBox.selectedIndex == 2, (success && m_chooserWindow.m_scoreTypeBox.selectedIndex == 2 ? Database.SORT_BY_SCORE : Database.highScoresSortType), (success && m_chooserWindow.m_scoreTypeBox.selectedIndex == 2 ? 1 : Database.curScorePage), (success && m_chooserWindow.m_scoreTypeBox && m_chooserWindow.m_scoreTypeBox.selectedIndex == 2 ? "" : Database.curSearch), finishGettingScoreData); ShowDialog("Getting scores..."); } else if (m_chooserWindow.dataType == SaveLoadWindow.LOAD_ROBOT_TYPE) { Database.GetRobotData(userName, password, !m_chooserWindow.yourRobotsBox.selected, (success && m_chooserWindow.yourRobotsBox.selected ? Database.SORT_BY_EDIT_TIME : Database.curSortType), (success && m_chooserWindow.yourRobotsBox.selected ? Database.SORT_PERIOD_ALLTIME : Database.curSortPeriod), (success && m_chooserWindow.yourRobotsBox.selected ? 1 : Database.curRobotPage), (success && m_chooserWindow.m_scoreTypeBox && m_chooserWindow.m_scoreTypeBox.selectedIndex == 2 ? "" : Database.curSearch), finishGettingLoadRobotData); ShowDialog("Getting robots..."); } else if (m_chooserWindow.dataType == SaveLoadWindow.LOAD_CHALLENGE_TYPE) { if (Database.curSortPeriod == Database.SORT_PERIOD_PROP) Database.curSortPeriod = Database.SORT_PERIOD_ALLTIME; Database.GetChallengeData(userName, password, !m_chooserWindow.yourRobotsBox.selected, (success && m_chooserWindow.yourRobotsBox.selected ? Database.SORT_BY_EDIT_TIME : Database.curSortType), (success && m_chooserWindow.yourRobotsBox.selected ? Database.SORT_PERIOD_ALLTIME : Database.curSortPeriod), (success && m_chooserWindow.yourRobotsBox.selected ? 1 : Database.curReplayPage), (success && m_chooserWindow.m_scoreTypeBox && m_chooserWindow.m_scoreTypeBox.selectedIndex == 2 ? "" : Database.curSearch), finishGettingLoadChallengeData); ShowDialog("Getting challenges..."); } else { if (Database.curSortPeriod == Database.SORT_PERIOD_PROP) Database.curSortPeriod = Database.SORT_PERIOD_ALLTIME; Database.GetReplayData(userName, password, !m_chooserWindow.yourRobotsBox.selected, (success && m_chooserWindow.yourRobotsBox.selected ? Database.SORT_BY_EDIT_TIME : Database.curSortType), (success && m_chooserWindow.yourRobotsBox.selected ? Database.SORT_PERIOD_ALLTIME : Database.curSortPeriod), (success && m_chooserWindow.yourRobotsBox.selected ? 1 : Database.curReplayPage), (success && m_chooserWindow.m_scoreTypeBox && m_chooserWindow.m_scoreTypeBox.selectedIndex == 2 ? "" : Database.curSearch), finishGettingLoadReplayData); ShowDialog("Getting replays..."); } m_chooserWindow.ShowFader(); Main.ShowHourglass(); } } } public function viewReplayButton(e:MouseEvent):void { if (viewingUnsavedReplay) { m_fader.visible = false; m_scoreWindow.visible = false; resetButton(e); } else { resetButton(e); replay = new Replay(cameraMovements, syncPoints, keyPresses, frameCounter, Database.VERSION_STRING_FOR_REPLAYS); replayParts = allParts.filter(IsPartOfRobot); playingReplay = true; Main.changeControllers = true; viewingUnsavedReplay = true; } } public function newButton(e:MouseEvent):void { if (Main.inIFrame) { m_fader.visible = true; ShowConfirmDialog("Redirect to incredibots2.com?", 7); } else { var partsExist:Boolean = false; for (var i:int = 0; i < allParts.length; i++) { if (allParts[i].isEditable) { partsExist = true; break; } } if (this is ControllerTutorial || this is ControllerHomeMovies || this is ControllerRubeGoldberg || this is ControllerNewFeatures || this is ControllerChallengeEditor || (curRobotID != "" && (!(this is ControllerChallenge) || curChallengeID != "")) || (!partsExist && !(this is ControllerChallenge))) { ConfirmNewRobot(e); } else { m_fader.visible = true; if (m_scoreWindow && m_scoreWindow.visible) m_scoreWindow.ShowFader(); ShowConfirmDialog("Exit to main menu? (Unsaved changes will be lost)", 4); } } } public virtual function saveButton(e:MouseEvent):void { if (selectingCondition) return; if (Main.inIFrame) { m_fader.visible = true; ShowConfirmDialog("Redirect to incredibots2.com?", 7); } else { if (!curRobotEditable || playingReplay) return; if (true || userName != "_Public") { if (/*!Main.premiumMode*/ false) { for (var i:int = 0; i < allParts.length; i++) { if (allParts[i] is Thrusters) { m_fader.visible = true; ShowDialog3("Sorry, only supporters are allowed to save robots containing thrusters!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); Main.ShowMouse(); return; } if (allParts[i] is Cannon) { m_fader.visible = true; ShowDialog3("Sorry, only supporters are allowed to save robots containing cannons!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); Main.ShowMouse(); return; } } } if (this is ControllerChallenge && !ControllerChallenge.playChallengeMode) { if (m_restrictionsDialog) removeChild(m_restrictionsDialog); m_restrictionsDialog = new RestrictionsWindow(this as ControllerChallenge); addChild(m_restrictionsDialog); saveAfterRestrictions = true; } else { //Database.GetRobotData(userName, password, false, Database.curSortType, (Database.curSortPeriod == Database.SORT_PERIOD_FEATURED ? Database.SORT_PERIOD_ALLTIME : Database.curSortPeriod), 1, "", finishGettingSaveRobotData); //ShowDialog("Getting robots..."); //Main.ShowHourglass(); Database.ExportRobot(new Robot(allParts.filter(PartIsEditable), ControllerSandbox.settings, draw.m_drawXOff, draw.m_drawYOff, m_physScale), "", "", 1, 1, 0, finishExporting); } m_fader.visible = true; curAction = -1; } else { clickedSave = true; loginButton(e, true, false); } } } public function loadAndInsertButton(e:MouseEvent):void { if (curRobotEditable && !selectingCondition && !playingReplay) { loadAndInsert = true; loadRobotButton(e); } } public virtual function loadButton(e:MouseEvent, makeThemRate:Boolean = true):void { if (selectingCondition) return; if (Main.inIFrame) { m_fader.visible = true; ShowConfirmDialog("Redirect to incredibots2.com?", 7); } else if (makeThemRate && playingReplay && curReplayID != "" && curReplayPublic && !ratedCurReplay && !LSOManager.HasRatedReplay(curReplayID)) { ratedCurReplay = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 1, 1); addChild(m_rateDialog); m_fader.visible = true; m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } else if (makeThemRate && !playingReplay && curChallengeID != "" && curChallengePublic && !ratedCurChallenge && !LSOManager.HasRatedChallenge(curChallengeID)) { ratedCurChallenge = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 2, 1); addChild(m_rateDialog); m_fader.visible = true; if (simStarted) { m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } } else if (makeThemRate && !playingReplay && curRobotID != "" && curRobotPublic && !ratedCurRobot && !LSOManager.HasRatedRobot(curRobotID)) { ratedCurRobot = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 0, 1); addChild(m_rateDialog); m_fader.visible = true; if (simStarted) { m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } } else { m_fader.visible = true; if (m_loadWindow) removeChild(m_loadWindow); m_loadWindow = new LoadWindow(this); addChild(m_loadWindow); } } public function loadRobotButton(e:MouseEvent, makeThemRate:Boolean = true):void { if (selectingCondition) return; if (Main.inIFrame) { m_fader.visible = true; ShowConfirmDialog("Redirect to incredibots2.com?", 7); } else if (makeThemRate && playingReplay && curReplayID != "" && curReplayPublic && !ratedCurReplay && !LSOManager.HasRatedReplay(curReplayID)) { ratedCurReplay = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 1, 2); addChild(m_rateDialog); m_fader.visible = true; m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } else if (makeThemRate && !playingReplay && curChallengeID != "" && curChallengePublic && !ratedCurChallenge && !LSOManager.HasRatedChallenge(curChallengeID)) { ratedCurChallenge = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 2, 2); addChild(m_rateDialog); m_fader.visible = true; if (simStarted) { m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } } else if (makeThemRate && !playingReplay && curRobotID != "" && curRobotPublic && !ratedCurRobot && !LSOManager.HasRatedRobot(curRobotID)) { ratedCurRobot = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 0, 2); addChild(m_rateDialog); m_fader.visible = true; m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } else { Database.GetRobotData(userName, password, Database.curShared, Database.curSortType, Database.curSortPeriod, (Database.curShared ? Database.curRobotPage : 1), "", finishGettingLoadRobotData); m_fader.visible = true; ShowDialog("Getting robots..."); Main.ShowHourglass(); curAction = -1; } } public function finishSaving(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_SAVE_ROBOT) return; var robotID:String = Database.FinishSavingRobot(e); if (robotID != "") { curRobotID = robotID; ratedCurRobot = true; curRobotPublic = potentialRobotPublic; curRobotFeatured = potentialRobotFeatured; m_progressDialog.SetMessage("Save successful!"); m_progressDialog.HideInXSeconds(1); m_chooserWindow.visible = false; removeChild(m_chooserWindow); m_chooserWindow = null; m_fader.visible = false; } } public function finishGettingSaveRobotData(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_GET_ROBOT_DATA) return; if (Database.FinishGettingRobotData(e)) { m_progressDialog.visible = false; if (m_chooserWindow) removeChild(m_chooserWindow); m_chooserWindow = new SaveLoadWindow(this, SaveLoadWindow.SAVE_ROBOT_TYPE); addChild(m_chooserWindow); } } public override function finishGettingLoadRobotData(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_GET_ROBOT_DATA) return; if (Database.FinishGettingRobotData(e)) { m_progressDialog.visible = false; if (m_chooserWindow) removeChild(m_chooserWindow); m_chooserWindow = new SaveLoadWindow(this, SaveLoadWindow.LOAD_ROBOT_TYPE); addChild(m_chooserWindow); } } public override function finishLoading(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_LOAD_ROBOT) return; var robot:Robot = Database.FinishLoadingRobot(e); processLoadedRobot(robot); } public override function processLoadedRobot(robot:Robot):void { if (robot) { var newParts:Array = robot.allParts; if (loadAndInsert) { loadAndInsert = false; var hasCircles:Boolean = false; var hasRects:Boolean = false; var hasTriangles:Boolean = false; var hasFJs:Boolean = false; var hasRJs:Boolean = false; var hasSJs:Boolean = false; var hasThrusters:Boolean = false; var hasCannons:Boolean = false; var hasStatic:Boolean = false; for (var i:int = 0; i < newParts.length; i++) { if (newParts[i].isStatic) hasStatic = true; if (newParts[i] is Circle) hasCircles = true; if (newParts[i] is Rectangle) hasRects = true; if (newParts[i] is Triangle) hasTriangles = true; if (newParts[i] is FixedJoint) hasFJs = true; if (newParts[i] is RevoluteJoint) hasRJs = true; if (newParts[i] is PrismaticJoint) hasSJs = true; if (newParts[i] is Thrusters) hasThrusters = true; if (newParts[i] is Cannon) hasCannons = true; } if (this is ControllerChallenge && ((hasStatic && !ControllerChallenge.challenge.fixateAllowed) || (hasCircles && !ControllerChallenge.challenge.circlesAllowed) || (hasRects && !ControllerChallenge.challenge.rectanglesAllowed) || (hasTriangles && !ControllerChallenge.challenge.trianglesAllowed) || (hasFJs && !ControllerChallenge.challenge.fixedJointsAllowed) || (hasRJs && !ControllerChallenge.challenge.rotatingJointsAllowed) || (hasSJs && !ControllerChallenge.challenge.slidingJointsAllowed) || (hasThrusters && !ControllerChallenge.challenge.thrustersAllowed) || (hasCannons && !ControllerChallenge.challenge.cannonsAllowed))) { m_fader.visible = true; loadAndInsert = true; ShowDialog3("Sorry, that robot contains parts that are not allowed in this challenge!"); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); Main.ShowMouse(); return; } else { curRobotID = ""; allParts = allParts.concat(newParts); CheckIfPartsFit(); m_progressDialog.SetMessage("Load successful!"); m_progressDialog.HideInXSeconds(1); if (m_chooserWindow) { m_chooserWindow.visible = false; removeChild(m_chooserWindow); m_chooserWindow = null; } m_fader.visible = false; curRobotEditable = (potentialRobotEditable/* && ((!hasThrusters && !hasCannons) || Main.premiumMode)*/); curRobotPublic = false; curRobotFeatured = false; redrawRobot = true; CenterOnLoadedRobot(); } } else { curRobotID = potentialRobotID; ratedCurRobot = false; curRobotEditable = (potentialRobotEditable/* && ((!hasThrusters && !hasCannons) || Main.premiumMode)*/); curRobotPublic = potentialRobotPublic; curRobotFeatured = potentialRobotFeatured; curReplayID = ""; loadedParts = newParts; Main.changeControllers = true; playingReplay = false; initX = robot.cameraX; initY = robot.cameraY; initZoom = robot.zoomLevel; if (robot.challenge) { Main.nextControllerType = 1; ControllerChallenge.challenge = robot.challenge; ControllerChallenge.playChallengeMode = true; ControllerChallenge.playOnlyMode = true; ControllerSandbox.settings = robot.challenge.settings; curChallengeID = potentialChallengeID; ratedCurChallenge = false; curChallengePublic = false; curChallengeFeatured = false; justLoadedRobotWithChallenge = true; } else { Main.nextControllerType = 0; ControllerSandbox.settings = robot.settings; curChallengeID = ""; } } } } public override function finishDeleting(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_DELETE_ROBOT) return; var id:String = Database.FinishDeletingRobot(e); if (id != "") { if (curRobotID == id) curRobotID = ""; m_progressDialog.SetMessage("Delete successful!"); m_progressDialog.HideInXSeconds(1); var type:int = m_chooserWindow.dataType; removeChild(m_chooserWindow); m_chooserWindow = new SaveLoadWindow(this, type); addChild(m_chooserWindow); removeChild(m_progressDialog); addChild(m_progressDialog); } } public override function finishExporting(exportStr:String, robotStr:String):void { if (m_chooserWindow) m_chooserWindow.visible = false; if (m_exportDialog) removeChild(m_exportDialog); m_exportDialog = new ExportWindow(this, exportStr, robotStr); m_fader.visible = true; addChild(m_exportDialog); } public virtual function saveReplayButton(e:MouseEvent):void { if (Main.inIFrame) { m_fader.visible = true; ShowConfirmDialog("Redirect to incredibots2.com?", 7); } else { pauseButton(e); if (canSaveReplay) { if (true || userName != "_Public") { //if (Database.curSortPeriod == Database.SORT_PERIOD_PROP) Database.curSortPeriod = Database.SORT_PERIOD_ALLTIME; //Database.GetReplayData(userName, password, false, Database.curSortType, (Database.curSortPeriod == Database.SORT_PERIOD_FEATURED ? Database.SORT_PERIOD_ALLTIME : Database.curSortPeriod), 1, "", finishGettingSaveReplayData); //ShowDialog("Getting replays..."); //Main.ShowHourglass(); //m_fader.visible = true; AddSyncPoint(); if (viewingUnsavedReplay) Database.ExportReplay(replay, "", "", curRobotID, new Robot(allParts, ControllerSandbox.settings), -1, "", 1, finishExporting); else Database.ExportReplay(new Replay(cameraMovements, syncPoints, keyPresses, frameCounter, Database.VERSION_STRING_FOR_REPLAYS), "", "", curRobotID, new Robot(allParts, ControllerSandbox.settings), -1, "", 1, finishExporting); } else { clickedSaveReplay = true; loginButton(e, true, false); } } else { m_fader.visible = true; if (frameCounter >= 9000) ShowDialog3("Sorry, you can only save replays that are under 5 minutes in length."); else ShowDialog3("Sorry, you can only save replays that contain 500 or fewer cannonballs."); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); } } } public virtual function loadReplayButton(e:MouseEvent, makeThemRate:Boolean = true):void { if (selectingCondition) return; if (Main.inIFrame) { m_fader.visible = true; ShowConfirmDialog("Redirect to incredibots2.com?", 7); } else if (makeThemRate && playingReplay && curReplayID != "" && curReplayPublic && !ratedCurReplay && !LSOManager.HasRatedReplay(curReplayID)) { ratedCurReplay = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 1, 3); addChild(m_rateDialog); m_fader.visible = true; m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } else if (makeThemRate && !playingReplay && curChallengeID != "" && curChallengePublic && !ratedCurChallenge && !LSOManager.HasRatedChallenge(curChallengeID)) { ratedCurChallenge = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 2, 3); addChild(m_rateDialog); m_fader.visible = true; if (simStarted) { m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } } else if (makeThemRate && !playingReplay && curRobotID != "" && curRobotPublic && !ratedCurRobot && !LSOManager.HasRatedRobot(curRobotID)) { ratedCurRobot = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 0, 3); addChild(m_rateDialog); m_fader.visible = true; m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } else { if (Database.curSortPeriod == Database.SORT_PERIOD_PROP) Database.curSortPeriod = Database.SORT_PERIOD_ALLTIME; Database.GetReplayData(userName, password, Database.curShared, Database.curSortType, Database.curSortPeriod, (Database.curShared ? Database.curReplayPage : 1), "", finishGettingLoadReplayData); ShowDialog("Getting replays..."); Main.ShowHourglass(); m_fader.visible = true; curAction = -1; } } public virtual function loadChallengeButton(e:MouseEvent, makeThemRate:Boolean = true):void { if (selectingCondition) return; if (Main.inIFrame) { m_fader.visible = true; ShowConfirmDialog("Redirect to incredibots2.com?", 7); } else if (makeThemRate && playingReplay && curReplayID != "" && curReplayPublic && !ratedCurReplay && !LSOManager.HasRatedReplay(curReplayID)) { ratedCurReplay = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 1, 4); addChild(m_rateDialog); m_fader.visible = true; m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } else if (makeThemRate && !playingReplay && curChallengeID != "" && curChallengePublic && !ratedCurChallenge && !LSOManager.HasRatedChallenge(curChallengeID)) { ratedCurChallenge = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 2, 4); addChild(m_rateDialog); m_fader.visible = true; if (simStarted) { m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } } else if (makeThemRate && !playingReplay && curRobotID != "" && curRobotPublic && !ratedCurRobot && !LSOManager.HasRatedRobot(curRobotID)) { ratedCurRobot = true; if (m_rateDialog) removeChild(m_rateDialog); m_rateDialog = new RateWindow(this, 0, 4); addChild(m_rateDialog); m_fader.visible = true; m_guiPanel.ShowPausePanel(!playingReplay); paused = true; } else { if (Database.curSortPeriod == Database.SORT_PERIOD_PROP) Database.curSortPeriod = Database.SORT_PERIOD_ALLTIME; Database.GetChallengeData(userName, password, Database.curShared, Database.curSortType, Database.curSortPeriod, (Database.curShared ? Database.curReplayPage : 1), "", finishGettingLoadChallengeData); ShowDialog("Getting challenges..."); Main.ShowHourglass(); m_fader.visible = true; curAction = -1; } } public function LoadReplayNow(replayID:String):void { Database.LoadReplayByID(replayID, finishLoadingReplay); ShowDialog("Loading Replay..."); m_fader.visible = true; } public function LoadRobotNow(robotID:String):void { Database.LoadRobotByID(robotID, finishLoading); ShowDialog("Loading Robot..."); m_fader.visible = true; } public function LoadChallengeNow(challengeID:String):void { Database.LoadChallengeByID(challengeID, finishLoadingChallenge); ShowDialog("Loading Challenge..."); m_fader.visible = true; } public function highScoresButton(e:MouseEvent):void { if (selectingCondition) return; if (Main.inIFrame) { m_fader.visible = true; ShowConfirmDialog("Redirect to incredibots2.com?", 7); } else { if (curChallengeID == "") { Database.GetChallengeData(ControllerGame.userName, ControllerGame.password, true, Database.curSortType, Database.curSortPeriod, Database.curChallengePage, "", finishGettingLoadChallengeForScoreData); ShowDialog("Getting challenges..."); } else { Database.GetScoreData(userName, password, curChallengeID, Database.highScoresDaily, Database.highScoresPersonal, Database.highScoresSortType, Database.curScorePage, "", finishGettingScoreData); ShowDialog("Getting high scores..."); } Main.ShowHourglass(); m_fader.visible = true; curAction = -1; } } public virtual function submitButton(e:MouseEvent):void { if (Main.inIFrame) { m_fader.visible = true; ShowConfirmDialog("Redirect to incredibots2.com?", 7); } else { if (!curRobotEditable) return; if (userName != "_Public") { AddSyncPoint(); if (viewingUnsavedReplay) Database.SaveReplay(userName, password, replay, "_ScoreReplay", "This replay is saved for a score", curRobotID, new Robot(allParts, ControllerSandbox.settings), (ChallengeOver() ? GetScore() : -1), curChallengeID, 1, finishSavingReplay); else Database.SaveReplay(userName, password, new Replay(cameraMovements, syncPoints, keyPresses, frameCounter, Database.VERSION_STRING_FOR_REPLAYS), "_ScoreReplay", "This replay is saved for a score", curRobotID, new Robot(allParts, ControllerSandbox.settings), (ChallengeOver() ? GetScore() : -1), curChallengeID, 1, finishSavingReplay); m_scoreWindow.ShowFader(); ShowDialog("Submitting score..."); clickedSubmitScore = true; } else { clickedSubmitScore = true; loginButton(e, true, false); } } } public override function finishAddingUser(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_ADD_USER) return; var retVal:String = Database.FinishAddingUser(e); if (retVal != "") { m_progressDialog.SetMessage("Success!"); m_progressDialog.HideInXSeconds(1); if (m_loginWindow) m_loginWindow.visible = false; m_newUserWindow.visible = false; if (!m_scoreWindow || !m_scoreWindow.visible) m_fader.visible = false; Main.premiumMode = false; userName = retVal.substring(retVal.indexOf("user: ") + 6, retVal.indexOf("password: ") - 1); password = retVal.substring(retVal.indexOf("password: ") + 10, retVal.indexOf("session: ") - 1); sessionID = retVal.substr(retVal.indexOf("session: ") + 9); m_guiPanel.ShowLogout(); loginHidden(e, true); } } public override function finishLoggingIn(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_LOGIN) return; var retVal:String = Database.FinishLoggingIn(e); if (retVal != "") { m_progressDialog.SetMessage("Success!"); m_progressDialog.HideInXSeconds(1); m_loginWindow.visible = false; if (!m_scoreWindow || !m_scoreWindow.visible) m_fader.visible = false; if (retVal.indexOf("premium") == 0) Main.premiumMode = true; else Main.premiumMode = false; userName = retVal.substring(retVal.indexOf("user: ") + 6, retVal.indexOf("password: ") - 1); password = retVal.substring(retVal.indexOf("password: ") + 10, retVal.indexOf("session: ") - 1); sessionID = retVal.substr(retVal.indexOf("session: ") + 9); //m_guiPanel.ShowFeatureButton(); m_guiPanel.ShowLogout(); loginHidden(e, true); } Main.ShowMouse(); } public function finishSavingReplay(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_SAVE_REPLAY) return; var robotID:String = Database.FinishSavingReplay(e); if (robotID != "") { curRobotID = robotID; ratedCurRobot = true; curRobotPublic = false; m_progressDialog.SetMessage("Save successful!"); m_progressDialog.HideInXSeconds(1); if (m_chooserWindow) { m_chooserWindow.visible = false; removeChild(m_chooserWindow); m_chooserWindow = null; } if (!m_scoreWindow || !m_scoreWindow.visible) m_fader.visible = false; else { if (clickedSubmitScore) { clickedSubmitScore = false; m_progressDialog.visible = false; highScoresButton(new MouseEvent("")); } else { m_scoreWindow.HideFader(); Main.ShowMouse(); } } } } public function finishGettingSaveReplayData(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_GET_REPLAY_DATA) return; if (Database.FinishGettingReplayData(e)) { m_progressDialog.visible = false; if (m_chooserWindow) removeChild(m_chooserWindow); m_chooserWindow = new SaveLoadWindow(this, SaveLoadWindow.SAVE_REPLAY_TYPE); addChild(m_chooserWindow); m_fader.visible = true; } } public override function finishGettingLoadReplayData(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_GET_REPLAY_DATA) return; if (Database.FinishGettingReplayData(e)) { m_progressDialog.visible = false; if (m_chooserWindow) removeChild(m_chooserWindow); m_chooserWindow = new SaveLoadWindow(this, SaveLoadWindow.LOAD_REPLAY_TYPE); addChild(m_chooserWindow); m_fader.visible = true; } } public override function finishLoadingReplay(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_LOAD_REPLAY) return; var replayAndRobot:Array = Database.FinishLoadingReplay(e); processLoadedReplay(replayAndRobot); } public override function processLoadedReplay(replayAndRobot:Array):void { if (replayAndRobot) { replay = replayAndRobot[0]; if (replay.version != Database.VERSION_STRING_FOR_REPLAYS) { if (replayDirectlyLinked) { if (Main.inIFrame) Main.BrowserRedirect("http://incredibots.com/old/" + replay.version + "/incredibots.php?replayID=" + potentialReplayID); else Main.BrowserRedirect("http://incredibots.com/old/" + replay.version + "/?replayID=" + potentialReplayID); } else { ShowConfirmDialog("This replay was saved using an older version of IncrediBots. Redirect there now?", 6); Main.ShowMouse(); } } else { var robot:Robot = replayAndRobot[1]; replayParts = robot.allParts; ControllerSandbox.settings = robot.settings; playingReplay = true; viewingUnsavedReplay = false; Main.changeControllers = true; Main.nextControllerType = 0; curRobotID = potentialRobotID; ratedCurReplay = true; curReplayID = potentialReplayID; ratedCurReplay = false; curReplayPublic = potentialReplayPublic; curReplayFeatured = potentialReplayFeatured; curChallengeID = ""; curChallengePublic = false; curChallengeFeatured = false; } } } public override function finishDeletingReplay(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_DELETE_REPLAY) return; if (Database.FinishDeletingReplay(e)) { m_progressDialog.SetMessage("Delete successful!"); m_progressDialog.HideInXSeconds(1); var type:int = m_chooserWindow.dataType; removeChild(m_chooserWindow); m_chooserWindow = new SaveLoadWindow(this, type); addChild(m_chooserWindow); removeChild(m_progressDialog); addChild(m_progressDialog); } } public function finishSavingChallenge(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_SAVE_CHALLENGE) return; var challengeID:String = Database.FinishSavingChallenge(e); if (challengeID != "") { curChallengeID = challengeID; ratedCurChallenge = true; curChallengePublic = false; curChallengeFeatured = false; m_progressDialog.SetMessage("Save successful!"); m_progressDialog.HideInXSeconds(1); if (m_chooserWindow) { m_chooserWindow.visible = false; removeChild(m_chooserWindow); m_chooserWindow = null; } if (!m_scoreWindow || !m_scoreWindow.visible) m_fader.visible = false; else { m_scoreWindow.HideFader(); Main.ShowMouse(); } } } public override function finishLoadingChallenge(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_LOAD_CHALLENGE) return; var challenge:Challenge = Database.FinishLoadingChallenge(e); processLoadedChallenge(challenge); } public override function processLoadedChallenge(challenge:Challenge):void { if (challenge) { Main.changeControllers = true; Main.nextControllerType = 1; playingReplay = false; ControllerChallenge.challenge = challenge; ControllerChallenge.playChallengeMode = !potentialChallengeEditable; ControllerChallenge.playOnlyMode = !potentialChallengeEditable; ControllerSandbox.settings = challenge.settings; curChallengeID = potentialChallengeID; ratedCurChallenge = false; curChallengePublic = potentialChallengePublic; curChallengeFeatured = potentialChallengeFeatured; curRobotID = ""; curReplayID = ""; loadedParts = challenge.allParts; initX = challenge.cameraX; initY = challenge.cameraY; initZoom = challenge.zoomLevel; } } public function finishGettingSaveChallengeData(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_GET_CHALLENGE_DATA) return; if (Database.FinishGettingChallengeData(e)) { m_progressDialog.visible = false; if (m_chooserWindow) removeChild(m_chooserWindow); m_chooserWindow = new SaveLoadWindow(this, SaveLoadWindow.SAVE_CHALLENGE_TYPE); addChild(m_chooserWindow); m_fader.visible = true; } } public override function finishGettingLoadChallengeData(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_GET_CHALLENGE_DATA) return; if (Database.FinishGettingChallengeData(e)) { m_progressDialog.visible = false; if (m_chooserWindow) removeChild(m_chooserWindow); m_chooserWindow = new SaveLoadWindow(this, SaveLoadWindow.LOAD_CHALLENGE_TYPE); addChild(m_chooserWindow); m_fader.visible = true; } } public override function finishGettingLoadChallengeForScoreData(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_GET_CHALLENGE_DATA) return; if (Database.FinishGettingChallengeData(e)) { m_progressDialog.visible = false; if (m_challengeWindow) removeChild(m_challengeWindow); m_challengeWindow = new ChooseChallengeWindow(this); addChild(m_challengeWindow); m_fader.visible = true; } } public override function finishDeletingChallenge(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_DELETE_CHALLENGE) return; if (Database.FinishDeletingChallenge(e)) { m_progressDialog.SetMessage("Delete successful!"); m_progressDialog.HideInXSeconds(1); var type:int = m_chooserWindow.dataType; removeChild(m_chooserWindow); m_chooserWindow = new SaveLoadWindow(this, type); addChild(m_chooserWindow); removeChild(m_progressDialog); addChild(m_progressDialog); } } public override function finishGettingScoreData(e:Event):void { if (!Database.waitingForResponse || Database.curTransactionType != Database.ACTION_GET_SCORE_DATA) return; if (Database.FinishGettingScoreData(e)) { m_progressDialog.visible = false; if (m_chooserWindow) removeChild(m_chooserWindow); m_chooserWindow = new SaveLoadWindow(this, SaveLoadWindow.HIGH_SCORE_TYPE); addChild(m_chooserWindow); m_fader.visible = true; } } public function ConfirmSaveRobot(e:MouseEvent):void { m_chooserWindow.saveRobotButtonPressed(e, true); } public function ConfirmSaveReplay(e:MouseEvent):void { m_chooserWindow.saveReplayButtonPressed(e, true); } public function ConfirmSaveChallenge(e:MouseEvent):void { m_chooserWindow.saveChallengeButtonPressed(e, true); } public override function ConfirmDeleteRobot(e:MouseEvent):void { m_chooserWindow.deleteRobotButtonPressed(e, true); } public override function ConfirmDeleteReplay(e:MouseEvent):void { m_chooserWindow.deleteReplayButtonPressed(e, true); } public override function ConfirmDeleteChallenge(e:MouseEvent):void { m_chooserWindow.deleteChallengeButtonPressed(e, true); } public override function ShowImportWindow(type:int):void { if (m_importDialog) removeChild(m_importDialog); m_importDialog = new ImportWindow(this, type); m_fader.visible = true; addChild(m_importDialog); } public override function ShowConfirmDialog(msg:String, type:int):void { if (m_progressDialog) removeChild(m_progressDialog); m_progressDialog = new DialogWindow(this, msg, true, false, (type == 8)); addChild(m_progressDialog); m_progressDialog.ShowOKAndCancelButton(type); } public function ShowDisabledDialog():void { m_fader.visible = true; if (m_progressDialog) removeChild(m_progressDialog); m_progressDialog = new DialogWindow(this, "That feature has been disabled for this level.", true); m_progressDialog.ShowOKButton(); m_progressDialog.StopTimer(); addChild(m_progressDialog); } public override function ShowDialog(msg:String):void { if (m_progressDialog) removeChild(m_progressDialog); m_progressDialog = new DialogWindow(this, msg); addChild(m_progressDialog); } public override function ShowDialog2(msg:String):void { if (m_progressDialog) removeChild(m_progressDialog); m_progressDialog = new DialogWindow(this, msg, true, true); addChild(m_progressDialog); } public override function ShowDialog3(msg:String):void { if (m_progressDialog) removeChild(m_progressDialog); m_progressDialog = new DialogWindow(this, msg, true); addChild(m_progressDialog); } public function ShowTutorialWindow(phraseNum:int, x:int, y:int, moreButton:Boolean = false):void { if (m_tutorialDialog) removeChild(m_tutorialDialog); m_tutorialDialog = new TutorialWindow(this, x, y, phraseNum, moreButton); addChild(m_tutorialDialog); } public virtual function CloseTutorialDialog(phraseNum:int):void { m_tutorialDialog.visible = false; } public override function ShowLinkDialog(msg1:String, msg2:String, isEmbedReplay:Boolean = false, id:String = "", isEmbedChallenge:Boolean = false):void { if (m_linkDialog) removeChild(m_linkDialog); m_linkDialog = new LinkWindow(this, msg1, msg2, isEmbedReplay, id, isEmbedChallenge); addChild(m_linkDialog); } public override function DialogOK(e:Event):void { m_progressDialog.visible = false; if (m_chooserWindow && m_chooserWindow.visible) m_chooserWindow.HideFader(); if (m_challengeWindow && m_challengeWindow.visible) m_challengeWindow.HideFader(); if (m_newUserWindow && m_newUserWindow.visible) m_newUserWindow.HideFader(); if (m_loginWindow && m_loginWindow.visible) m_loginWindow.HideFader(); if (m_scoreWindow && m_scoreWindow.visible) m_scoreWindow.HideFader(); if (m_restrictionsDialog && m_restrictionsDialog.visible) m_restrictionsDialog.HideFader(); if (m_conditionsDialog && m_conditionsDialog.visible) m_conditionsDialog.HideFader(); } public virtual override function HideDialog(e:Event):void { if (Database.nonfatalErrorOccurred) { Database.nonfatalErrorOccurred = false; if (m_chooserWindow) m_chooserWindow.HideFader(); if (m_challengeWindow) m_challengeWindow.HideFader(); if (m_newUserWindow && m_newUserWindow.visible) m_newUserWindow.HideFader(); else if (m_loginWindow) m_loginWindow.HideFader(); } else { m_fader.visible = false; if (m_chooserWindow && m_chooserWindow.visible) { m_fader.visible = true; m_chooserWindow.HideFader(); } if (m_challengeWindow && m_challengeWindow.visible) { m_fader.visible = true; m_challengeWindow.HideFader(); } if (m_newUserWindow && m_newUserWindow.visible) m_newUserWindow.visible = false; else if (m_loginWindow && m_loginWindow.visible) m_loginWindow.visible = false; else if (m_scoreWindow && m_scoreWindow.visible) { m_fader.visible = true; m_scoreWindow.HideFader(); } else if (m_postReplayWindow && m_postReplayWindow.visible) { m_fader.visible = true; m_postReplayWindow.HideFader(); } } m_progressDialog.visible = false; if (failedChallenge) resetButton(new MouseEvent("")); failedChallenge = false; } public override function HideLinkDialog(e:Event):void { m_linkDialog.visible = false; if (m_chooserWindow && m_chooserWindow.visible) { m_chooserWindow.HideFader(); } else { m_fader.visible = false; } } public override function HideExportDialog(e:Event):void { m_exportDialog.visible = false; if (m_chooserWindow && m_chooserWindow.visible) { m_chooserWindow.HideFader(); } m_fader.visible = false; } public override function HideImportDialog(e:Event):void { m_importDialog.visible = false; m_fader.visible = false; } public override function HideConfirmDialog(e:Event):void { m_progressDialog.visible = false; if (m_chooserWindow && m_chooserWindow.visible) m_chooserWindow.HideFader(); else if (m_scoreWindow && m_scoreWindow.visible) m_scoreWindow.HideFader(); else m_fader.visible = false; } public function ShowPostReplayWindow():void { if (m_postReplayWindow) removeChild(m_postReplayWindow); m_postReplayWindow = new PostReplayWindow(this); addChild(m_postReplayWindow); m_fader.visible = true; } public function DeletePart(part:Part, addAction:Boolean = true, clearFromSelected:Boolean = true):void { allParts = Util.RemoveFromArray(part, allParts); if (clearFromSelected) selectedParts = Util.RemoveFromArray(part, selectedParts); part.isEnabled = false; var affectedJoints:Array = new Array(); if (part is ShapePart) { var jointFound:Boolean; do { jointFound = false; for (var i:int = 0; i < allParts.length; i++) { if (jointFound) { if (i != allParts.length - 1) { allParts[i] = allParts[i + 1]; } } else if (allParts[i] is JointPart) { var p:JointPart = (allParts[i] as JointPart); if (p.part1 == part || p.part2 == part) { jointFound = true; affectedJoints.push(p); p.isEnabled = false; if (clearFromSelected) selectedParts = Util.RemoveFromArray(p, selectedParts); if (i != allParts.length - 1) allParts[i] = allParts[i + 1]; } } else if (allParts[i] is Thrusters) { var t:Thrusters = (allParts[i] as Thrusters); if (t.shape == part) { jointFound = true; affectedJoints.push(t); t.isEnabled = false; if (clearFromSelected) selectedParts = Util.RemoveFromArray(t, selectedParts); if (i != allParts.length - 1) allParts[i] = allParts[i + 1]; } } } if (jointFound) allParts.pop(); } while (jointFound); } else if (part is TextPart) { (part as TextPart).m_textField.visible = false; } if (addAction) AddAction(new DeleteAction(part, affectedJoints)); CheckIfPartsFit(); curRobotID = ""; } // Private Part: private function CreateWorld():void { var worldAABB:b2AABB = new b2AABB(); worldAABB.lowerBound.Set(-300.0, -200.0); worldAABB.upperBound.Set(300.0, 200.0); // Construct a world object m_world = new b2World(worldAABB, GetGravity(), true); var filter:ContactFilter = new ContactFilter(); m_world.SetContactFilter(filter); var listener:ContactListener = new ContactListener(this); m_world.SetContactListener(listener); } protected virtual function GetGravity():b2Vec2 { return new b2Vec2(0.0, 15.0); } private function TooManyShapes():Boolean { return (allParts.filter(PartIsPhysical).length > Number.POSITIVE_INFINITY); } protected function IsPartOfRobot(p:Part, index:int, array:Array):Boolean { return p.drawAnyway; } protected function PartIsEditable(p:Part, index:int, array:Array):Boolean { return p.isEditable; } private function PartIsShape(p:Part, index:int, array:Array):Boolean { return (p is ShapePart); } private function PartIsPhysical(p:Part, index:int, array:Array):Boolean { return (p is ShapePart || p is PrismaticJoint); } protected function FindCenterOfRobot():ShapePart { var heaviestGroup:Array = null; var massOfHeaviestGroup:Number = 0; for (var i:int = 0; i < allParts.length; i++) { if (allParts[i].isEditable && allParts[i] is ShapePart && allParts[i].isEnabled && allParts[i].m_collisionGroup == -(i + 1)) { var attachedParts:Array = allParts[i].GetAttachedParts().filter(PartIsShape); var groupMass:Number = 0; var bodiesUsed:Array = new Array(); var partsUsed:Array = new Array(); for (var j:int = 0; j < attachedParts.length; j++) { if (!Util.ObjectInArray(attachedParts[j].GetBody(), bodiesUsed)) { groupMass += attachedParts[j].GetMass(); bodiesUsed.push(attachedParts[j].GetBody()); partsUsed.push(attachedParts[j]); } } if (groupMass > massOfHeaviestGroup) { massOfHeaviestGroup = groupMass; heaviestGroup = partsUsed; } } } if (!heaviestGroup) return null; var bestIndex:int = -1; var bestMass:Number = 0; for (i = 0; i < heaviestGroup.length; i++) { var mass:Number = heaviestGroup[i].GetMass(); if (mass > bestMass) { bestMass = mass; bestIndex = i; } } if (bestIndex == -1) return null; return heaviestGroup[bestIndex]; } private function Zoom(zoomIn:Boolean):void { var oldScale:Number = m_physScale; var centerX:Number = (ZOOM_FOCUS_X + draw.m_drawXOff) / m_physScale; var centerY:Number = (ZOOM_FOCUS_Y + draw.m_drawYOff) / m_physScale; if (zoomIn) { m_physScale *= 4.0 / 3.0; if (m_physScale > MAX_ZOOM_VAL) m_physScale = MAX_ZOOM_VAL; } else { m_physScale *= 3.0 / 4.0; if (m_physScale < MIN_ZOOM_VAL) m_physScale = MIN_ZOOM_VAL; } draw.m_drawXOff = centerX * m_physScale - ZOOM_FOCUS_X; draw.m_drawYOff = centerY * m_physScale - ZOOM_FOCUS_Y; if (oldScale != m_physScale) hasZoomed = true; if (simStarted) cameraMovements.push(new CameraMovement(frameCounter, (autoPanning ? Number.POSITIVE_INFINITY : draw.m_drawXOff), (autoPanning ? Number.POSITIVE_INFINITY : draw.m_drawYOff), m_physScale)); } private function MaybeCreateJoint():void { var candidateParts:Array = new Array(); var jointX:Number = mouseXWorldPhys; var jointY:Number = mouseYWorldPhys; var snapPart:ShapePart = FindPartToSnapTo(); if (snapToCenter && snapPart) { jointX = snapPart.centerX; jointY = snapPart.centerY; } for (var i:int = allParts.length - 1; i >= 0; i--) { if (allParts[i] is ShapePart && allParts[i].isEditable && allParts[i].isEnabled) { var part:ShapePart = ShapePart(allParts[i]); if (part.InsideShape(jointX, jointY, m_physScale)) { candidateParts.push(part); } } } if (candidateParts.length == 2) { if (curAction == NEW_REVOLUTE_JOINT) { var rjoint:RevoluteJoint = new RevoluteJoint(candidateParts[0], candidateParts[1], jointX, jointY); if (copiedJoint is RevoluteJoint) rjoint.SetJointProperties(copiedJoint as RevoluteJoint); allParts.push(rjoint); AddAction(new CreateAction(rjoint)); m_sidePanel.ShowJointPanel(rjoint); selectedParts = new Array(); selectedParts.push(rjoint); curAction = -1; if (centerOnSelected) CenterOnSelected(); PlayJointSound(); } else if (curAction == NEW_FIXED_JOINT) { var fjoint:JointPart = new FixedJoint(candidateParts[0], candidateParts[1], jointX, jointY); allParts.push(fjoint); AddAction(new CreateAction(fjoint)); m_sidePanel.ShowJointPanel(fjoint); selectedParts = new Array(); selectedParts.push(fjoint); curAction = -1; if (centerOnSelected) CenterOnSelected(); PlayJointSound(); } curRobotID = ""; redrawRobot = true; } else if (candidateParts.length > 2) { potentialJointPart1 = candidateParts[0]; potentialJointPart2 = candidateParts[1]; potentialJointPart1.highlightForJoint = true; potentialJointPart2.highlightForJoint = true; candidateJointX = jointX; candidateJointY = jointY; candidateJointType = curAction; candidateJointParts = candidateParts; curAction = FINALIZING_JOINT; } else { curAction = -1; redrawRobot = true; } } private function MaybeCreateThrusters():void { var candidateParts:Array = new Array(); var jointX:Number = mouseXWorldPhys; var jointY:Number = mouseYWorldPhys; var snapPart:ShapePart = FindPartToSnapTo(); if (snapToCenter && snapPart) { jointX = snapPart.centerX; jointY = snapPart.centerY; } for (var i:int = allParts.length - 1; i >= 0; i--) { if (allParts[i] is ShapePart && allParts[i].isEditable && allParts[i].isEnabled) { var part:ShapePart = ShapePart(allParts[i]); if (part.InsideShape(jointX, jointY, m_physScale)) { candidateParts.push(part); } } } if (candidateParts.length == 1) { var t:Thrusters = new Thrusters(candidateParts[0], jointX, jointY); if (copiedThrusters) { t.strength = copiedThrusters.strength; t.angle = copiedThrusters.angle; t.thrustKey = copiedThrusters.thrustKey; t.autoOn = copiedThrusters.autoOn; } allParts.push(t); AddAction(new CreateAction(t)); m_sidePanel.ShowThrustersPanel(t); selectedParts = new Array(); selectedParts.push(t); curAction = -1; if (centerOnSelected) CenterOnSelected(); curRobotID = ""; redrawRobot = true; PlayJointSound(); } else if (candidateParts.length > 1) { potentialJointPart1 = candidateParts[0]; potentialJointPart1.highlightForJoint = true; candidateJointX = jointX; candidateJointY = jointY; candidateJointType = curAction; candidateJointParts = candidateParts; curAction = FINALIZING_JOINT; } else { curAction = -1; redrawRobot = true; } } private function MaybeStartCreatingPrismaticJoint():void { var candidateParts:Array = new Array(); var jointX:Number = mouseXWorldPhys; var jointY:Number = mouseYWorldPhys; var snapPart:ShapePart = FindPartToSnapTo(); if (snapToCenter && snapPart) { jointX = snapPart.centerX; jointY = snapPart.centerY; } for (var i:int = allParts.length - 1; i >= 0; i--) { if (allParts[i] is ShapePart && allParts[i].isEditable && allParts[i].isEnabled) { var part:ShapePart = ShapePart(allParts[i]); if (part.InsideShape(jointX, jointY, m_physScale)) { candidateParts.push(part); } } } if (candidateParts.length == 0) { curAction = -1; redrawRobot = true; } else if (candidateParts.length == 1) { jointPart = candidateParts[0]; firstClickX = jointX; firstClickY = jointY; actionStep++; PlayJointSound(); } else { potentialJointPart1 = candidateParts[0]; potentialJointPart1.highlightForJoint = true; candidateJointX = jointX; candidateJointY = jointY; candidateJointType = curAction; candidateJointParts = candidateParts; curAction = FINALIZING_JOINT; } } private function MaybeFinishCreatingPrismaticJoint():void { var candidateParts:Array = new Array(); var jointX:Number = mouseXWorldPhys; var jointY:Number = mouseYWorldPhys; var snapPart:ShapePart = FindPartToSnapTo(); if (snapToCenter && snapPart) { jointX = snapPart.centerX; jointY = snapPart.centerY; } for (var i:int = allParts.length - 1; i >= 0; i--) { if (allParts[i] is ShapePart && allParts[i].isEditable && allParts[i] != jointPart) { var part:ShapePart = ShapePart(allParts[i]); if (part.InsideShape(jointX, jointY, m_physScale)) { candidateParts.push(part); } } } if (candidateParts.length == 1) { var pjoint:PrismaticJoint = new PrismaticJoint(jointPart, candidateParts[0], firstClickX, firstClickY, jointX, jointY); if (copiedJoint is PrismaticJoint) pjoint.SetJointProperties(copiedJoint as PrismaticJoint); allParts.push(pjoint); AddAction(new CreateAction(pjoint)); m_sidePanel.ShowJointPanel(pjoint); selectedParts = new Array(); selectedParts.push(pjoint); curAction = -1; jointPart.highlightForJoint = false; curRobotID = ""; if (centerOnSelected) CenterOnSelected(); redrawRobot = true; PlayJointSound(); } else if (candidateParts.length > 1) { potentialJointPart1 = candidateParts[0]; potentialJointPart1.highlightForJoint = true; candidateJointX = jointX; candidateJointY = jointY; candidateJointType = curAction; candidateJointParts = candidateParts; curAction = FINALIZING_JOINT; } else if (candidateParts.length == 0) { curAction = -1; redrawRobot = true; } } private function FindPartToSnapTo(draggingPart:ShapePart = null):ShapePart { var closestPart:ShapePart = null; var closestDist:Number = Number.MAX_VALUE; for (var i:int = 0; i < allParts.length; i++) { if (allParts[i] is ShapePart && allParts[i] != draggingPart && allParts[i].isEditable) { var part:ShapePart = (allParts[i] as ShapePart); var dist:Number = Util.GetDist(mouseXWorldPhys, mouseYWorldPhys, part.centerX, part.centerY); if (dist < closestDist) { closestDist = dist; closestPart = part; } } } var DIST_THRESHHOLD:Number = 12.0 / m_physScale; if (closestDist < DIST_THRESHHOLD) return closestPart; return null; } private function GetBodyAtMouse():b2Body { // Make a small box. var mousePVec:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys); var aabb:b2AABB = new b2AABB(); aabb.lowerBound.Set(mouseXWorldPhys - 0.001, mouseYWorldPhys - 0.001); aabb.upperBound.Set(mouseXWorldPhys + 0.001, mouseYWorldPhys + 0.001); // Query the world for overlapping shapes. var k_maxCount:int = 10; var shapes:Array = new Array(); var count:int = m_world.Query(aabb, shapes, k_maxCount); var body:b2Body = null; for (var i:int = 0; i < count; ++i) { if (shapes[i].m_body.IsStatic() == false && !shapes[i].GetUserData().undragable && shapes[i].GetUserData().isPiston == -1) { var tShape:b2Shape = shapes[i] as b2Shape; var inside:Boolean = tShape.TestPoint(tShape.m_body.GetXForm(), mousePVec); if (inside) { body = tShape.m_body; break; } } } return body; } private function MouseOverSelectedPart():Boolean { for (var i:int = 0; i < selectedParts.length; i++) { if (selectedParts[i].InsideShape(mouseXWorldPhys, mouseYWorldPhys, m_physScale)) return true; } return false; } private function GetPartAtMouse():Part { for (var j:int = 0; j < allParts.length; j++) { if (allParts[j].isEditable && allParts[j] is TextPart && allParts[j].InsideMoveBox(mouseXWorldPhys, mouseYWorldPhys, m_physScale)) return allParts[j]; } var candidateParts:Array = new Array(); var firstSelectedPart:int = -1; var allPartsSelected:Boolean = true; var noPartsSelected:Boolean = true; for (var i:int = allParts.length - 1; i >= 0; i--) { if (allParts[i].isEditable && allParts[i].InsideShape(mouseXWorldPhys, mouseYWorldPhys, m_physScale)) { if (Util.ObjectInArray(allParts[i], selectedParts)) { noPartsSelected = false; if (firstSelectedPart == -1) firstSelectedPart = candidateParts.length; } else { allPartsSelected = false; } candidateParts.push(allParts[i]); } } if (candidateParts.length == 0) return null; if (candidateParts.length == 1 || allPartsSelected || noPartsSelected) return candidateParts[0]; for (i = (firstSelectedPart + 1) % candidateParts.length; i != firstSelectedPart; i = (i + 1) % candidateParts.length) { if (!Util.ObjectInArray(candidateParts[i], selectedParts)) return candidateParts[i]; } return null; } } }