예제 #1
0
 private static void AddEventsToLog(this GameUI gameUI, List <ActionEvent> events)
 {
     if (events.Count == 0)
     {
         return;
     }
     gameUI.AddLog();
     gameUI.AddLog("本轮结算清单:");
     events.ForEach(actionEvent =>
     {
         var fishId =
             (actionEvent.Enemy ? gameUI.GameState.EnemyFishId : gameUI.GameState.MyFishId)
             [actionEvent.Pos];
         var fishName = SharedRefs.Mode == Constants.GameMode.Offline ||
                        !actionEvent.Enemy ||
                        gameUI.GameState.EnemyFishExpose[actionEvent.Pos]
             ? Constants.FishName[fishId]
             : "[未知]";
         gameUI.AddLog(
             $"  {actionEvent.Time}. {(actionEvent.Enemy ? GameUI.EnemyStr : GameUI.MeStr)}{actionEvent.Pos}号位置的{fishName}血量{(actionEvent.Positive ? "+" : "-")}{actionEvent.Value}"
             );
     });
     gameUI.AddLog();
 }
예제 #2
0
    public void Init(Map map)
    {
        EventHandler = new GameEventHandler(this);
        FlagGenerator = GameObject.Find("FlagGenerator").GetComponent<FlagGenerator>();
        FlagGenerator.GenerateFlag();
        Map = map;
        Map.InitializeMap(showRegionBorders: true, showShorelineBorders: true, showContinentBorders: false, showWaterConnections: false, MapColorMode.Basic, MapTextureMode.BiomeTextures);
        GameUI = GameObject.Find("GameUI").GetComponent<GameUI>();
        MarkovChainWordGenerator.TargetNumWords = Map.Regions.Count * 2;
        GameObject.Find("LoadingScreen").SetActive(false);

        // Camera
        CameraHandler = Camera.main.GetComponent<CameraHandler>();
        CameraHandler.SetMap(map);
        CameraHandler.JumpToFocusMap(map);

        GameUI.AddLog("Welcome to this new empty world.");
    }
예제 #3
0
        public static void NormalAttackAnim(this GameUI gameUI, JsonData actionInfo, string logPrefix)
        {
            var actionFish = (int)actionInfo["ActionFish"];
            var target     = (int)actionInfo["hit"][0]["target"];

            try
            {
                target = (int)actionInfo["hit"].OfType <JsonData>().First(e => (bool)e["traceable"])["target"];
            }
            catch (Exception e)
            {
                Debug.Log($"@{SharedRefs.ReplayCursor}");
                Debug.Log(e);
            }

            var myTurn   = gameUI.GameState.MyTurn;
            var distance =
                GameObjectManager.FishRelativePosition(!myTurn, actionFish) -
                GameObjectManager.FishRelativePosition(myTurn, target);

            gameUI.Repeat(cnt =>
            {
                (myTurn ? gameUI.Gom.MyFishTransforms : gameUI.Gom.EnemyFishTransforms)[actionFish].localPosition =
                    GameObjectManager.FishRelativePosition(myTurn, target) +
                    Math.Abs(cnt - 40f) / 40f * distance;
            }, () => { }, 81, 0, 10);

            var fishId   = (gameUI.GameState.MyTurn ? gameUI.GameState.EnemyFishId : gameUI.GameState.MyFishId)[target];
            var fishName = SharedRefs.Mode == Constants.GameMode.Offline ||
                           !gameUI.GameState.MyTurn ||
                           gameUI.GameState.EnemyFishExpose[(int)actionInfo["ActionFish"]]
                ? Constants.FishName[fishId]
                : "[未知]";
            var side = gameUI.GameState.MyTurn ? GameUI.EnemyStr : GameUI.MeStr;

            gameUI.AddLog($"{logPrefix}{side}{target}号位置的{fishName}发起了普通攻击。");
        }
예제 #4
0
        public static void Dissolve(this GameUI gameUI, bool enemy, int pos)
        {
            if (enemy)
            {
                gameUI.GameState.EnemyFishAlive[pos] = false;
            }
            else
            {
                gameUI.GameState.MyFishAlive[pos] = false;
            }

            try
            {
                var transform     = (enemy ? gameUI.Gom.EnemyFishTransforms : gameUI.Gom.MyFishTransforms)[pos];
                var meshRenderers = transform.GetComponentsInChildren <SkinnedMeshRenderer>();
                var fish          = (enemy ? gameUI.Gom.EnemyFishTransforms : gameUI.Gom.MyFishTransforms)[pos];
                var fog           = (enemy ? gameUI.Gom.EnemyFogs : gameUI.Gom.MyFogs)[pos];
                transform.GetComponentInChildren <ParticleSystem>().Play();

                foreach (var meshRenderer in meshRenderers)
                {
                    meshRenderer.material = gameUI.dissolveEffect;
                }

                gameUI.Repeat(cnt =>
                {
                    try
                    {
                        foreach (var meshRenderer in meshRenderers)
                        {
                            meshRenderer.material.SetFloat(gameUI.DissolveShaderProperty,
                                                           gameUI.fadeIn.Evaluate(Mathf.InverseLerp(0, 3, cnt / 25f)));
                        }
                    }
                    catch (Exception)
                    {
                        // ignored
                    }
                }, () =>
                {
                    try
                    {
                        if (fish != null)
                        {
                            Object.Destroy(fish.gameObject);
                        }
                        fog.gameObject.SetActive(false);
                    }
                    catch (Exception)
                    {
                        // ignored
                    }
                },
                              75, 0, 40);
            }
            catch (Exception)
            {
                // ignored
            }

            var name = SharedRefs.Mode == Constants.GameMode.Offline || !enemy || gameUI.GameState.EnemyFishExpose[pos]
                ? Constants.FishName[(enemy ? gameUI.GameState.EnemyFishId : gameUI.GameState.MyFishId)[pos]]
                : "鱼";

            gameUI.AddLog($"{(enemy ? GameUI.EnemyStr : GameUI.MeStr)}{pos}号位置的{name}死亡。");
        }
예제 #5
0
        public static void SkillAttackAnim(this GameUI gameUI, JsonData actionInfo, string logPrefix)
        {
            var myTurn     = gameUI.GameState.MyTurn;
            var actionFish = (int)actionInfo["ActionFish"];

            void Subtle()
            {
                if (!myTurn)
                {
                    gameUI.GameState.EnemyUsedSkills[actionFish].Add("无作为技能");
                }

                var myselfRecover = UnityEngine.Object.Instantiate(gameUI.recoverEffect, gameUI.allFishRoot);

                myselfRecover.localPosition = GameObjectManager.FishRelativePosition(!myTurn, actionFish);
                gameUI.SetTimeout(() => { UnityEngine.Object.Destroy(myselfRecover.gameObject); }, 4000);

                if (SharedRefs.Mode == Constants.GameMode.Online && !myTurn)
                {
                    gameUI.AddLog($"{logPrefix}己方使用了无作为技能。");
                    return;
                }

                var friendId = actionFish;

                for (var i = 0; i < 4; i++)
                {
                    if ((!myTurn || !gameUI.GameState.MyFishSelectedAsTarget[i]) &&
                        (myTurn || !gameUI.GameState.EnemyFishSelectedAsTarget[i]))
                    {
                        continue;
                    }
                    friendId = i;
                    break;
                }

                var shield = UnityEngine.Object.Instantiate(gameUI.shieldEffect, gameUI.allFishRoot);

                shield.localPosition = GameObjectManager.FishRelativePosition(!myTurn, friendId);
                gameUI.SetTimeout(() => { UnityEngine.Object.Destroy(shield.gameObject); }, 5000);

                gameUI.AddLog($"{logPrefix}己方{friendId}号位置的鱼使用了无作为技能。");
            }

            switch ((string)actionInfo["skill"]["type"])
            {
            case "aoe":
            {
                if (!myTurn)
                {
                    gameUI.GameState.EnemyUsedSkills[actionFish].Add("AOE");
                }
                var targetList = actionInfo["skill"]["targets"];
                var ids        = new List <string>();
                for (var i = 0; i < targetList.Count; i++)
                {
                    var id = (int)actionInfo["skill"]["targets"][i]["pos"];
                    ids.Add(id.ToString());
                    gameUI.SetTimeout(() =>
                        {
                            var originalDistance =
                                GameObjectManager.FishRelativePosition(myTurn, id) -
                                GameObjectManager.FishRelativePosition(!myTurn, actionFish);
                            var targetFishId = (myTurn ? gameUI.GameState.EnemyFishId : gameUI.GameState.MyFishId)[id];
                            var bias         = targetFishId == 4 ? new Vector3(4f, 0, 0) : new Vector3(3f, 0, 0);
                            var distance     = originalDistance + (originalDistance.x < 0 ? 1 : -1) * bias;
                            var angle        = Math.Atan(distance.x / distance.z) / Math.PI * 180.0;
                            UnityEngine.Object.Instantiate(
                                gameUI.waterProjectile,
                                GameObjectManager.FishRelativePosition(!myTurn, actionFish) +
                                new Vector3(3, 0, 0) * (myTurn ? -1 : 1),
                                Quaternion.Euler(
                                    new Vector3(
                                        0,
                                        Convert.ToInt32(myTurn
                                            ? angle < 0 ? angle : angle - 180.0
                                            : angle > 0
                                                ? angle
                                                : angle + 180.0),
                                        0
                                        )
                                    )
                                );
                        }, i * 120);
                }
                gameUI.AddLog(
                    $"{logPrefix}{(gameUI.GameState.MyTurn ? GameUI.EnemyStr : GameUI.MeStr)}{string.Join(",", ids)}号位置的鱼发起了AOE攻击。"
                    );
                if (SharedRefs.Mode == Constants.GameMode.Offline &&
                    (myTurn ? gameUI.GameState.MyFishSelectedAsTarget : gameUI.GameState.EnemyFishSelectedAsTarget)
                    .Any(b => b))
                {
                    Subtle();
                }
                break;
            }

            case "infight":
            {
                if (!myTurn)
                {
                    gameUI.GameState.EnemyUsedSkills[actionFish].Add("伤害队友");
                }
                var target        = (int)actionInfo["skill"]["targets"][0]["pos"];
                var myFishExplode = UnityEngine.Object.Instantiate(gameUI.bigExplosion, gameUI.allFishRoot);
                myFishExplode.localPosition = GameObjectManager.FishRelativePosition(!myTurn, target);
                gameUI.SetTimeout(() => { UnityEngine.Object.Destroy(myFishExplode.gameObject); }, 2000);
                var myFishRecover = UnityEngine.Object.Instantiate(gameUI.recoverEffect, gameUI.allFishRoot);
                myFishRecover.localPosition = GameObjectManager.FishRelativePosition(!myTurn, actionFish);
                gameUI.SetTimeout(() => { UnityEngine.Object.Destroy(myFishRecover.gameObject); }, 4000);
                gameUI.AddLog($"{logPrefix}伤害了己方{target}号位置队友。");
                break;
            }

            case "crit":
            {
                if (!myTurn)
                {
                    gameUI.GameState.EnemyUsedSkills[actionFish].Add("暴击");
                }
                var target   = (int)actionInfo["skill"]["targets"][0]["pos"];
                var distance =
                    GameObjectManager.FishRelativePosition(!myTurn, actionFish) -
                    GameObjectManager.FishRelativePosition(myTurn, target);
                gameUI.Repeat(cnt =>
                    {
                        (myTurn ? gameUI.Gom.MyFishTransforms : gameUI.Gom.EnemyFishTransforms)
                        [actionFish].localPosition =
                            GameObjectManager.FishRelativePosition(myTurn, target) +
                            Math.Abs(cnt - 5f) / 5f * distance;
                    }, () => { }, 11, 0, 40);
                gameUI.SetTimeout(() =>
                    {
                        var targetExplode =
                            UnityEngine.Object.Instantiate(gameUI.explodePrefab, gameUI.allFishRoot);
                        targetExplode.localPosition = GameObjectManager.FishRelativePosition(myTurn, target);
                        gameUI.SetTimeout(() => { UnityEngine.Object.Destroy(targetExplode.gameObject); }, 1000);
                    }, 200);
                gameUI.AddLog(
                    $"{logPrefix}{(gameUI.GameState.MyTurn ? GameUI.EnemyStr : GameUI.MeStr)}{target}号位置的鱼发起了暴击伤害。"
                    );
                if (SharedRefs.Mode == Constants.GameMode.Offline &&
                    (myTurn ? gameUI.GameState.MyFishSelectedAsTarget : gameUI.GameState.EnemyFishSelectedAsTarget)
                    .Any(b => b))
                {
                    Subtle();
                }
                break;
            }

            case "subtle":
            {
                Subtle();
                break;
            }
            }
            if (SharedRefs.Mode == Constants.GameMode.Online &&
                !myTurn && !gameUI.GameState.EnemyFishExpose[actionFish])
            {
                GameObjectManager.UpdateHiddenExtension(gameUI, actionFish);
            }
        }
예제 #6
0
        /// <summary>
        ///   <remarks>OFFLINE ONLY!</remarks>
        ///   <para>The method basically reads one record of replay data, handles
        /// it and increment the cursor by one.</para>
        /// </summary>
        public static void MoveCursor(this GameUI gameUI)
        {
            if (ErrorParser.HandleErrorCheck(gameUI))
            {
                return;
            }
            var state        = SharedRefs.ReplayJson[SharedRefs.ReplayCursor];
            var coercedState = SharedRefs.ReplayCursor >= SharedRefs.ReplayJson.Count - 1
                ? 2
                : (int)state["gamestate"];

            switch (coercedState)
            {
            case 2:     // Current round is over
            {
                var gain = (int)SharedRefs.ReplayJson[SharedRefs.ReplayCursor - 1]["score"]
                           - (int)SharedRefs.ReplayJson[SharedRefs.ReplayCursor - 2]["score"];
                gameUI.resultText.text = gain > 0 ? $"{GameUI.MeStr}获胜" : $"{GameUI.EnemyStr}获胜";
                gameUI.gameOverMask.SetActive(true);

                var rounds = (int)SharedRefs.ReplayJson[SharedRefs.ReplayCursor - 1]["rounds"] + 1;
                var score  = (int)SharedRefs.ReplayJson[SharedRefs.ReplayCursor - 1]["score"];
                gameUI.scoreText.text = $"{(rounds - score - 1) / 2}:{(score + rounds - 1) / 2}";

                for (var i = 0; i < 4; i++)
                {
                    if ((int)SharedRefs.ReplayJson[SharedRefs.ReplayCursor - 1]["players"][(gain + 1) / 2]
                        ["fight_fish"][i]["state"] != 2)
                    {
                        (gain > 0 ? gameUI.enemyStatus : gameUI.myStatus)[i].Current = 0;
                        gameUI.Dissolve(gain > 0, i);
                    }
                }

                if ((int)SharedRefs.ReplayJson[SharedRefs.ReplayCursor - 1]["rounds"] == 3)
                {
                    gameUI.gameOverText.text = "回到首页";
                    SharedRefs.ReplayCursor--;
                }
                break;
            }

            case 3:     // Process Assertion
            {
                SharedRefs.ReplayCursor++;
                var operation = state["operation"][0];
                var subject   = (int)state["cur_turn"] == 0 ? GameUI.MeStr : GameUI.EnemyStr;
                var target    = (int)state["cur_turn"] == 0 ? GameUI.EnemyStr : GameUI.MeStr;
                if ((string)operation["Action"] == "Assert")
                {
                    gameUI.GameState.AssertionPlayer = (int)operation["ID"];
                    gameUI.GameState.Assertion       = (int)operation["Pos"];
                    gameUI.GameState.AssertionTarget = (int)operation["id"] - 1;
                    gameUI.MakeAGuess(gameUI.GameState.AssertionPlayer == 0, 2000);
                    gameUI.AddLog(
                        $"{subject}断言{target}{operation["Pos"]}号位置鱼为{Constants.FishName[(int) operation["id"] - 1]}。"
                        );
                }
                else
                {
                    gameUI.GameState.Assertion = -1;
                    gameUI.ChangeStatus();
                    gameUI.AddLog($"{subject}放弃断言。");
                }
                break;
            }

            case 4:     // Process Action
            {
                SharedRefs.ReplayCursor++;
                var operation = state["operation"][0];
                if ((string)operation["Action"] == "Action")
                {
                    // Set attacher
                    gameUI.GameState.MyTurn = (int)operation["ID"] == 0;
                    if (gameUI.GameState.MyTurn)
                    {
                        gameUI.GameState.MyFishSelected = (int)operation["MyPos"];
                    }
                    else
                    {
                        gameUI.GameState.EnemyFishSelected = (int)operation["MyPos"];
                    }
                    gameUI.ChangeStatus();

                    // Set attackee
                    if (operation.ContainsKey("EnemyPos"))
                    {
                        (gameUI.GameState.MyTurn
                                ? gameUI.GameState.EnemyFishSelectedAsTarget
                                : gameUI.GameState.MyFishSelectedAsTarget)[(int)operation["EnemyPos"]] = true;
                        gameUI.GameState.NormalAttack = true;
                    }
                    else if (operation["EnemyList"] != null)
                    {
                        gameUI.GameState.NormalAttack = false;
                        if (operation["MyList"] != null)
                        {
                            for (var i = 0; i < operation["MyList"].Count; i++)
                            {
                                (gameUI.GameState.MyTurn
                                            ? gameUI.GameState.MyFishSelectedAsTarget
                                            : gameUI.GameState.EnemyFishSelectedAsTarget)
                                [(int)operation["MyList"][i]] = true;
                            }
                        }
                    }
                    SharedRefs.ActionInfo = operation["ActionInfo"];
                    gameUI.ChangeStatus();
                }

                // Process hp and death
                if (SharedRefs.ReplayJson[SharedRefs.ReplayCursor] != null)
                {
                    if ((int)SharedRefs.ReplayJson[SharedRefs.ReplayCursor]["gamestate"] == 3)
                    {
                        var players     = SharedRefs.ReplayJson[SharedRefs.ReplayCursor]["players"];
                        var lastPlayers = SharedRefs.ReplayJson[SharedRefs.ReplayCursor - 2]["players"];
                        for (var i = 0; i < 4; i++)
                        {
                            if ((int)players[0]["fight_fish"][i]["state"] == 2 &&
                                (int)lastPlayers[0]["fight_fish"][i]["state"] != 2)
                            {
                                gameUI.Dissolve(false, i);
                            }
                            if ((int)players[1]["fight_fish"][i]["state"] == 2 &&
                                (int)lastPlayers[1]["fight_fish"][i]["state"] != 2)
                            {
                                gameUI.Dissolve(true, i);
                            }
                        }
                    }
                    gameUI.SetTimeout(() =>
                        {
                            if (SharedRefs.AutoPlay)
                            {
                                gameUI.MoveCursor();
                            }
                            else
                            {
                                gameUI.nextStepButton.interactable  = true;
                                gameUI.prevStepButton.interactable  = true;
                                gameUI.prevRoundButton.interactable = true;
                                gameUI.nextRoundButton.interactable =
                                    (int)SharedRefs.ReplayJson[SharedRefs.ReplayCursor]["rounds"] < 2;
                            }
                        }, 3000);
                }
                break;
            }

            default:     // Something should be wrong
                SharedRefs.ReplayCursor++;
                gameUI.SetTimeout(gameUI.MoveCursor, 100);
                break;
            }
        }
예제 #7
0
        public static void AssertionAnim(this GameUI gameUI)
        {
            var hit =
                SharedRefs.Mode == Constants.GameMode.Offline &&
                gameUI.GameState.AssertionTarget == (gameUI.GameState.AssertionPlayer == 1
                    ? gameUI.GameState.MyFishId
                    : gameUI.GameState.EnemyFishId)[gameUI.GameState.Assertion] ||
                SharedRefs.Mode == Constants.GameMode.Online && gameUI.GameState.OnlineAssertionHit;

            gameUI.AddLog("断言" + (hit ? "成功。" : "失败。"));
            if (hit)
            {
                (gameUI.GameState.AssertionPlayer == 1
                    ? gameUI.Gom.MyFogs
                    : gameUI.Gom.EnemyFogs)[gameUI.GameState.Assertion].gameObject.SetActive(false);
                (gameUI.GameState.AssertionPlayer == 1
                    ? gameUI.GameState.MyFishExpose
                    : gameUI.GameState.EnemyFishExpose)[gameUI.GameState.Assertion] = true;

                if (SharedRefs.Mode == Constants.GameMode.Online)
                {
                    (gameUI.GameState.AssertionPlayer == 1
                            ? gameUI.GameState.MyFishId
                            : gameUI.GameState.EnemyFishId)
                    [gameUI.GameState.Assertion] = gameUI.GameState.AssertionTarget;
                    var transforms =
                        gameUI.GameState.AssertionPlayer == 1
                            ? gameUI.Gom.MyFishTransforms
                            : gameUI.Gom.EnemyFishTransforms;
                    Object.Destroy(transforms[gameUI.GameState.Assertion].gameObject);
                    transforms[gameUI.GameState.Assertion] = gameUI.Gom.GenFish(
                        gameUI.GameState.AssertionPlayer == 0,
                        gameUI.GameState.Assertion,
                        gameUI
                        );
                    if (gameUI.GameState.AssertionPlayer == 0)
                    {
                        gameUI.enemyExtensions[gameUI.GameState.Assertion].UpdateText(
                            $"{Constants.FishName[gameUI.GameState.AssertionTarget]}\n主动:{Constants.SkillDescription[gameUI.GameState.AssertionTarget]}\n被动:{Constants.PassiveDescription[gameUI.GameState.AssertionTarget]}"
                            );
                        gameUI.enemyProfiles[gameUI.GameState.Assertion].SetupFish(
                            gameUI.GameState.AssertionTarget,
                            gameUI.enemyExtensions[gameUI.GameState.Assertion]
                            );
                    }
                }
            }

            for (var i = 0; i < 4; i++)
            {
                if (((gameUI.GameState.AssertionPlayer == 1) ^ hit
                    ? gameUI.GameState.EnemyFishAlive
                    : gameUI.GameState.MyFishAlive)[i])
                {
                    var explosionObj = Object.Instantiate(
                        gameUI.explodePrefab,
                        GameObjectManager.FishRelativePosition(
                            (gameUI.GameState.AssertionPlayer == 1) ^ hit, i),
                        Quaternion.identity,
                        gameUI.allFishRoot).gameObject;
                    gameUI.SetTimeout(() => { Object.Destroy(explosionObj); }, 2000);
                    if (SharedRefs.Mode == Constants.GameMode.Offline || !gameUI.GameState.MyTurn)
                    {
                        ((gameUI.GameState.AssertionPlayer == 1) ^ hit ? gameUI.enemyStatus : gameUI.myStatus)
                        [i].Current -= 50;
                    }
                }
            }
        }
예제 #8
0
        /// <summary>
        ///   <para>Probably the most complicated part of the GameUI</para>
        ///   <para>Consider the game as a simple state machine. States are to
        /// be changed within enum <code>GameStatus</code>.<br/>
        ///   When This method is called, it indicates that there is a change
        /// of status in this game, and certain actions should be performed.</para>
        ///   <para>Basically, there are five states available:<br/>
        /// <code>DoAssertion</code><br/>
        /// <code>WaitAssertion</code><br/>
        /// <code>SelectMyFish</code><br/>
        /// <code>SelectEnemyFish</code><br/>
        /// <code>WaitingAnimation</code>
        /// </para>
        /// <para><code>SelectMyFish</code> and <code>WaitingAnimation</code>
        /// are rather simple - they merely serves as a no-op.</para>
        /// <para>As for `DoAssertion`, the main things that the method should
        /// handle are sending assertion selection to remote (when on player's
        /// turn) and playing assertion animation.</para>
        /// <para>And for `WaitAssertion`, literally it means waiting for the
        /// assertion animation to finish, and at this stage, this function
        /// shall either prepare the player for his operation when online and
        /// is his turn, or read the operation results from remote or replay.</para>
        /// <para>Lastly, for the `SelectEnemyFish` part, if it is the player's
        /// turn, send his attacking plan to remote first. After that, play the
        /// attacking animations.</para>
        /// </summary>
        public static void ChangeStatus(this GameUI gameUI)
        {
            switch (gameUI.GameState.GameStatus)
            {
            case Constants.GameStatus.DoAssertion:
            {
                var end = false;
                gameUI.GameState.GameStatus = Constants.GameStatus.WaitAssertion;

                void AfterWorks()
                {
                    gameUI.RunOnUiThread(() =>
                        {
                            // When either side made an assertion, play the animation.
                            if (gameUI.GameState.Assertion != -1)
                            {
                                gameUI.AssertionAnim();
                            }

                            if (SharedRefs.Mode == Constants.GameMode.Online && !gameUI.GameState.MyTurn)
                            {
                                if ((string)SharedRefs.ActionInfo["Action"] == "Finish")
                                {
                                    end = true;
                                    gameUI.resultText.text =
                                        (string)SharedRefs.ActionInfo["Result"] == "Win"
                                            ? $"{GameUI.MeStr}获胜"
                                            : $"{GameUI.EnemyStr}获胜";
                                    gameUI.GameOver((string)SharedRefs.ActionInfo["Result"] == "Win");
                                }
                                else
                                {
                                    for (var i = 0; i < 4; i++)
                                    {
                                        var id = i;
                                        if (gameUI.GameState.MyFishAlive[i] && gameUI.myStatus[i].Current <= 0)
                                        {
                                            gameUI.SetTimeout(() => { gameUI.Dissolve(false, id); }, 500);
                                        }
                                        if (gameUI.GameState.EnemyFishAlive[i] && gameUI.enemyStatus[i].Current <= 0)
                                        {
                                            gameUI.SetTimeout(() => { gameUI.Dissolve(true, id); }, 500);
                                        }
                                    }
                                }
                            }

                            if (end)
                            {
                                return;
                            }

                            // Enter `WaitAssertion` branch
                            gameUI.SetTimeout(() =>
                            {
                                gameUI.GameState.Assertion = -1;
                                gameUI.ChangeStatus();
                            }, gameUI.GameState.Assertion == -1 ? 200 : 1000);
                        });
                }

                // When online and my turn, I have to make an assertion and see
                // whether my assertion was correct. When online but not my turn,
                // the assertion result is stored in `SharedRefs.ActionInfo`, so
                // no operation is needed here.
                if (SharedRefs.Mode == Constants.GameMode.Online && gameUI.GameState.MyTurn)
                {
                    if (gameUI.GameState.Assertion == -1)
                    {
                        GameUI.SendWsMessage(JsonMapper.ToJson(new Null()));
                        gameUI.AddLog($"{GameUI.MeStr}放弃断言。");
                    }
                    else
                    {
                        GameUI.SendWsMessage(JsonMapper.ToJson(new Assert
                            {
                                Pos = gameUI.GameState.Assertion,
                                ID  = gameUI.GameState.AssertionTarget + 1
                            }
                                                               ));
                        gameUI.AddLog(
                            $"{GameUI.MeStr}断言{GameUI.EnemyStr}{gameUI.GameState.Assertion}号位置的鱼为{Constants.FishName[gameUI.GameState.AssertionTarget]}。"
                            );
                    }
                    SharedRefs.OnlineWaiting = 4;
                }
                else
                {
                    AfterWorks();
                }
                break;
            }

            case Constants.GameStatus.WaitAssertion:
                gameUI.GameState.GameStatus = Constants.GameStatus.SelectMyFish;
                if (SharedRefs.Mode == Constants.GameMode.Offline)
                {
                    gameUI.MoveCursor();
                }
                else if (gameUI.GameState.MyTurn)
                {
                    gameUI.Gom.ResetCountDown(gameUI);
                }
                else
                {
                    gameUI.RunOnUiThread(() =>
                    {
                        gameUI.ChangeStatus();
                        gameUI.ChangeStatus();
                    });
                }
                break;

            case Constants.GameStatus.SelectMyFish:
                gameUI.GameState.GameStatus = Constants.GameStatus.SelectEnemyFish;
                break;

            case Constants.GameStatus.SelectEnemyFish:
            {
                gameUI.GameState.GameStatus = Constants.GameStatus.WaitingAnimation;
                gameUI.AddLog();

                void AfterWorks()
                {
                    gameUI.RunOnUiThread(() =>
                        {
                            // And now the animation part
                            var hasPassive = gameUI.ActionAnim();

                            if (SharedRefs.Mode == Constants.GameMode.Offline ||
                                !gameUI.GameState.MyTurn ||
                                SharedRefs.ActionInfo.ContainsKey("EnemyAssert"))
                            {
                                // Now go for a new round
                                gameUI.GameState.MyTurn = !gameUI.GameState.MyTurn;
                                gameUI.SetTimeout(gameUI.NewRound, hasPassive ? 2000 : 1000);
                            }
                            else
                            {
                                // Game over
                                gameUI.resultText.text = (string)SharedRefs.ActionInfo["Result"] == "Win"
                                    ? $"{GameUI.MeStr}获胜"
                                    : $"{GameUI.EnemyStr}获胜";
                                gameUI.GameOver((string)SharedRefs.ActionInfo["Result"] == "Win");
                            }
                        });
                }

                // Handle the communication part with remote
                if (SharedRefs.Mode == Constants.GameMode.Online && gameUI.GameState.MyTurn)
                {
                    gameUI.Gom.StopCountDown(gameUI);
                    if (gameUI.GameState.NormalAttack)
                    {
                        var enemyPos = 0;
                        for (var i = 0; i < 4; i++)
                        {
                            if (!gameUI.GameState.EnemyFishSelectedAsTarget[i])
                            {
                                continue;
                            }
                            enemyPos = i;
                            break;
                        }
                        GameUI.SendWsMessage(JsonMapper.ToJson(new NormalAction
                            {
                                MyPos    = gameUI.GameState.MyFishSelected,
                                EnemyPos = enemyPos
                            }));
                    }
                    else
                    {
                        var myList    = new List <int>();
                        var enemyList = new List <int>();
                        for (var i = 0; i < 4; i++)
                        {
                            if (gameUI.GameState.MyFishSelectedAsTarget[i])
                            {
                                myList.Add(i);
                            }
                            if (gameUI.GameState.EnemyFishSelectedAsTarget[i])
                            {
                                enemyList.Add(i);
                            }
                        }
                        if (gameUI.GameState.MyFishId[gameUI.GameState.MyFishSelected] == 6)
                        {
                            gameUI.counters[gameUI.GameState.MyFishSelected].text =
                                $"{++gameUI.GameState.TurtleUsed}";
                        }
                        if (gameUI.GameState.MyFishId[gameUI.GameState.MyFishSelected] == 10)
                        {
                            gameUI.counters[gameUI.GameState.MyFishSelected].text =
                                $"{++gameUI.GameState.ClownUsed}";
                        }
                        if (gameUI.GameState.MyFishId[gameUI.GameState.MyFishSelected] == 11 &&
                            (SharedRefs.MyImitate == 6 || SharedRefs.MyImitate == 10))
                        {
                            gameUI.counters[gameUI.GameState.MyFishSelected].text =
                                $"{++gameUI.GameState.ImitateUsed}";
                        }
                        GameUI.SendWsMessage(JsonMapper.ToJson(new SkillAction
                            {
                                MyPos     = gameUI.GameState.MyFishSelected,
                                EnemyList = enemyList,
                                MyList    = myList
                            }));
                    }
                    SharedRefs.OnlineWaiting = 3;
                }
                else
                {
                    AfterWorks();
                }
                break;
            }

            case Constants.GameStatus.WaitingAnimation:
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
예제 #9
0
        public static void PassiveAnim(this GameUI gameUI, JsonData actionInfo)
        {
            var passiveList = actionInfo["passive"];

            for (var i = 0; i < passiveList.Count; i++)
            {
                var sourcePos = (int)passiveList[i]["source"];
                var enemy     = SharedRefs.Mode == Constants.GameMode.Offline
                    ? (int)passiveList[i]["player"] == 1
                    : (bool)passiveList[i]["isEnemy"];
                var sourceName = enemy ? GameUI.EnemyStr : GameUI.MeStr;
                switch ((string)passiveList[i]["type"])
                {
                case "counter":
                {
                    if (enemy)
                    {
                        gameUI.GameState.EnemyUsedPassives[sourcePos].Add("膨胀反伤");
                    }
                    gameUI.SetTimeout(() =>
                        {
                            var explosion           = Object.Instantiate(gameUI.smallExplosion, gameUI.allFishRoot);
                            explosion.localPosition = GameObjectManager.FishRelativePosition(enemy, sourcePos);
                            gameUI.SetTimeout(() => { Object.Destroy(explosion.gameObject); }, 1800);
                        }, 500);
                    gameUI.AddLog($"{sourceName}{sourcePos}号位置的鱼使用了被动技能:膨胀反伤。");
                    break;
                }

                case "deflect":
                    if (enemy)
                    {
                        gameUI.GameState.EnemyUsedPassives[sourcePos].Add("队友承伤");
                    }
                    gameUI.SetTimeout(() =>
                    {
                        for (var j = 0; j < 4; j++)
                        {
                            if (j == sourcePos)
                            {
                                continue;
                            }
                            if (enemy && gameUI.enemyStatus[j].Current <= 0 ||
                                !enemy && gameUI.myStatus[j].Current <= 0)
                            {
                                continue;
                            }
                            var targetExplode           = Object.Instantiate(gameUI.explodePrefab, gameUI.allFishRoot);
                            targetExplode.localPosition = GameObjectManager.FishRelativePosition(enemy, j);
                            gameUI.SetTimeout(() => { Object.Destroy(targetExplode.gameObject); }, 2000);
                        }
                    }, 400);
                    gameUI.AddLog($"{sourceName}{sourcePos}号位置的鱼使用了被动技能:队友承伤。");
                    break;

                case "reduce":
                {
                    if (enemy)
                    {
                        gameUI.GameState.EnemyUsedPassives[sourcePos].Add("减伤");
                    }
                    var shield = Object.Instantiate(gameUI.shieldEffect, gameUI.allFishRoot);
                    shield.localPosition = GameObjectManager.FishRelativePosition(enemy, sourcePos);
                    gameUI.SetTimeout(() => { Object.Destroy(shield.gameObject); }, 3000);
                    gameUI.AddLog($"{sourceName}{sourcePos}号位置的鱼使用了被动技能:减伤。");
                    break;
                }

                case "heal":
                {
                    if (enemy)
                    {
                        gameUI.GameState.EnemyUsedPassives[sourcePos].Add("自愈");
                    }
                    gameUI.SetTimeout(() =>
                        {
                            var recover           = Object.Instantiate(gameUI.recoverEffect, gameUI.allFishRoot);
                            recover.localPosition = GameObjectManager.FishRelativePosition(enemy, sourcePos);
                            gameUI.SetTimeout(() => { Object.Destroy(recover.gameObject); }, 2400);
                        }, 600);
                    gameUI.AddLog($"{sourceName}{sourcePos}号位置的鱼使用了被动技能:自愈。");
                    break;
                }

                case "explode":
                {
                    if (enemy)
                    {
                        gameUI.GameState.EnemyUsedPassives[sourcePos].Add("亡语");
                    }
                    gameUI.SetTimeout(() =>
                        {
                            var fireBall           = Object.Instantiate(gameUI.fireBallPrefab, gameUI.allFishRoot);
                            fireBall.localPosition = GameObjectManager.FishRelativePosition(enemy, sourcePos);
                            gameUI.SetTimeout(() => { Object.Destroy(fireBall.gameObject); }, 3000);
                        }, 500);
                    gameUI.AddLog($"{sourceName}{sourcePos}号位置的鱼使用了被动技能:亡语。");
                    break;
                }
                }
                if (SharedRefs.Mode == Constants.GameMode.Online &&
                    enemy && !gameUI.GameState.EnemyFishExpose[sourcePos])
                {
                    GameObjectManager.UpdateHiddenExtension(gameUI, sourcePos);
                }
            }
        }
예제 #10
0
        /// <summary>
        ///   <para>First, resets the game states.<br/>
        /// After that, for online mode, listens to message from remote
        /// and determine what to show next; for offline mode, simply resets
        /// <code>_gameStatus</code> to <code>DoAssertion</code>.</para>
        /// </summary>
        public static void NewRound(this GameUI gameUI)
        {
            gameUI.GameState.MyFishSelected    = -1;
            gameUI.GameState.EnemyFishSelected = -1;
            gameUI.GameState.NormalAttack      = true;
            gameUI.GameState.GameStatus        = Constants.GameStatus.DoAssertion;
            for (var i = 0; i < 4; i++)
            {
                gameUI.GameState.MyFishSelectedAsTarget[i] = gameUI.GameState.EnemyFishSelectedAsTarget[i] = false;
            }
            gameUI.AddLog();

            if (SharedRefs.Mode == Constants.GameMode.Offline)
            {
                var players = SharedRefs.ReplayJson[SharedRefs.ReplayCursor]["players"];
                for (var i = 0; i < 4; i++)
                {
                    gameUI.myProfiles[i].SetAtk((int)players[0]["fight_fish"][i]["atk"]);
                    gameUI.enemyProfiles[i].SetAtk((int)players[1]["fight_fish"][i]["atk"]);
                }
                return;
            }

            for (var i = 0; i < 4; i++)
            {
                gameUI.GameState.MyFishId[i] = SharedRefs.FishChosen[i];
            }

            if (!gameUI.Gom.Initialized)
            {
                gameUI.Gom.Init(gameUI);
            }

            if (SharedRefs.ActionInfo.ContainsKey("GameInfo"))
            {
                var gameInfo = SharedRefs.ActionInfo["GameInfo"];
                for (var i = 0; i < 4; i++)
                {
                    if ((int)gameInfo["EnemyFish"][i] > 0)
                    {
                        gameUI.GameState.EnemyFishId[i] = (int)gameInfo["EnemyFish"][i] - 1;
                    }
                    gameUI.myProfiles[i].SetAtk((int)gameInfo["MyATK"][i]);
                    if (gameUI.GameState.MyFishAlive[i] && gameUI.myStatus[i].Current <= 0)
                    {
                        gameUI.Dissolve(false, i);
                    }
                    if (gameUI.GameState.EnemyFishAlive[i] && gameUI.enemyStatus[i].Current <= 0)
                    {
                        gameUI.Dissolve(true, i);
                    }
                }
            }

            if (gameUI.GameState.MyTurn)
            {
                gameUI.Gom.ResetCountDown(gameUI);
                return;
            }

            gameUI.GameState.AssertionPlayer = 1;
            var enemyAssert = SharedRefs.ActionInfo["EnemyAssert"];

            if (enemyAssert["AssertPos"] == null)
            {
                gameUI.AddLog($"{GameUI.EnemyStr}放弃断言。");
                gameUI.GameState.Assertion          = -1;
                gameUI.GameState.OnlineAssertionHit = false;
                gameUI.GameState.AssertionTarget    = 0;
                gameUI.ChangeStatus();
                return;
            }

            gameUI.GameState.Assertion          = (int)enemyAssert["AssertPos"];
            gameUI.GameState.OnlineAssertionHit = (bool)enemyAssert["AssertResult"];
            gameUI.GameState.AssertionTarget    = (int)enemyAssert["AssertContent"] - 1;
            gameUI.MakeAGuess(false, 1200);
            gameUI.SetTimeout(gameUI.ChangeStatus, 3000); // Just waits for the assertion animation to finish

            gameUI.AddLog(
                $"{GameUI.EnemyStr}断言{GameUI.MeStr}{gameUI.GameState.Assertion}号位置的鱼为{Constants.FishName[gameUI.GameState.AssertionTarget]}。"
                );
        }
예제 #11
0
 public void AddLog(string text)
 {
     GameUI.AddLog("Year " + Year + ": " + text);
 }