void DestroyMech(BattleMech mechToDestroy) { Debug.Log(mechToDestroy.name + " destroyed!"); BattleTile tile = mechToDestroy.tile; // Remove the mech and all references to it (such as teams and targets). tile.mech = null; mechToDestroy.team.mechs.Remove(mechToDestroy); mechToDestroy.isDestroyed = true; foreach (BattleTeam team in this.teams) { foreach (BattleMech mech in team.mechs) { if (mech.target == mechToDestroy) { mech.target = null; } } } Destroy(mechToDestroy.gameObject); // Change the map TileData tileData = GameData.GetTile("Destroyed mech"); tileData.groundMaterial = tile.data.groundMaterial; tile.Recreate(tileData); this.UpdateFogOfWar(); }
/* * Tilemap section */ public void PrintTileInfo(Vector3Int cellPosition) { BattleTile tile = PathfindingMap.GetTile(cellPosition) as BattleTile; if (tile != null) { Debug.Log($"Tile at position ({cellPosition.x}, {cellPosition.y}) exists\n Is blocked: {tile.IsBlocked}"); Node node = _graph.GetNode(cellPosition); Debug.Log($"Connections count: {node.Connections.Count}"); if (node.ProcessStatus == Node.NodeProcessStatus.InClosedList) { Debug.Log($"In closed list"); } else if (node.ProcessStatus == Node.NodeProcessStatus.InOpenList) { Debug.Log($"In open list"); } else if (node.ProcessStatus == Node.NodeProcessStatus.NotVisited) { Debug.Log($"Not visited"); } } else { Debug.Log($"Tile at position ({cellPosition.x}, {cellPosition.y}) does not exist"); } }
public void Populate() { int[,] map = World.BattlefieldByID(Player.CurrentTown.ID).Field; int width = map.GetLength(0); int height = map.GetLength(1); BattlefieldForm.ArenaField = new BattleTile[width + 1, height + 1]; BattleTile[,] arenaField = new BattleTile[width, height]; int panelWidth = panel1.Width / width; int panelHeight = panel1.Height / height; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { Occupied occ; occ = Occupied.Empty; BattleTile square = new BattleTile(panel1, occ, panelHeight, panelWidth, j, i, map[j, i], rtbBattle, SelectedTile, MyTeam, EnemyTeam, ArenaField, height); panel1.Controls.Add(square.Button); arenaField[j, i] = square; } } BattleTile[,] arenafieldTemp = new BattleTile[width + 1, height + 1]; BattleTile.endBattle = btnEndBattle; foreach (BattleTile bt in arenaField) { arenafieldTemp[bt.X, bt.Y] = bt; } BattlefieldForm.ArenaField = arenafieldTemp; BattleTile.ArenaField = ArenaField; }
//creates new tiles for both player and enemy private BattleTile CreateTile(Vector2 pos) { BattleTile tile = Instantiate(battleTilePrefab, pos, Quaternion.identity).GetComponent <BattleTile>(); tile.transform.parent = transform; tile.transform.localPosition = pos; return(tile); }
// TODO: State dependent behaviour for when a tile can't be clicked bool CanClickTile() { BattleTile tile = this.hoveredTile; if (this.state == BattleState.SelectingAction) { return(true); } else if (this.state == BattleState.MoveAction) { if ( tile == null || tile == this.selectedTile || tile.mech != null || tile.data.allowsMovement == false || this.CanTeamSeeTile(this.selectedTile.mech.team, tile) == false ) { return(false); } if (this.moveActionData.pathingResult == null) { this.moveActionData.pathingResult = this.pathNetwork.FindPath( this.selectedTile, tile ); } if (this.moveActionData.pathingResult.Value.isValid == false) { return(false); } BattleMech mech = this.selectedTile.mech; var apCostResult = mech.GetAPCostForMove(this.moveActionData.pathingResult.Value.nodes); if (apCostResult.isValid == false) { return(false); } return(true); } else if (this.state == BattleState.SetTargetAction) { return( tile != null && tile.mech != null && tile != this.selectedTile && this.CanTeamSeeTile(this.selectedTile.mech.team, tile) ); } else { return(false); } }
public override void Execute(BattleManager manager, BattleQueueTime time) { BattleQueueTime.Generator timeAllTargets = new BattleQueueTime.InfiniteGenerator(time); int hpcost = Mathf.RoundToInt(HPCost * Skill.Cost(Agent)); int spcost = Mathf.RoundToInt(SPCost * Skill.Cost(Agent)); if (Agent.HP <= hpcost || Agent.SP < spcost) { return; } Agent.HP -= hpcost; Agent.SP -= spcost; foreach (Vector2Int point in Target) { BattleTile tile = manager.grid[point]; if (tile != null && tile.Actor != null) { BattleQueueTime.Generator timeThisTarget = new BattleQueueTime.FiniteGenerator(timeAllTargets.Generate(), 5); BattleAgent target = tile.Actor.Agent; // Trigger any events before the user uses the skill BattleSkillEvent eventInfo = new BattleSkillEvent( BattleEvent.Type.BeforeUseSkill, manager, timeThisTarget.Generate(), Agent, target, Skill ); eventInfo.Power = Mathf.RoundToInt(eventInfo.Power * Power); Agent.OnTrigger(eventInfo); // Trigger any events before the target is targeted by the skill eventInfo.Time = timeThisTarget.Generate(); eventInfo.Event = BattleEvent.Type.BeforeTargetedBySkill; target.OnTrigger(eventInfo); // Animate the skill if (Skill.Animation != null) { manager.Add(new BattleSpecialEffectAnimation(timeThisTarget.Generate(), Skill.Animation, eventInfo.Target)); } // Make the skill happen eventInfo.Time = timeThisTarget.Generate(); Skill.Execute(eventInfo); // Trigger any events after the target is targeted by the skill eventInfo.Time = timeThisTarget.Generate(); eventInfo.Event = BattleEvent.Type.AfterTargetedBySkill; target.OnTrigger(eventInfo); } } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Event-like functions public void MouseEvent(MapTile mapTile, MapDisplay.MouseEventType eventType) { if (hardInput.GetKey("Pan Camera")) { return; } BattleTile tile = mapTile ? this.GetTile(mapTile.pos) : null; BattleTile newHoveredTile = this.hoveredTile; if (eventType == MapDisplay.MouseEventType.Enter) { newHoveredTile = tile; } else if (eventType == MapDisplay.MouseEventType.Exit) { newHoveredTile = null; } else if (eventType == MapDisplay.MouseEventType.Click) { if (this.CanClickTile()) { this.HexTileClicked(); } } else if (eventType == MapDisplay.MouseEventType.RightClick) { this.HexTileRightClicked(); } if (newHoveredTile != this.hoveredTile) { if (this.hoveredTile) { // Stopped hovering this tile. this.mapDisplay.DisableHoveredTile(); } this.hoveredTile = newHoveredTile; if (this.hoveredTile) { // Started hovering this tile. this.mapDisplay.SetHoveredTile(this.hoveredTile.mapTile); } this.HexTileHovered(); } }
public bool TestLOS(BattleTile tile1, BattleTile tile2) { Vector2 from = tile1.Get2DPosition(); Vector2 to = tile2.Get2DPosition(); Vector2 dir = (to - from).normalized; RaycastHit2D result = Physics2D.Raycast( from, dir, Vector2.Distance(from, to), LayerMask.GetMask("Map 2D") ); bool canSee = result.collider == null; return(canSee); }
private void FindTartget() { currnetTile = enemy.GetCurrentTile(enemyPosition); if (currnetTile == null) { return; } if (enemy.TargetObject != null && pathTile == null) { BattleTile destinationTile = enemy.GetCurrentTile(targetPosition); if (targetDistance < longAttackLength * 2f) { Debug.Log("타겟은 있는데 경로가 없는 경우의 이동"); MoveChar(destinationTile); } else { pathTile = null; PathFinder(destinationTile); } } else if (enemy.TargetObject != null && pathTile != null) { if (enemy.currentState is Idle && pathTile.Count > 0) { Debug.Log("타겟이 있고, 경로도 있는 경우의 이동"); MoveChar(pathTile.Pop()); } //다음 목적지가 없는 경우 도착으로 간주 else if (pathTile.Count == 0) { pathTile = null; } } else if (enemy.TargetObject == null) { int randomCoord = Random.Range(0, coordX.Length); BattleTile battleTile = SearchAdjacentTiles(randomCoord); if (battleTile != null) { MoveChar(battleTile); Debug.Log("타겟이 없으면 주변을 배회한다."); } } }
private Stack <BattleTile> CreateParh(BattleTile startTile) { Stack <BattleTile> tempPathTile = new Stack <BattleTile>(); tempPathTile.Push(currnetTile); BattleTile parent = TileManager.Instance.BattleTileGrid[currnetTile.ParentTileXCoord, currnetTile.ParentTileZCoord].GetComponent <BattleTile>(); while (parent != startTile) { tempPathTile.Push(parent); parent = TileManager.Instance.BattleTileGrid[parent.ParentTileXCoord, parent.ParentTileZCoord].GetComponent <BattleTile>(); } return(tempPathTile); }
override public void init(Rectangle screenSize) { //init self base.init(screenSize); //backButton = new Button(this, Renderer, new Rectangle(0, 0, 100, 100), "Back"); //backButton.setClick(() => { // base.gameController.goToPreviousScreen(); // return true; //}); battleControls = new BattleInfoTile(this, Renderer, new Rectangle(0, (int)(ScreenSize.Height * .8), (int)(ScreenSize.Width), (int)(ScreenSize.Height * .2))); Rectangle battleTileRect = new Rectangle(0, 0, (int)(ScreenSize.Width), (int)(ScreenSize.Height * .8)); battle = new Battle(playerInfo.PlayerArmy, playerInfo.EnemyArmy, battleTileRect); battleTile = new BattleTile(this, this.Renderer, battleTileRect, battle); soundController.playSong("HeroicDemise"); }
//Player shooting public void OnTileClick(BattleTile tile) { if (gameState == GameState.MyTurn) { if (gameEnded) { return; } if (selectedTile.Contains(tile)) { tile.Selected = false; selectedTile.Remove(tile); } else { tile.Selected = true; selectedTile.Add(tile); HowManyTileLeftEmpty(); if (selectedTile.Count == shotsAmount) { foreach (BattleTile t in selectedTile) { t.Selected = false; enemyMap.ShootAt(t.X, t.Y); } if (enemyMap.AllShipsAreDead()) { EndGame(); } selectedTile.Clear(); gameState = GameState.EnemyTurn; } } } }
private void PathFinder(BattleTile destinationTile) { openSet.Clear(); closedSet.Clear(); currnetTile = enemy.GetCurrentTile(enemyPosition); startTile = currnetTile; startTile.ParentTileXCoord = currnetTile.TileCoordinate.x; startTile.ParentTileZCoord = currnetTile.TileCoordinate.z; endTile = destinationTile; do { closedSet.Add(currnetTile); for (int i = 0; i < coordX.Length; i++) { BattleTile battleTile = SearchAdjacentTiles(i); if (battleTile != null) { if (battleTile.isWall) { closedSet.Add(battleTile); continue; } battleTile.g = Mathf.Abs(startTile.TileCoordinate.x - battleTile.TileCoordinate.x) + Mathf.Abs(startTile.TileCoordinate.z - battleTile.TileCoordinate.z); battleTile.h = Mathf.Abs(battleTile.TileCoordinate.x - endTile.TileCoordinate.x) + Mathf.Abs(battleTile.TileCoordinate.z - endTile.TileCoordinate.z); int tempG = 0; if (battleTile.g < currnetTile.g) { tempG = currnetTile.g; } battleTile.f = battleTile.g + battleTile.h + tempG; if (!closedSet.Contains(battleTile) && !openSet.Contains(battleTile)) { battleTile.ParentTileXCoord = currnetTile.TileCoordinate.x; battleTile.ParentTileZCoord = currnetTile.TileCoordinate.z; openSet.Add(battleTile); } if (openSet.Count > 1) { openSet.Sort(delegate(BattleTile a, BattleTile b) { if (a.f > b.f) { return(1); } else if (a.f < b.f) { return(-1); } return(0); }); } } } if (openSet.Count > 0) { currnetTile = openSet[0]; openSet.Remove(currnetTile); } else { return; } }while (currnetTile != endTile); pathTile = CreateParh(startTile); }
public void Update() { // Test: path to a target mech, stop when we can see it and keep firing. BattleMech target = null; foreach (BattleTeam team in this.battle.teams) { foreach (BattleMech mech in team.mechs) { if (team != this.ourMech.team) { target = mech; break; } } } if (target == null) { return; } BattleTile ourTile = this.ourMech.tile; BattleTile targetTile = target.tile; bool canSeeTarget = this.battle.TestLOS(ourTile, targetTile); // TODO: this is really stupid this.battle.pathNetwork.SetNodeEnabled(ourTile, true); this.battle.pathNetwork.SetNodeEnabled(targetTile, true); PathingResult result = this.battle.pathNetwork.FindPath(ourTile, targetTile); this.battle.pathNetwork.SetNodeEnabled(ourTile, false); this.battle.pathNetwork.SetNodeEnabled(targetTile, false); if (result.isValid == false) { return; } BattleTile nextTile = (BattleTile)result.nodes[1]; if (canSeeTarget && result.distance <= 5) { var move = new BattleMove.StandingFire(); move.mechIndex = ourTile.index; move.targetMechIndex = targetTile.index; this.battle.ExecuteMove(move); } else { var move = new BattleMove.Move(); move.mechIndex = ourTile.index; move.newIndex = nextTile.index; if (canSeeTarget) { move.isFiring = true; move.targetMechIndex = targetTile.index; } else { move.isFiring = false; } this.battle.ExecuteMove(move); } this.battle.SetState(BattleState.EndOfAction); }
/* * Graph section */ public void InitializeGraph() { _graph = new PathfindingGraph(); PathfindingMap.CompressBounds(); //analyze pathfinding map and build pathfinding graph foreach (Vector3Int pos in PathfindingMap.cellBounds.allPositionsWithin) { BattleTile tile = PathfindingMap.GetTile <BattleTile>(pos); if (tile != null) { Node centralTileNode = _graph.GetNode(pos); if (centralTileNode == null) { centralTileNode = new Node(); centralTileNode.Coords = pos; centralTileNode.ProcessStatus = Node.NodeProcessStatus.NotVisited; if (tile.IsBlocked) { centralTileNode.GameStatus = Node.TileGameStatus.Block; } else { centralTileNode.GameStatus = Node.TileGameStatus.Empty; } centralTileNode.Influences = new List <KeyValuePair <int, Node.InfluenceStatus> >(); _graph.AddNode(centralTileNode); } //adding connections if (centralTileNode.GameStatus == Node.TileGameStatus.Empty) { for (int i = 0; i < 4; ++i) { Vector3Int currentTileLocation = pos + offsets[i]; BattleTile offsetTile = PathfindingMap.GetTile <BattleTile>(currentTileLocation); if (offsetTile != null) { Node offsetTileNode = _graph.GetNode(currentTileLocation); if (offsetTileNode == null) { offsetTileNode = new Node(); offsetTileNode.Coords = currentTileLocation; offsetTileNode.ProcessStatus = Node.NodeProcessStatus.NotVisited; if (offsetTile.IsBlocked) { offsetTileNode.GameStatus = Node.TileGameStatus.Block; } else { offsetTileNode.GameStatus = Node.TileGameStatus.Empty; } offsetTileNode.Influences = new List <KeyValuePair <int, Node.InfluenceStatus> >(); _graph.AddNode(offsetTileNode); } if (offsetTileNode.GameStatus == Node.TileGameStatus.Empty) { centralTileNode.AddConnection(offsetTileNode); } } } } } } }
public bool CanTeamSeeTile(BattleTeam team, BattleTile tile) { return(team.visibleTiles[tile.mapTile.pos.x + tile.mapTile.pos.y * this.mapSize.x] == true || this.fogOfWar == false); }
void Start() { // Load map XmlDocument mapDoc = new XmlDocument(); mapDoc.PreserveWhitespace = false; try { mapDoc.Load("Assets/Battle/Data/Maps/" + NextMapFile + ".xml"); XmlNode root = mapDoc.SelectSingleNode("map"); grid.info = root.SelectSingleNode("grid") as XmlElement; foreach (XmlElement battleInfo in root.SelectNodes("battle")) { if (battleInfo.GetAttribute("id").Equals(NextBattle)) { // Load agents BattleUnit.Reset(); foreach (XmlElement characterInfo in battleInfo.SelectNodes("character")) { try { string unit = characterInfo.HasAttribute("unit") ? characterInfo.GetAttribute("unit") : "civilian"; BattleBehaviour behaviour; if (characterInfo.HasAttribute("behaviour")) { behaviour = BattleBehaviour.Parse(characterInfo.GetAttribute("behaviour")); } else if (unit.Equals("player")) { behaviour = null; } else if (unit.Equals("civilian")) { behaviour = null; // TODO run away } else { behaviour = new BattleOffensiveBehaviour(); } Character character = AssetHolder.Characters[characterInfo.GetAttribute("name")]; BattleAgent agent = new BattleAgent(character, behaviour); agent.Coordinates = new Vector2Int( int.Parse(characterInfo.GetAttribute("x")), int.Parse(characterInfo.GetAttribute("y")) ); agent.Unit = BattleUnit.Get(unit); agents.Add(agent); BattleTile tile = grid[agent.Coordinates]; BattleActor actor = Instantiate <BattleActor>((BattleActor)AssetHolder.Objects["actor"], tile.ground.transform); actor.Agent = agent; tile.Actor = actor; } catch (System.Exception e) { Debug.Log(e); // TODO } } // Load cutscenes m_Cutscenes = new Dictionary <string, BattleAction>(); foreach (XmlElement cutsceneInfo in battleInfo.SelectNodes("cutscene")) { try { List <BattleAction> cutsceneSequence = new List <BattleAction>(); foreach (XmlNode sceneInfoNode in cutsceneInfo.ChildNodes) { XmlElement sceneInfo = sceneInfoNode as XmlElement; if (sceneInfo != null) { if (sceneInfo.Name.Equals("move")) { string character = sceneInfo.GetAttribute("character"); BattleAgent target = null; foreach (BattleAgent agent in agents) { if (agent.BaseCharacter.Name.Equals(character)) { target = agent; break; } } if (target != null) { cutsceneSequence.Add( new BattleMoveAction( target, new Vector2Int( int.Parse(sceneInfo.GetAttribute("x")), int.Parse(sceneInfo.GetAttribute("y")) ) ) ); } } else if (sceneInfo.Name.Equals("text")) { string character = sceneInfo.GetAttribute("character"); BattleAgent target = null; foreach (BattleAgent agent in agents) { if (agent.BaseCharacter.Name.Equals(character)) { target = agent; break; } } if (target != null) { cutsceneSequence.Add( new BattleDialogueAction(target, sceneInfo.InnerText.Trim()) ); } } } } m_Cutscenes.Add(cutsceneInfo.GetAttribute("trigger"), new BattleSequenceAction(cutsceneSequence)); } catch (System.Exception e) { Debug.Log(e); } } } } BattleAgentUI.Shown = false; BattleSelector.Shown = false; } catch (System.Exception e) { Debug.Log(e); // TODO } }
protected bool IsValidTarget(Vector2Int point) { BattleTile tile = m_Manager.grid[point]; return(tile != null && tile.Actor != null); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // State-dependent behaviour public void SetState(BattleState newState) { if (this.state != BattleState.None) { Debug.Log("Ending state " + this.state); } if (this.state == BattleState.AiControl) { this.uiRefs.advanceAiButton.interactable = false; } else if (this.state == BattleState.MoveAction) { if (this.moveActionData.ghostMechTiles != null) { foreach (BattleTile tile in this.moveActionData.ghostMechTiles) { tile.mapTile.RemoveLayer(MapTile.Layer.GhostSprite); } } this.moveActionData.ghostMechTiles = null; if (this.moveActionData.losLinesGO) { Destroy(this.moveActionData.losLinesGO); } if (this.moveActionData.moved == false) { this.pathNetwork.SetNodeEnabled(this.moveActionData.fromTile, false); } this.ResetActionPointsPreview(); } this.state = newState; Debug.Log("Beginning state " + this.state); if (this.state == BattleState.EndOfAction) { if (this.currentTeam.isPlayer) { this.SetState(BattleState.SelectingAction); } else { this.SetState(BattleState.AiControl); } } else if (this.state == BattleState.AiControl) { this.hoveredTile = null; this.selectedTile = null; this.mapDisplay.DisableSelectedTiles(); this.mapDisplay.DisableHoveredTile(); this.SetMenusUsable(false); this.uiRefs.advanceAiButton.interactable = true; // TODO: ugh, this is AWFUL this.AdjustTileInfoTabButtonGraphics(); this.UpdateRightPanel(); } else if (this.state == BattleState.SelectingAction) { this.HexTileHovered(); this.SetMenusUsable(true); } else if (this.state == BattleState.MoveAction) { this.moveActionData = new MoveActionData(); this.moveActionData.fromTile = this.selectedTile; this.moveActionData.pathingResult = null; this.moveActionData.ghostMechTiles = new List <BattleTile>(); this.moveActionData.moved = false; this.pathNetwork.SetNodeEnabled(this.moveActionData.fromTile, true); this.SetMenusUsable(false); } else if (this.state == BattleState.SetTargetAction) { this.SetMenusUsable(false); } }
void HexTileHovered() { bool isHoveredTileGOActive = this.hoveredTile != null; if (this.state == BattleState.AiControl) { isHoveredTileGOActive = false; } else if (this.state == BattleState.MoveAction) { foreach (BattleTile tile in this.moveActionData.ghostMechTiles) { tile.mapTile.RemoveLayer(MapTile.Layer.GhostSprite); } this.moveActionData.ghostMechTiles.Clear(); if (this.moveActionData.losLinesGO) { Destroy(this.moveActionData.losLinesGO); } this.moveActionData.losLinesGO = new GameObject("LOS lines"); this.moveActionData.losLinesGO.transform.parent = this.worldGO.transform; this.ResetActionPointsPreview(); this.moveActionData.pathingResult = this.pathNetwork.FindPath( this.selectedTile, this.hoveredTile ); if (this.CanClickTile() == false) { goto end; } PathingResult result = this.moveActionData.pathingResult.Value; if (result.isValid == false) { goto end; } // Create ghost mechs this.moveActionData.ghostMechTiles.Capacity = result.nodes.Count - 1; GameObject prevGO = this.selectedTile.gameObject; GameObject currentGO; for (int n = 1; n < result.nodes.Count; ++n) { BattleTile tile = (BattleTile)result.nodes[n]; this.moveActionData.ghostMechTiles.Add(tile); currentGO = tile.gameObject; bool right = currentGO.transform.position.x > prevGO.transform.position.x; tile.mapTile.SetLayer( MapTile.Layer.GhostSprite, sprite: this.selectedTile.mech.data.sprite, flipX: right, color: new Color(1.0f, 1.0f, 1.0f, 0.5f) ); prevGO = currentGO; } // Create LOS lines from each tile to the target BattleMech target = this.selectedTile.mech.target; if (target && this.selectedTile.mech.fireAuto) { for (int n = 1; n < result.nodes.Count; ++n) { BattleTile tile = (BattleTile)result.nodes[n]; GameObject go = (GameObject)Instantiate(Resources.Load("Prefabs/LOS line")); go.transform.parent = this.moveActionData.losLinesGO.transform; float offsetOutward = 0.33f; Vector3 dir = (target.tile.transform.position - tile.transform.position).normalized; Vector3 pos1 = tile.transform.position + dir * offsetOutward; Vector3 pos2 = target.tile.transform.position - dir * offsetOutward; float height = 0.25f; pos1.y += height; pos2.y += height; LineRenderer lr = go.GetComponent <LineRenderer>(); lr.SetPositions(new Vector3[] { pos1, pos2 }); bool canSee = this.TestLOS(tile, target.tile); Color lineColor = canSee ? Color.green : Color.red; lr.startColor = lineColor; lr.endColor = lineColor; } } // Update action point UI element. float apRequired = this.selectedTile.mech.GetAPCostForMove(result.nodes).ap; this.UpdateActionPointsPreview(this.selectedTile.mech.actionPoints - apRequired); } end: if (isHoveredTileGOActive) { this.mapDisplay.SetHoveredTile(this.hoveredTile.mapTile); this.mapDisplay.SetHoveredTileValid(this.CanClickTile()); } else { this.mapDisplay.DisableHoveredTile(); } }
// NOTE: can be null void HexTileClicked() { BattleTile clickedTile = this.hoveredTile; if (this.state == BattleState.SelectingAction) { if (clickedTile != this.selectedTile) { if (this.selectedTile) { // Unselected this tile. this.mapDisplay.DisableSelectedTiles(); this.mapDisplay.DisableTargetTile(); } this.selectedTile = clickedTile; if (this.selectedTile) { // Selected this tile. this.mapDisplay.SetSelectedTile(this.selectedTile.mapTile); BattleMech mech = this.selectedTile.mech; if (mech) { this.UpdateTargetTile(mech); } } else { // Just for a consistent look when no tile is selected. this.BringTileTabButtonToFront(this.uiRefs.mechTabButton); } this.AdjustTileInfoTabButtonGraphics(); this.UpdateRightPanel(); } } else if (this.state == BattleState.MoveAction) { if (clickedTile) { BattleMech mech = this.selectedTile.mech; var move = new BattleMove.Move(); move.mechIndex = mech.tile.index; move.newIndex = clickedTile.index; move.isFiring = mech.target != null && mech.fireAuto; if (move.isFiring) { move.targetMechIndex = mech.target.tile.index; } this.ExecuteMove(move); this.moveActionData.moved = true; // Make this the new selected tile. this.selectedTile = clickedTile; this.mapDisplay.SetSelectedTile(this.selectedTile.mapTile); this.UpdateTargetTile(this.selectedTile.mech); this.UpdateRightPanel(); this.SetState(BattleState.EndOfAction); } else { this.SetState(BattleState.EndOfAction); } } else if (this.state == BattleState.SetTargetAction) { BattleMech mech = this.selectedTile.mech; var move = new BattleMove.SetTarget(); move.mechIndex = mech.tile.index; move.hasTarget = clickedTile != null; if (move.hasTarget) { move.targetMechIndex = clickedTile.index; } this.ExecuteMove(move); // TODO: Keep mech's dir pointed towards its target, if it has one this.UpdateTargetTile(mech); this.UpdateRightPanel(); this.SetState(BattleState.EndOfAction); } }
public void Init(Game game, BattleHistory battleHistory) { this.game = game; // Copy the history, except for the moves; they'll be applied later. this.history = battleHistory; List <object> moveHistory = battleHistory.moves; this.history.moves = new List <object>(); Scenario scenario = this.history.scenario; BattleMap map = this.history.startingMap; this.mapDisplay.Init(this, map.size); // Build misc objects. { // Let us know when anything on the UI is clicked (and not handled by a button or something). EventTrigger eventTrigger = this.uiRefs.canvas.gameObject.AddComponent <EventTrigger>(); var entry = new EventTrigger.Entry(); entry.eventID = EventTriggerType.PointerClick; entry.callback.AddListener((data) => { var button = ((PointerEventData)data).button; if (button == PointerEventData.InputButton.Left) { this.MouseEvent(null, MapDisplay.MouseEventType.Click); } else if (button == PointerEventData.InputButton.Right) { this.MouseEvent(null, MapDisplay.MouseEventType.RightClick); } }); eventTrigger.triggers.Add(entry); } // Build map. this.mapSize = map.size; this.tiles = new BattleTile[this.mapSize.x * this.mapSize.y]; TileData baseTileData = GameData.GetTile(map.baseTileName); TileData tileData = baseTileData; this.pathNetwork = new PathNetwork(); for (int y = 0; y < map.size.y; ++y) { for (int x = 0; x < map.size.x; ++x) { var pos = new Vector2i(x, y); tileData = baseTileData; foreach (var o in map.tileOverrides) { if (o.pos == pos) { tileData = GameData.GetTile(o.name); break; } } MapTile mapTile = this.mapDisplay.GetTile(pos); BattleTile newTile = mapTile.gameObject.AddComponent <BattleTile>(); newTile.Init(this, x, y, tileData); this.tiles[x + y * this.mapSize.x] = newTile; } } foreach (BattleTile tile in this.tiles) { for (int n = 0; n < 6; ++n) { BattleTile neighbor = tile.GetNeighbor(n); if (neighbor) { this.pathNetwork.ConnectNodes(tile, neighbor); } } if (tile.data.allowsMovement == false) { this.pathNetwork.SetNodeEnabled(tile, false); } } // Create teams and place mechs. var playerSpawns = new Stack <Vector2i>(); var enemySpawns = new Stack <Vector2i>(); foreach (var e in map.entities) { if (e.name == "PlayerMechSpawn") { playerSpawns.Push(e.pos); } else if (e.name == "EnemyMechSpawn") { enemySpawns.Push(e.pos); } } this.teams = new List <BattleTeam>(); foreach (Scenario.Team teamData in scenario.teams) { BattleTeam team = new BattleTeam(); this.teams.Add(team); team.mechs = new List <BattleMech>(); team.isPlayer = teamData.isPlayer; if (team.isPlayer == false) { team.ai = new BattleTeamAi(team); } team.visibleTiles = new bool[this.tiles.Length]; foreach (Scenario.Mech m in teamData.mechs) { MechData mechData = GameData.GetMech(m.mechName); Vector2i spawnPos = team.isPlayer ? playerSpawns.Pop() : enemySpawns.Pop(); BattleTile tile = this.GetTile(spawnPos); GameObject mechGO = new GameObject(string.Concat("Mech: ", mechData.name)); mechGO.transform.parent = tile.transform; BattleMech mech = mechGO.AddComponent <BattleMech>(); mech.Init(this, mechData); mech.PlaceAtMapTile(tile.mapTile); mech.SetDirection(m.direction); Assert.IsTrue(tile.mech == null); tile.mech = mech; mech.tile = tile; if (team.isPlayer == false) { mech.ai = new BattleMechAi(mech); } this.pathNetwork.SetNodeEnabled(tile, false); team.mechs.Add(mech); mech.team = team; } } this.currentTeamIndex = this.history.scenario.startingTeamIndex; this.currentTeam = this.teams[this.currentTeamIndex]; // UI stuff. this.uiRefs.advanceAiButton.interactable = false; this.uiRefs.tileInfoBorder.SetActive(false); this.uiRefs.mechTab.SetActive(false); this.uiRefs.pilotTab.SetActive(false); this.uiRefs.tileTab.SetActive(false); this.uiRefs.actionsPanel.SetActive(false); Utility.AddButtonClickListener(this.uiRefs.finishTurnButton, this.UnitListButtonPressed); Utility.AddButtonClickListener(this.uiRefs.advanceAiButton, this.UnitListButtonPressed); Utility.AddButtonClickListener(this.uiRefs.mechTabButton, this.TileInfoTabButtonClicked); Utility.AddButtonClickListener(this.uiRefs.pilotTabButton, this.TileInfoTabButtonClicked); Utility.AddButtonClickListener(this.uiRefs.tileTabButton, this.TileInfoTabButtonClicked); Utility.AddButtonClickListener(this.uiRefs.moveButton, this.ActionButtonPressed); Utility.AddButtonClickListener(this.uiRefs.setTargetButton, this.ActionButtonPressed); Utility.AddButtonClickListener(this.uiRefs.fireNowButton, this.ActionButtonPressed); Utility.AddToggleListener(this.uiRefs.fireAutoToggle, this.ActionToggleChanged); Utility.AddButtonHoverListener(this.uiRefs.fireNowButton, this.ActionButtonHoverChanged); this.BringTileTabButtonToFront(this.uiRefs.mechTabButton); this.UpdateRightPanel(); this.apTextOriginalColor = this.uiRefs.apText.color; // Execute any moves to start with. foreach (object o in moveHistory) { this.ExecuteMove(o); } this.currentTeamIndex = battleHistory.currentTeamIndex; this.currentTeam = this.teams[this.currentTeamIndex]; // Start first state. this.UpdateFogOfWar(); if (this.currentTeam.isPlayer) { this.SetState(BattleState.SelectingAction); } else { this.SetState(BattleState.AiControl); } }
private void MoveChar(BattleTile destination) { enemy.destinationPoint = destination.gameObject.transform.position; enemy.ChangeState(EnemyStateType.Move); }
public override List <object> Select(BattleManager manager, BattleAgent agent, Dictionary <string, object> selections, bool offense) { string rangeType, targetType; GetRangeAndTarget(agent, selections, out rangeType, out targetType); BattleManhattanDistanceZone range = Skill.GetRange(rangeType, agent); List <object> targets = new List <object>(); if (targetType.StartsWith("All")) { BattleManhattanDistanceZone target = Skill.GetTarget(targetType, agent, range); foreach (Vector2Int point in target) { // count if enemy or ally in space BattleTile tile = manager.grid[point]; if (tile != null && tile.Actor != null) { BattleUnit other = tile.Actor.Agent.Unit; if ((offense && agent.Unit.Opposes(other)) || (!offense && !agent.Unit.Opposes(other))) { targets.Add(target); break; } } } } else { int badMin = int.MaxValue; int goodMax = 0; int bestHealth = offense ? int.MaxValue : 0; foreach (Vector2Int center in range) { BattleManhattanDistanceZone target = Skill.GetTarget(targetType, agent, range); target.Center = center; int badCount = 0; int goodCount = 0; int health = 0; foreach (Vector2Int point in target) { // count if enemy or ally in space BattleTile tile = manager.grid[point]; if (tile != null && tile.Actor != null) { BattleAgent other = tile.Actor.Agent; if (offense) { if (agent.Unit.Opposes(other.Unit)) // is an enemy (good target) { ++goodCount; health += agent.HP; } else // is an ally or neutral (bad target) { ++badCount; } } else { if (agent.Unit.Opposes(other.Unit)) // is an enemy (bad target) { ++badCount; } else // is an ally or neutral (good target) { ++goodCount; health += agent.HP; } } } } if (badCount < badMin || (badCount == badMin && goodCount >= goodMax)) { if (badCount < badMin || goodCount > goodMax) { targets = new List <object>(); badMin = badCount; goodMax = goodCount; bestHealth = health; } else if (health < bestHealth) { targets = new List <object>(); bestHealth = health; } targets.Add(target); } } if (goodMax == 0) { return(new List <object>()); } } return(targets); }
public override BattleAction Update() { m_Manager.grid.Selector.SelectedTile = m_Agent.Coordinates; if (m_Agent["Turn:Action"] <= 0) { return(new BattleEndTurnAction(m_Agent)); } // Find most powerful skill WeaponSkillFilter filter = new WeaponSkillFilter(m_Agent.BaseCharacter); Skill bestSkill = null; float bestPower = float.NegativeInfinity; foreach (Skill skill in filter) { float power = 0f; foreach (SkillEffect effect in skill.Effects) { power += CalculatePower(effect); } if (power > bestPower) { bestSkill = skill; bestPower = power; } } if (bestSkill == null) { return(new BattleEndTurnAction(m_Agent)); } // Select a target BattleManhattanDistanceZone range = Skill.GetRange(bestSkill.Range, m_Agent); List <Vector2Int> options = new List <Vector2Int>(); Vector2Int target; foreach (Vector2Int point in range) { BattleTile tile = m_Manager.grid[point]; if (tile != null && tile.Actor != null) { options.Add(point); } } if (options.Count == 0) { if (m_Agent["Turn:Move"] <= 0) { return(new BattleEndTurnAction(m_Agent)); } // Try to move closer target = TargetNearest(); BattleAction moveAction = MoveWithinRangeOfTarget(target, range); return(moveAction != null ? moveAction : new BattleEndTurnAction(m_Agent)); } else if (options.Count == 1) { target = options[0]; } else { System.Random rand = new System.Random(); target = options[rand.Next() % options.Count]; } BattleManhattanDistanceZone targets = Skill.GetTarget(bestSkill.Target, m_Agent, range); targets.Center = target; return(new BattleSkillAction(m_Agent, bestSkill, targets, 0.01f * m_Agent["Power: " + bestSkill.Element], 1f, 0f)); }
// Called by all 6 of the ListView items when clicked. // Basically clicking in the grid is passed here. Includes the tile that was clicked async void GridListTapped(BattleTile tile) { // If the state of the game is attack phase if (onAttack) { // Checks if the tile is a valid attack target if ((battleSystem.TurnList[0].Row == tile.Row && battleSystem.TurnList[0].Column == tile.Column) || tile.Highlight == "Red") { // Compute the damage of the attack, then feed the results to the records FeedRecords(battleSystem.CharacterAttacks(tile)); // If the battle has ended as a result of the character attacking if (battleSystem.IsBattleOver()) { // Push a new BattleRest page so they can equip stuff loading = false; BattleSystemViewModel.Instance.SetState("BattlePage"); await Navigation.PushModalAsync(new BattleRest(battleSystem.BattleOver(), battleSystem.ItemPool, battleSystem.TotalScore, battleSystem.BattleCount)); } // If the game has ended(since AI can attack after the character attacks) else if (battleSystem.IsGameOver()) { // Push a new ScorePage to display the results of the game Score score = battleSystem.GameOver(); await SQLDataStore.Instance.AddAsync_Score(score); ScoresViewModel.Instance.Dataset.Add(score); ScoresViewModel.Instance.SetNeedsRefresh(true); loading = false; await Navigation.PushModalAsync(new ScoreResults(new ScoreDetailViewModel(score))); } // Otherwise transition from attack mode to move mode then refresh the grid. else { LoadTheGrid(); onAttack = false; } } // If the selected tile is not an attack target, display information about the tile to the user. else { if (tile.Type == "Monster" || tile.Type == "Character") { await DisplayAlert(tile.GetTitleInfo(), tile.GetAllInfo(), "Okay"); } } } // If the state of the game is in move phase else { // Checks if the tile is a valid move location if ((battleSystem.TurnList[0].Row == tile.Row && battleSystem.TurnList[0].Column == tile.Column) || tile.Highlight == "Blue") { // Executes the move, change from move to attack phase, then update the grid. battleSystem.MoveCharacter(tile); onAttack = true; LoadTheGrid(); } // If it is not possible to move here, then the information about the tile is displayed instead else { if (tile.Type == "Monster" || tile.Type == "Character") { await DisplayAlert(tile.GetTitleInfo(), tile.GetAllInfo(), "Okay"); } } } loading = false; }
public void BattleModeSprite() { BattleTile e = GameManager.Battlefied[(int)actor.TilePosition.x, (int)actor.TilePosition.y]; var walking = DistanceToPos > 0f; foreach (var item in anim) { item.SetBool("Walking", walking); } anim[0].SetBool("Defend", actor.Defending); var g = transform.position.x - e.transform.position.x; if (!InverseSprite) { if (g > 0) { transform.rotation = Quaternion.Euler(new Vector3(0, 180, 0)); } else if (g < 0) { transform.rotation = Quaternion.Euler(new Vector3(0, 0, 0)); } } else { if (g > 0) { transform.rotation = Quaternion.Euler(new Vector3(0, 0, 0)); } else if (g < 0) { transform.rotation = Quaternion.Euler(new Vector3(0, 180, 0)); } } for (int i = 0; i < sprity.Length; i++) { var item = sprity[i]; if (i > 0) { item.sprite = sprity[0].sprite; item.flipX = sprity[0].flipX; } } Position = new Vector2(actor.TilePosition.x, actor.TilePosition.y); DistanceToPos = (Vector3.Distance(transform.position, e.transform.position + new Vector3(offset.x, offset.y)) - 90.9f) * 100; var x = 1; this.transform.position = Vector3.Lerp(transform.position, (Vector2)e.transform.position + offset, Speed * x * Time.smoothDeltaTime / (DistanceToPos + .1f)); if (DistanceToPos <= 0.0025f) { BattleOnEnterTile(); } sprity[0].sortingOrder = 2 + (int)actor.TilePosition.y; Indicator.gameObject.SetActive(GameManager.SelectedActor == actor); Indicator.transform.rotation = Quaternion.Euler(Vector3.zero); Indicator.transform.position = e.transform.position; }
// Note: this will be used for replays and maybe save files, so only use data from the move data // and the current state of the map. // Hmmmm, this is starting to seem very independent from the rest of this file. public void ExecuteMove(object o) { if (o.GetType() == typeof(BattleMove.Move)) { var move = (BattleMove.Move)o; Assert.IsTrue( this.GetTile(move.mechIndex).mech != null && this.GetTile(move.newIndex).mech == null && (move.isFiring == false || this.GetTile(move.targetMechIndex).mech != null) ); BattleMech mech = this.GetTile(move.mechIndex).mech; BattleMech targetMech = move.isFiring ? this.GetTile(move.targetMechIndex).mech : null; BattleTile fromTile = mech.tile; BattleTile toTile = this.GetTile(move.newIndex); this.pathNetwork.SetNodeEnabled(fromTile, true); PathingResult result = this.pathNetwork.FindPath(fromTile, toTile); Assert.IsTrue(result.isValid); bool isFiring = move.isFiring; BattleTile prevTile = (BattleTile)result.nodes[0]; for (int n = 1; n < result.nodes.Count; ++n) { BattleTile currentTile = (BattleTile)result.nodes[n]; prevTile.mech = null; currentTile.mech = mech; mech.tile = currentTile; if (isFiring) { bool canSeeTarget = this.TestLOS(currentTile, targetMech.tile); if (canSeeTarget) { this.MechAttack(mech, targetMech); if (targetMech.isDestroyed) { isFiring = false; } } } prevTile = currentTile; } mech.PlaceAtMapTile(toTile.mapTile); BattleTile lastTile1 = (BattleTile)result.nodes[result.nodes.Count - 2]; BattleTile lastTile2 = (BattleTile)result.nodes[result.nodes.Count - 1]; bool right = lastTile2.transform.position.x > lastTile1.transform.position.x; MechDirection newDir = right ? MechDirection.Right : MechDirection.Left; mech.SetDirection(newDir); var apCostResult = mech.GetAPCostForMove(result.nodes); Assert.IsTrue(mech.actionPoints > 0); mech.actionPoints -= apCostResult.ap; this.pathNetwork.SetNodeEnabled(toTile, false); this.UpdateFogOfWar(); } else if (o.GetType() == typeof(BattleMove.StandingFire)) { var move = (BattleMove.StandingFire)o; Assert.IsTrue( this.GetTile(move.mechIndex).mech != null && this.GetTile(move.targetMechIndex).mech != null ); BattleMech mech = this.GetTile(move.mechIndex).mech; BattleMech targetMech = this.GetTile(move.targetMechIndex).mech; this.MechAttack(mech, targetMech); var apCostResult = mech.GetAPCostForStandingFire(); mech.actionPoints -= apCostResult.ap; } else if (o.GetType() == typeof(BattleMove.SetTarget)) { var move = (BattleMove.SetTarget)o; Assert.IsTrue( this.GetTile(move.mechIndex).mech != null && (move.hasTarget == false || this.GetTile(move.targetMechIndex).mech != null) ); BattleMech mech = this.GetTile(move.mechIndex).mech; if (move.hasTarget) { mech.target = this.GetTile(move.targetMechIndex).mech; } else { mech.target = null; } } else { throw new UnityException(); } // Add to battle history. this.history.moves.Add(o); // Determine if this team's turn is over so we can advance the turn. bool hasAP = false; foreach (BattleMech mech in this.currentTeam.mechs) { if (mech.actionPoints > 0) { hasAP = true; break; } } if (hasAP == false) { this.AdvanceTurn(); } }