/// <summary> /// Removes the clothing from the GUI. If it isn't in the GUI, searches the TailorStations in the Level and then the current Selection. /// </summary> public void RemoveClothingItem(ItemId clothingItemId) { // Check the GUI for the clothing bool foundItem = RemoveClothingItemFromGui(clothingItemId) != null; if (!foundItem) { // Check the level's tailor stations for the clothing FashionLevel level = GameFacade.Instance.RetrieveMediator <FashionLevel>(); foreach (TailorStation tailorStation in level.TailorStations) { if (tailorStation.CurrentClothing != null && tailorStation.CurrentClothing.ItemId == clothingItemId) { tailorStation.Clear(); foundItem = true; break; } } } if (!foundItem) { // Check the selection for the item foundItem = mInput.Selection.RemoveClothing(clothingItemId); } if (!foundItem) { throw new Exception("Cannot remove a clothing item (" + clothingItemId + ") that does not exist in the GUI, the Selection or in a Tailor Station."); } }
/// <summary> /// Receives messages from the server that report the assets of a single friend that was just hired by the user /// </summary> public void HiredFriend(Message message, FashionLevel level) { Jobs job = (Jobs)Enum.Parse(typeof(Jobs), message.Data[0].ToString()); // Parse the XML from the message and build the avatars it describes mActiveTasks.Add ( mScheduler.StartCoroutine ( BuildNpcs ( job, level, Functionals.Reduce <XmlDocument, List <XmlNode> > ( delegate(List <XmlNode> accumulator, XmlDocument docItem) { foreach (XmlNode node in docItem.SelectNodes("//Avatar")) { accumulator.Add(node); } return(accumulator); }, MessageUtil.GetXmlDocumentsFromMessage(message) ), level.Gui.HiredFriendLoaded ) ) ); }
public LevelGui(XmlDocument levelXml, FashionLevel level) { if (levelXml == null) { throw new ArgumentNullException("levelXml"); } mLevelXml = levelXml; if (level == null) { throw new ArgumentNullException("level"); } mLevel = level; ClientAssetRepository assetRepo = GameFacade.Instance.RetrieveProxy <ClientAssetRepository>(); assetRepo.LoadAssetFromPath <SoundAsset>(LEVEL_COMPLETE_SFX_PATH, delegate(SoundAsset asset) { mLevelCompleteSfx = asset.AudioClip; }); assetRepo.LoadAssetFromPath <SoundAsset>(LEVEL_UP_SFX_PATH, delegate(SoundAsset asset) { mLevelUpSfx = asset.AudioClip; }); }
public LevelGameplay(XmlDocument levelXml, FashionLevel level, FashionNpcMediator modelFactory) { if (levelXml == null) { throw new ArgumentNullException("levelXml"); } mLevelXml = levelXml; if (level == null) { throw new ArgumentNullException("level"); } mLevel = level; mScheduler = GameFacade.Instance.RetrieveMediator <SchedulerMediator>().Scheduler; XmlNode timeBetweenWaves = mLevelXml.SelectSingleNode("Level/Waves/@timeBetweenWaves"); if (timeBetweenWaves == null) { throw new Exception("Unable to load level (" + mLevel.Name + "), no Level/Waves/@timeBetweenWaves node found."); } mTimeBetweenWaves = float.Parse(timeBetweenWaves.InnerText); XmlNode perfectLevelBonusNode = mLevelXml.SelectSingleNode("Level/PerfectLevelBonus/@value"); if (perfectLevelBonusNode != null) { mPerfectLevelBonus = uint.Parse(perfectLevelBonusNode.InnerText); } else { mPerfectLevelBonus = 0; } XmlNode closeSaveDistanceNode = mLevelXml.SelectSingleNode("Level/CloseSaveDistance/@value"); if (closeSaveDistanceNode == null) { throw new Exception("Cannot load level (" + mLevel.Name + "), no Level/@path attribute found."); } mCloseSaveDistance = float.Parse(closeSaveDistanceNode.InnerText); if (modelFactory == null) { throw new ArgumentNullException("modelFactory"); } mModelFactory = modelFactory; mLevel.Gui.BuildTopGui(delegate() { if (Time.time - mNextWaveTime > mAvoidDuplicateWavesThreshold) { mNextWaveButtonPressed = true; EventLogger.Log(LogGlobals.CATEGORY_FASHION_MINIGAME, LogGlobals.GAMEPLAY_BEHAVIOR, "NextWaveButtonPress", mLevel.Name); } }); }
public void BuildNpcsForLevel(FashionLevel level) { mAvatarsDownloading = true; FashionGameCommands.GetAllHiredAvatars(delegate(Message message) { GetHiredNpcs(message, level, delegate() { mAvatarsDownloading = false; }); }); }
public FashionModel GetModel(FashionLevel level, FashionModelNeeds needs, string type) { FashionModelInfo modelTypeInfo = mFashionModelTypes[type]; FashionModel resultModel = mFashionModels.GetNpc(); resultModel.SetActive(needs, level); resultModel.WalkSpeed = modelTypeInfo.Speed; resultModel.UnityGameObject.SetActiveRecursively(true); return(resultModel); }
private void LevelLoaded(FashionLevel level) { PlayLevelState playLevelState = new PlayLevelState(level, BeginLoadLevel); if (this.CurrentState is LoadLevelState) { this.CurrentState.AddTransition(playLevelState); this.TransitionToState(playLevelState); } else { throw new Exception("Cannot enter a PlayLevelState if the GameStateMachine is not in a completed LoadLevelState."); } }
public WalkToEndGoal(FashionModel model, FashionLevel level) { if (model == null) { throw new ArgumentNullException("model"); } mModel = model; if (level == null) { throw new ArgumentNullException("level"); } mLevel = level; }
public PlayLevelState(FashionLevel level, Hangout.Shared.Action onLevelComplete) { if (level == null) { throw new ArgumentNullException("level"); } mLevel = level; GameFacade.Instance.RegisterMediator(mLevel); mScheduler = GameFacade.Instance.RetrieveMediator <SchedulerMediator>().Scheduler; mOnLevelComplete = onLevelComplete; }
/// <summary> /// Does not count any of the GUIs made by models or stations that don't effect gameplay /// </summary> public bool MouseIsOverGui(FashionLevel level) { bool mouseOverImportantGui = false; foreach (ITopLevel topLevel in GameFacade.Instance.RetrieveMediator <RuntimeGuiManager>().OccludingTopLevels(mMousePosition)) { if (!IsModelOrStationTopLevel(topLevel, level)) { mouseOverImportantGui = true; break; } } return(mouseOverImportantGui); }
public bool HasModelsForLevel(FashionLevel level) { if (level.ModelsRequired > mFashionModels.Count) { return(false); } bool result = true; foreach (FashionGameStation station in level.Stations) { if (!(station is HoldingStation) && !HasWorkerForStation(station)) { result = false; break; } } return(result); }
private bool IsModelOrStationTopLevel(ITopLevel topLevel, FashionLevel level) { foreach (FashionGameStation station in level.Stations) { if (topLevel == station.MainGui) { return(true); } } foreach (FashionModel model in level.ActiveModels) { if (topLevel == model.DesiredClothingWindow || topLevel == model.Nametag) { return(true); } } return(false); }
private IEnumerator <IYieldInstruction> BuildLevel ( XmlDocument levelXml, LevelInfo levelInfo, bool firstTimePlayed, Action <FashionLevel> fashionLevelResult ) { //Console.WriteLine(Time.realtimeSinceStartup.ToString("f2") + "> Building Level"); // Start loading the clothing assets ClothingMediator clothingMediator = GameFacade.Instance.RetrieveMediator <ClothingMediator>(); clothingMediator.LoadClothing ( Functionals.Map <ItemId> ( delegate(object xmlNode) { return(new ItemId(XmlUtility.GetUintAttribute((XmlNode)xmlNode, "id"))); }, levelXml.SelectNodes("Level/Clothing/ClothingItem") ), levelInfo.LevelDataPath ); yield return(new YieldWhile(delegate() { return !clothingMediator.ClothingLoaded; })); FashionNpcMediator fashionModelFactory = GameFacade.Instance.RetrieveMediator <FashionNpcMediator>(); // Clear this value mLeveledThisLevel = false; // Make the first level that this player qualifies for FashionLevel result = new FashionLevel(levelInfo.LevelDataPath, fashionModelFactory, firstTimePlayed, levelInfo.Energy); fashionLevelResult(result); //Console.WriteLine(Time.realtimeSinceStartup.ToString("f2") + "> Build Level Completed"); }
public WalkToStationState(FashionModel model, ModelStation station, FashionLevel level) { if (model == null) { throw new ArgumentNullException("model"); } mModel = model; if (station == null) { throw new ArgumentNullException("station"); } mStation = station; if (level == null) { throw new ArgumentNullException("level"); } mLevel = level; }
private IEnumerator <IYieldInstruction> SetupLevel(FashionLevel level) { // Wait for the async parts of the level to complete yield return(new YieldWhile(delegate() { return !level.IsLoaded; })); // Load the models for this level FashionNpcMediator npcFactory = GameFacade.Instance.RetrieveMediator <FashionNpcMediator>(); npcFactory.BuildNpcsForLevel(level); // Yield if there are any new models to download yield return(new YieldWhile(delegate() { return npcFactory.Downloading; })); mOnLevelLoaded(level); }
/// <summary> /// Creates a new FashionModel Entity /// </summary> /// <param name="start">Pair of Vector3s, first = Position, second = Direction</param> /// <param name="walkSpeed">Constant speed that the fashion models walk at</param> public FashionModel(string name, FashionLevel level, GameObject displayObject, HeadController headController, BodyController bodyController) : base(name, displayObject, headController, bodyController) { if (level == null) { throw new ArgumentNullException("level"); } mLevel = level; mScheduler = GameFacade.Instance.RetrieveMediator <SchedulerMediator>().Scheduler; ClientAssetRepository assetRepo = GameFacade.Instance.RetrieveProxy <ClientAssetRepository>(); assetRepo.LoadAssetFromPath <SoundAsset>(APPLY_CLOTHING_SFX, delegate(SoundAsset asset) { mApplyClothingSfx = asset.AudioClip; }); assetRepo.LoadAssetFromPath <SoundAsset>(ERROR_SFX_PATH, delegate(SoundAsset asset) { mErrorSfx = asset.AudioClip; }); mNametag = SetupNametag(name, displayObject); }
private IEnumerator <IYieldInstruction> BuildNpcs ( Jobs job, FashionLevel level, IEnumerable <XmlNode> modelsXml, Hangout.Shared.Action onBuildingNpcsComplete ) { // Key = FBID, Value = name, assets for model Dictionary <long, Pair <string, IEnumerable <Asset> > > modelInfos = new Dictionary <long, Pair <string, IEnumerable <Asset> > >(); uint gettingAssets = 0; ClientAssetRepository repo = GameFacade.Instance.RetrieveProxy <ClientAssetRepository>(); foreach (XmlNode modelXml in modelsXml) { string name; XmlNode fbidNode = modelXml.SelectSingleNode(".//@FBID"); if (fbidNode == null) { throw new Exception("modelXml doesn't have an FBID attribute: " + modelXml.OuterXml); } long uniqueId = long.Parse(fbidNode.InnerText); name = modelXml.Attributes["FirstName"].InnerText; // +" " + modelXml.Attributes["LastName"].InnerText; // Only grab the avatars we don't already have loaded if (!JobHasNpc(job, uniqueId) && !modelInfos.ContainsKey(uniqueId)) { gettingAssets++; List <AssetInfo> assetInfos = new List <AssetInfo>(); foreach (AssetInfo assetInfo in ClientAssetInfo.Parse(modelXml)) { if (!mIgnoredAssets.Contains(assetInfo.AssetSubType)) { assetInfos.Add(assetInfo); } } repo.GetAssets <Asset>(assetInfos, delegate(IEnumerable <Asset> modelAssets) { gettingAssets--; if (!modelInfos.ContainsKey(uniqueId)) { modelInfos.Add(uniqueId, new Pair <string, IEnumerable <Asset> >(name, modelAssets)); } else { Console.WriteLine("Attempted to download model info for " + uniqueId + " twice at the same time."); } }); } } yield return(new YieldWhile(delegate() { return gettingAssets != 0; })); int spreadFrames = 25; List <Pair <long, INpc> > newNpcs = new List <Pair <long, INpc> >(); foreach (KeyValuePair <long, Pair <string, IEnumerable <Asset> > > assets in modelInfos) { // This object will be cleaned up by the fashion model GameObject displayObject = (GameObject)GameObject.Instantiate(mRigPrototype); displayObject.SetActiveRecursively(false); HeadController headController = new HeadController(GameObjectUtility.GetNamedChildRecursive("Head", displayObject)); BodyController bodyController = new BodyController(displayObject); bodyController.SetAssets(assets.Value.Second); headController.SetAssets(assets.Value.Second); bodyController.UpdateAssetsOverFrames(spreadFrames); headController.UpdateAssetsOverFrames(spreadFrames); INpc newNpc; if (job == Jobs.Model) { newNpc = new FashionModel(assets.Value.First, level, displayObject, headController, bodyController); } else { newNpc = new StationWorker(assets.Value.First, displayObject, headController, bodyController); } CharacterMediator.AddAnimationClipToRig(newNpc.DisplayObject, "Avatar/F_walk_normal_loop"); CharacterMediator.AddAnimationClipToRig(newNpc.DisplayObject, "Avatar/F_idle_normal_loop"); newNpcs.Add(new Pair <long, INpc>(assets.Key, newNpc)); } yield return(new YieldWhile(delegate() { return spreadFrames-- != 0 || !mModelAnimationsDownloaded; })); foreach (Pair <long, INpc> npc in newNpcs) { switch (job) { case Jobs.Hair: mHairStationWorkers.AddNpc(npc.First, npc.Second); break; case Jobs.Makeup: mMakeupStationWorkers.AddNpc(npc.First, npc.Second); break; case Jobs.Model: FashionModel newModel = (FashionModel)npc.Second; newModel.SetImpatientSitIdle(mImpatientSitIdle); newModel.SetSittingIdle(mSittingIdle); newModel.SetMediumHurried(mMediumHurried, mMediumHurriedSpeed); newModel.SetCatWalk(mCatWalk, mCatWalkSpeed); mFashionModels.AddNpc(npc.First, npc.Second); break; case Jobs.Seamstress: mSewingStationWorkers.AddNpc(npc.First, npc.Second); break; } } if (onBuildingNpcsComplete != null) { onBuildingNpcsComplete(); } }
private void GetHiredNpcs(Message message, FashionLevel level, Hangout.Shared.Action onComplete) { if (message == null) { throw new ArgumentNullException("message"); } // Expecting the XML for a single avatar in each item in message.Data Dictionary <Jobs, List <XmlNode> > avatarsPerJob = new Dictionary <Jobs, List <XmlNode> >(); foreach (XmlDocument doc in MessageUtil.GetXmlDocumentsFromMessage(message)) { XmlNode avatarNode = doc.SelectSingleNode("//Avatar"); if (avatarNode == null) { throw new Exception("Unable to find avatar node in messageData: " + doc.OuterXml); } XmlNode jobNode = avatarNode.SelectSingleNode("@job"); if (jobNode == null) { throw new Exception("Unable to find job attribute on XmlNode: " + avatarNode.OuterXml); } Jobs job = (Jobs)Enum.Parse(typeof(Jobs), jobNode.InnerText); List <XmlNode> avatarsList; if (!avatarsPerJob.TryGetValue(job, out avatarsList)) { avatarsList = new List <XmlNode>(); avatarsPerJob.Add(job, avatarsList); } avatarsList.Add(avatarNode); AccountId accountId; if (avatarNode.Attributes["AccountId"].InnerText != "") { accountId = new AccountId(XmlUtility.GetUintAttribute(avatarNode, "AccountId")); } else { accountId = new AccountId(0u); } long fbAccountId = XmlUtility.GetLongAttribute(avatarNode, "FBID"); string firstName = XmlUtility.GetStringAttribute(avatarNode, "FirstName"); string lastName = XmlUtility.GetStringAttribute(avatarNode, "LastName"); if (XmlUtility.XmlNodeHasAttribute(avatarNode, "ImageUrl")) { string imageUrl = XmlUtility.GetStringAttribute(avatarNode, "ImageUrl"); FacebookFriendInfo facebookFriendInfo = new FacebookFriendInfo(accountId, fbAccountId, firstName, lastName, imageUrl); mHiredFacebookFriendInfos.Add(facebookFriendInfo); } } foreach (KeyValuePair <Jobs, List <XmlNode> > avatarListing in avatarsPerJob) { mActiveTasks.Add ( mScheduler.StartCoroutine ( BuildNpcs ( avatarListing.Key, level, avatarListing.Value, onComplete ) ) ); } }
/// <summary> /// Starts a walk down the runway /// </summary> public void SetActive(FashionModelNeeds needs, FashionLevel level) { if (needs == null) { throw new ArgumentNullException("needs"); } mNeeds = needs; if (level == null) { throw new ArgumentNullException("level"); } mLevel = level; mNametag.MainGui.Showing = true; mDesiredClothing.Clear(); if (mDesiredClothingFrame != null) { mDesiredClothingFrame.ClearChildWidgets(); } mDesiredStations.Clear(); mStateMachine = new FashionModelStateMachine(this, mLevel); UnityGameObject.transform.position = mLevel.Start.First; mActiveWalkCycle = mCatWalk; mActiveWalkCycleSpeed = mCatWalkSpeed; mCompletionBonusTime = 5.0f; mReady = false; mHandleBonusTask = mScheduler.StartCoroutine(HandleBonus()); IGuiManager manager = GameFacade.Instance.RetrieveMediator <RuntimeGuiManager>(); mDesiredClothingFrame = new GuiFrame("MainFrame", new MainFrameSizePosition()); IGuiStyle windowStyle = new GuiStyle(manager.GetDefaultStyle(typeof(Window)), "ModelNeedsWindow"); windowStyle.Normal.Background = null; windowStyle.Hover.Background = null; // TODO: Hard coded values float windowHeight = 192.0f; mDesiredClothingWindow = new Window ( "ModelClothingPanel", new FixedSize(128.0f, windowHeight), manager, mDesiredClothingFrame, windowStyle ); // TODO: Hard coded values mFollowWorldSpaceObject = new FollowWorldSpaceObject ( GameFacade.Instance.RetrieveMediator <FashionCameraMediator>().Camera, this.DisplayObject.transform, GuiAnchor.CenterLeft, new Vector2(0.0f, windowHeight * 0.4f), new Vector3(0.125f, APPROX_AVATAR_HEIGHT * 1.3f, 0.25f) ); manager.SetTopLevelPosition ( mDesiredClothingWindow, mFollowWorldSpaceObject ); ClothingMediator clothingMediator = GameFacade.Instance.RetrieveMediator <ClothingMediator>(); // Setup Clothes GUI foreach (ItemId clothing in mNeeds.Clothing) { Image desiredClothingImage = new Image("DesiredClothingLabel", clothingMediator.GetThumbStyle(clothing), clothingMediator.GetThumbnail(clothing)); mDesiredClothing.Add(clothing, desiredClothingImage); mDesiredClothingFrame.AddChildWidget(desiredClothingImage, new HorizontalAutoLayout()); } // Setup Station GUI foreach (ModelStation station in mNeeds.Stations) { Image desiredStationImage = new Image("DesiredStationImage", station.Image); mDesiredStations.Add(station, desiredStationImage); mDesiredClothingFrame.AddChildWidget(desiredStationImage, new HorizontalAutoLayout()); mCompletionBonusTime += station.WaitTime + mWalkToStationTimeBonus; } this.DisplayObject.SetActiveRecursively(true); Shader fashionModelShader = Shader.Find("Avatar/Fashion Model"); if (fashionModelShader == null) { throw new Exception("Cannot find 'Avatar/Fashion Model' shader"); } mModelMaterials.Clear(); foreach (Component component in UnityGameObject.GetComponentsInChildren(typeof(Renderer))) { Renderer renderer = (Renderer)component; foreach (Material mat in renderer.materials) { mat.shader = fashionModelShader; mModelMaterials.Add(mat); } } mNeeds.AddOnCompleteAction(ModelComplete); }
private void MouseDown() { RaycastHit rh; Ray mouseThruScreenRay = GameFacade.Instance.RetrieveMediator <FashionCameraMediator>().Camera.ScreenPointToRay(mMousePosition); GameFacade.Instance.RetrieveMediator <FashionGameGui>().MouseDown(); if (!GameFacade.Instance.HasMediator <FashionLevel>()) { return; } bool clickHadEffect = false; FashionLevel level = GameFacade.Instance.RetrieveMediator <FashionLevel>(); if (!GameFacade.Instance.RetrieveMediator <FashionGameGui>().OccludesScreenPoint(mMousePosition)) { if (Physics.Raycast(mouseThruScreenRay, out rh, Mathf.Infinity, 1 << FashionMinigame.STATION_LAYER)) { FashionGameStation station = level.GetStationFromGameObject(rh.collider.gameObject); if (station is TailorStation) { TailorStation tailorStation = (TailorStation)station; if (tailorStation.HasReadyClothing) { mSelection.Select(tailorStation.RetrieveFixedClothing()); clickHadEffect = true; } } } if (Physics.Raycast(mouseThruScreenRay, out rh, Mathf.Infinity, 1 << FashionMinigame.CLOTHING_LAYER)) { Transform billboardHit = rh.collider.transform; foreach (TailorStation tailorStation in level.TailorStations) { if (tailorStation != null && tailorStation.CurrentClothing != null && tailorStation.CurrentClothing.UnityGameObject.transform == billboardHit) { mSelection.Select(tailorStation.RetrieveFixedClothing()); clickHadEffect = true; break; } } } if (mSelection.TopClothing == null) { if (Physics.Raycast(mouseThruScreenRay, out rh, Mathf.Infinity, 1 << FashionMinigame.STATION_LAYER)) { FashionGameStation station = level.GetStationFromGameObject(rh.collider.gameObject); if (station is ModelStation) { clickHadEffect = mSelection.Select((ModelStation)station); } } if (Physics.Raycast(mouseThruScreenRay, out rh, Mathf.Infinity, 1 << FashionMinigame.MODEL_LAYER)) { mSelection.ClearModel(); mSelection.Select(level.GetModelFromGameObject(rh.collider.gameObject)); FashionModel thisModel = mSelection.Model; mSelection.Model.AddOnTargetReachedAction(delegate() { // If the selection is still this model, unselect it if (mSelection.Model == thisModel) { mSelection.ClearModel(); } }); clickHadEffect = true; } } } else { clickHadEffect = DropClothing(mouseThruScreenRay); } if (!clickHadEffect && !MouseIsOverGui(level)) { EventLogger.LogNoMixPanel ( LogGlobals.CATEGORY_FASHION_MINIGAME, LogGlobals.GAMEPLAY_BEHAVIOR, LogGlobals.USELESS_CLICK, level.Name + " (" + mMousePosition.x.ToString("f0") + " " + mMousePosition.y.ToString("f0") + ")" ); } }
/// <summary> /// Constructs a FashionModelStateMachine for the given model. Model must have needs before creating the state machine (so that the proper states for each station can be created) /// </summary> public FashionModelStateMachine(FashionModel model, FashionLevel level) { if (model == null) { throw new ArgumentNullException("model"); } mModel = model; mInactiveState = new ModelInactiveState(model); mWalkToEndGoalState = new WalkToEndGoal(model, level); mInactiveState.AddTransition(mWalkToEndGoalState); mWalkToEndGoalState.AddTransition(mInactiveState); mWalkToCenterState = new WalkToCenterState(model, level); mWalkToCenterState.AddTransition(mInactiveState); List <ModelStation> possibleStations = new List <ModelStation>(model.RequiredStations); foreach (HoldingStation station in level.HoldingStations) { possibleStations.Add(station); } foreach (ModelStation station in possibleStations) { WalkToStationState walkToStation = new WalkToStationState(model, station, level); AtStationState atStation = new AtStationState(model, station); atStation.AddTransition(mWalkToCenterState); atStation.AddTransition(mInactiveState); // All the WalkToStation states can enter the corresponding AtStation state walkToStation.AddTransition(atStation); walkToStation.AddTransition(mInactiveState); mAtStationStates.Add(station, atStation); // If the model doesn't need to stay at this station, it could go back to walk to center walkToStation.AddTransition(mWalkToCenterState); mWalkToEndGoalState.AddTransition(walkToStation); // An avatar walking to center can be redirected to a station mWalkToCenterState.AddTransition(walkToStation); mWalkToStationStates.Add(station, walkToStation); } // Make it so that avatars can be interrupted from walking to // one station by sending them to another station they need foreach (WalkToStationState stateA in mWalkToStationStates.Values) { foreach (WalkToStationState stateB in mWalkToStationStates.Values) { stateA.AddTransition(stateB); } } mWalkToCenterState.AddTransition(mWalkToEndGoalState); mModel.Clickable = mInactiveState.Clickable; this.EnterInitialState(mInactiveState); }