예제 #1
0
        /// <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.");
            }
        }
예제 #2
0
        /// <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
                    )
                )
            );
        }
예제 #3
0
        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;
            });
        }
예제 #4
0
        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);
                }
            });
        }
예제 #5
0
        public void BuildNpcsForLevel(FashionLevel level)
        {
            mAvatarsDownloading = true;

            FashionGameCommands.GetAllHiredAvatars(delegate(Message message)
            {
                GetHiredNpcs(message, level, delegate() { mAvatarsDownloading = false; });
            });
        }
예제 #6
0
        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);
        }
예제 #7
0
        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.");
            }
        }
예제 #8
0
        public WalkToEndGoal(FashionModel model, FashionLevel level)
        {
            if (model == null)
            {
                throw new ArgumentNullException("model");
            }
            mModel = model;

            if (level == null)
            {
                throw new ArgumentNullException("level");
            }
            mLevel = level;
        }
예제 #9
0
        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;
        }
예제 #10
0
        /// <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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        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");
        }
예제 #14
0
        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;
        }
예제 #15
0
        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);
        }
예제 #16
0
        /// <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);
        }
예제 #17
0
        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();
            }
        }
예제 #18
0
        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
                        )
                    )
                );
            }
        }
예제 #19
0
        /// <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);
        }
예제 #20
0
        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") + ")"
                );
            }
        }
예제 #21
0
        /// <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);
        }