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(); }
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."); }
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}发起了普通攻击。"); }
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}死亡。"); }
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); } }
/// <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; } }
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; } } } }
/// <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(); } }
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); } } }
/// <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]}。" ); }
public void AddLog(string text) { GameUI.AddLog("Year " + Year + ": " + text); }