protected void CmdSetUnit(int x, int y) { if (y == GRID_HEIGHT) { previous_Space = bench[x]; } else { previous_Space = grid[x, y]; } unit_ToMove = previous_Space.unit.gameObject; }
//Add an element to the open list, sorting it by position relative to its //f cost private void AddElement(List <GridSpace> openList, GridSpace element) { for (int i = 0; i < openList.Count; i++) { if (element.f < openList[i].f) { openList.Insert(i, element); return; } } openList.Add(element); }
protected void CmdPlaceUnit(GameObject grid_Object) { GridSpace new_Spot = grid_Object.GetComponent <GridSpace>(); Character character = unit_ToMove.GetComponent <Character>(); if (new_Spot.unit == null) { new_Spot.AddCharacter(character); previous_Space.RemoveCharacter(); if (previous_Space.transform.position.z <= benchZPosition && new_Spot.transform.position.z > benchZPosition) { BenchToField(bench_Units.IndexOf(character)); } else if (previous_Space.transform.position.z > benchZPosition && new_Spot.transform.position.z <= benchZPosition) { FieldToBench(field_Units.IndexOf(character)); } TargetPlaceUnit(grid_Object); ResetHeldUnit(); } else if (new_Spot != previous_Space) { Character previous_Unit = character; character = new_Spot.unit; if (previous_Space.transform.position.z <= -6.5f && new_Spot.transform.position.z > -6.5f) { FieldToBench(field_Units.IndexOf(character)); BenchToField(bench_Units.IndexOf(previous_Unit)); } else if (previous_Space.transform.position.z > -6.5f && new_Spot.transform.position.z <= -6.5f) { BenchToField(bench_Units.IndexOf(character)); FieldToBench(field_Units.IndexOf(previous_Unit)); } new_Spot.AddCharacter(previous_Unit); previous_Space.AddCharacter(character); TargetPlaceUnit(grid_Object); ResetHeldUnit(); } else { previous_Space.ResetUnitPosition(); TargetPlaceUnit(grid_Object); ResetHeldUnit(); } }
//Move the character according to their path public bool Moving(int current_Distance) { //Debug.Log(next_Space); //If the character does not have a path if (path == null) { return(false); } if (Vector3.Distance(transform.position, next_Space.transform.position) <= 0.1) { transform.position = next_Space.transform.position; future_Distance = (int)Vector2.Distance(grid_Position, target.grid_Position + target.future_Position); //If there are no more tiles to follow, or if the distance //between the target and this character grows, //Change path if (current_Distance <= range) { FaceDirection(new Vector2(target.transform.position.x, target.transform.position.z)); ResetPath(); return(false); } if (path.Count == 0 || current_Distance >= future_Distance) { ResetPath(); return(false); } //Get a new space to find next_Space.combat_Unit = null; next_Space = path.Pop(); //Change path if the next space is occupied if (next_Space.combat_Unit != null) { ResetPath(); return(false); } //Add the character to the path next_Space.AddCombatCharacter(this); future_Position = next_Space.grid_Position; FaceDirection(new Vector2(next_Space.transform.position.x, next_Space.transform.position.z)); } transform.position = Vector3.Lerp(transform.position, next_Space.transform.position, 0.1f); return(true); }
//protected override void CmdBenchToField(Character unit) //{ // bench_Units.Remove(unit); // field_Units.Add(unit); // foreach (Character c in field_Units) // { // if (unit.name == c.name && c != unit) // { // return; // } // } // foreach (ATTRIBUTES o in unit.attributes) // { // if (p_Attributes.ContainsKey(o)) p_Attributes[o]++; // else p_Attributes.Add(o, 1); // CheckAttributes(o); // } //} // //protected override void CmdFieldToBench(Character unit) //{ // field_Units.Remove(unit); // bench_Units.Add(unit); // foreach (Character c in field_Units) // { // if (unit.name == c.name && unit != c) // { // return; // } // } // foreach (ATTRIBUTES o in unit.attributes) // { // if (p_Attributes.ContainsKey(o)) p_Attributes[o]--; // CheckAttributes(o); // if (p_Attributes[o] == 0) p_Attributes.Remove(o); // } //} public void SetupGrid() { grid = new GridSpace[GRID_WIDTH, GRID_HEIGHT]; bench = new GridSpace[GRID_WIDTH]; if (isServer) { RpcCreateBoard(); } for (short i = 0; i < GRID_WIDTH; i++) { GameObject benchSpot = Instantiate <GameObject>(gridPrefab); benchSpot.transform.SetParent(transform); benchSpot.transform.SetPositionAndRotation(new Vector3(transform.position.x + i - 4, 0, transform.position.z + 6), Quaternion.Euler(Vector3.zero)); NetworkServer.Spawn(benchSpot, connectionToClient); if (isServer) { RpcSetBenchSpot(i, benchSpot); } bench[i] = benchSpot.GetComponent <GridSpace>(); bench[i].SetGridPosition(new Vector2(i, GRID_HEIGHT)); for (short j = 0; j < GRID_HEIGHT; j++) { GameObject gridSpot = Instantiate <GameObject>(gridPrefab); gridSpot.transform.SetParent(transform); gridSpot.transform.SetPositionAndRotation(new Vector3(transform.position.x + i - 4, 0, transform.position.z + 8 + (j % GRID_HEIGHT)), Quaternion.Euler(Vector3.zero)); NetworkServer.Spawn(gridSpot, connectionToClient); if (isServer) { RpcSetGridSpot(i, j, gridSpot); } grid[i, j] = gridSpot.GetComponent <GridSpace>(); grid[i, j].SetGridPosition(new Vector2(i, j)); } } Character character = Instantiate <Character>(characterPrefab); character.transform.SetParent(transform); character.transform.rotation = Quaternion.Euler(Vector3.zero); NetworkServer.Spawn(character.gameObject); //CmdBenchToField(character); grid[7, 3].AddCharacter(character); }
//Reset the unit being held so that //a new one can be acquired private void ResetHeldUnit() { unit_ToMove = null; previous_Space = null; dragging_Unit = false; }
//CALLED EVERY FRAME public virtual void Update() { if (!isLocalPlayer) { return; } if (readyToSetup && grid == null) { CmdSetUpPlayerGrid(); } //Check if the player is holding a unit and they clicked if (dragging_Unit) { //Put out raycast on Gridpositions LayerMask mask = 1 << 8; //Plane layer ProjectRay(mask); unit_ToMove.transform.position = hit.point; //Check if the unit we're holding is an item or character if (Input.GetMouseButtonDown(0)) { if (!unit_ToMove.GetComponent <Item>()) { //Checks if we're trying to sell a unit by shooting out a graphical raycast at specific ui elements mask = 1 << 10; //Grid layer ProjectGraphicalRay(); if (ui_Results.Count != 0 && !unit_ToMove.GetComponent <Item>() && ui_Results[0].gameObject.name == "ShopBackground") { Character character = unit_ToMove.GetComponent <Character>(); SellUnit(character); } //If we hit anything with our initial raycast we want to place the unit there else if (ProjectRay(mask)) { CmdPlaceUnit(hit.transform.gameObject); } //If the raycast hits nothing we want to place the unit in its original position and reset the held unit else { previous_Space.ResetUnitPosition(); ResetHeldUnit(); } } //If the unit we're holding is an item we go in here else { //Checking if the player clicked on a character mask = 1 << 9; //Character layer if (ProjectRay(mask)) { Character clickedChar = hit.transform.gameObject.GetComponent <Character>(); //Add item to characters list if there is room PlaceItem(clickedChar); } //If we don't click on a unit, place the item back to its original spot else { unit_ToMove.transform.position = previousItemSpot; ResetHeldUnit(); } } } } else if (Input.GetMouseButtonDown(0)) { //If player left clicks while nothing is done here we do this LayerMask unitMask = 1 << 9; //Character layer //Checks if we clicked a character if (ProjectRay(unitMask)) { //Find the space occupied by the character Character character = hit.transform.gameObject.GetComponent <Character>(); if (!character.GetComponent <NetworkIdentity>().hasAuthority) { return; } if (recentSpace != null) { Debug.Log(recentSpace.grid_Position); } int x = (int)character.grid_Position.x; int y = (int)character.grid_Position.y; if (y == GRID_HEIGHT) { previous_Space = bench[x]; } else { previous_Space = grid[x, y]; } unit_ToMove = previous_Space.unit.gameObject; CmdSetUnit(x, y); dragging_Unit = true; } //Checking if we clicked an item else if (ProjectRay(1 << 12)) { unit_ToMove = hit.transform.gameObject; dragging_Unit = true; } } }
//Perform an A* search to determine an optimal path to an un-specific target //based on the character's range private void FindTarget(Character character) { //Reset the grid for (short i = 0; i < 8; i++) { for (short j = 0; j < 8; j++) { grid[j, i].ResetCosts(); } } //Initialize the open and closed lists List <GridSpace> openList = new List <GridSpace>(); bool[,] closedList = new bool[8, 8]; //Get the first space which is the space currently occupied by //the character GridSpace space = grid[(int)character.grid_Position.x, (int)character.grid_Position.y]; space.f = (int)Vector2.Distance(character.grid_Position, character.target.grid_Position); space.g = 0; space.h = 0; space.parent_Position = space.grid_Position; openList.Add(space); while (openList.Count > 0) { //Remove the space from the openlist and //add it to the closed list space = openList[0]; openList.RemoveAt(0); int x = (int)space.grid_Position.x; int y = (int)space.grid_Position.y; closedList[x, y] = true; float g, f, h; //WEST SUCCESSOR if (IsValid(x - 1, y)) { if (IsOptimal(character.target.grid_Position, grid[x - 1, y].grid_Position, character.range)) { grid[x - 1, y].parent_Position = space.grid_Position; CalculatePath(character, new Vector2(x - 1, y)); return; } if (!closedList[x - 1, y]) { g = grid[x, y].g + 1; h = CalculateHeuristic(character.target.grid_Position, grid[x - 1, y].grid_Position); f = g + h; if (grid[x - 1, y].f > f) { UpdateSpace(x - 1, y, f, g, h, space.grid_Position); AddElement(openList, grid[x - 1, y]); } } } //EAST SUCCESSOR if (IsValid(x + 1, y)) { if (IsOptimal(character.target.grid_Position, grid[x + 1, y].grid_Position, character.range)) { grid[x + 1, y].parent_Position = space.grid_Position; CalculatePath(character, new Vector2(x + 1, y)); return; } if (!closedList[x + 1, y]) { g = grid[x, y].g + 1; h = CalculateHeuristic(character.target.grid_Position, grid[x + 1, y].grid_Position); f = g + h; if (grid[x + 1, y].f > f) { UpdateSpace(x + 1, y, f, g, h, space.grid_Position); AddElement(openList, grid[x + 1, y]); } } } //NORTH SUCCESSOR if (IsValid(x, y + 1)) { if (IsOptimal(character.target.grid_Position, grid[x, y + 1].grid_Position, character.range)) { grid[x, y + 1].parent_Position = space.grid_Position; CalculatePath(character, new Vector2(x, y + 1)); return; } if (!closedList[x, y + 1]) { g = grid[x, y].g + 1; h = CalculateHeuristic(character.target.grid_Position, grid[x, y + 1].grid_Position); f = g + h; if (grid[x, y + 1].f > f) { UpdateSpace(x, y + 1, f, g, h, space.grid_Position); AddElement(openList, grid[x, y + 1]); } } } //SOUTH SUCCESSOR if (IsValid(x, y - 1)) { if (IsOptimal(character.target.grid_Position, grid[x, y - 1].grid_Position, character.range)) { grid[x, y - 1].parent_Position = space.grid_Position; CalculatePath(character, new Vector2(x, y - 1)); return; } if (!closedList[x, y - 1]) { g = grid[x, y].g + 1; h = CalculateHeuristic(character.target.grid_Position, grid[x, y - 1].grid_Position); f = g + h; if (grid[x, y - 1].f > f) { UpdateSpace(x, y - 1, f, g, h, space.grid_Position); AddElement(openList, grid[x, y - 1]); } } } //NORTHEAST SUCCESSOR if (IsValid(x + 1, y + 1)) { if (IsOptimal(character.target.grid_Position, grid[x + 1, y + 1].grid_Position, character.range)) { grid[x + 1, y + 1].parent_Position = space.grid_Position; CalculatePath(character, new Vector2(x + 1, y + 1)); return; } if (!closedList[x + 1, y + 1]) { g = grid[x, y].g + 1.414f; h = CalculateHeuristic(character.target.grid_Position, grid[x + 1, y + 1].grid_Position); f = g + h; if (grid[x + 1, y + 1].f > f) { UpdateSpace(x + 1, y + 1, f, g, h, space.grid_Position); AddElement(openList, grid[x + 1, y + 1]); } } } //NORTHWEST SUCCESSOR if (IsValid(x - 1, y + 1)) { if (IsOptimal(character.target.grid_Position, grid[x - 1, y + 1].grid_Position, character.range)) { grid[x - 1, y + 1].parent_Position = space.grid_Position; CalculatePath(character, new Vector2(x - 1, y + 1)); return; } if (!closedList[x - 1, y + 1]) { g = grid[x, y].g + 1.414f; h = CalculateHeuristic(character.target.grid_Position, grid[x - 1, y + 1].grid_Position); f = g + h; if (grid[x - 1, y + 1].f > f) { UpdateSpace(x - 1, y + 1, f, g, h, space.grid_Position); AddElement(openList, grid[x - 1, y + 1]); } } } //SOUTHEAST SUCCESSOR if (IsValid(x + 1, y - 1)) { if (IsOptimal(character.target.grid_Position, grid[x + 1, y - 1].grid_Position, character.range)) { grid[x + 1, y - 1].parent_Position = space.grid_Position; CalculatePath(character, new Vector2(x + 1, y - 1)); return; } if (!closedList[x + 1, y - 1]) { g = grid[x, y].g + 1.414f; h = CalculateHeuristic(character.target.grid_Position, grid[x + 1, y - 1].grid_Position); f = g + h; if (grid[x + 1, y - 1].f > f) { UpdateSpace(x + 1, y - 1, f, g, h, space.grid_Position); AddElement(openList, grid[x + 1, y - 1]); } } } //SOUTHWEST SUCCESSOR if (IsValid(x - 1, y - 1)) { if (IsOptimal(character.target.grid_Position, grid[x - 1, y - 1].grid_Position, character.range)) { grid[x - 1, y - 1].parent_Position = space.grid_Position; CalculatePath(character, new Vector2(x - 1, y - 1)); return; } if (!closedList[x - 1, y - 1]) { g = grid[x, y].g + 1.414f; h = CalculateHeuristic(character.target.grid_Position, grid[x - 1, y - 1].grid_Position); f = g + h; if (grid[x - 1, y - 1].f > f) { UpdateSpace(x - 1, y - 1, f, g, h, space.grid_Position); AddElement(openList, grid[x - 1, y - 1]); } } } } }