public void InstantiatePrefab(Vector3 location, RUnit unit) { GameObject newGameObject; if (unit.unitType == UnitType.Army) { newGameObject = ArmyPrefab; } else if (unit.unitType == UnitType.Fortress) { newGameObject = FortressPrefab; } else if (unit.unitType == UnitType.Spy) { newGameObject = SpyPrefab; } else { newGameObject = ArmyPrefab; } Transform parent = this.transform; GameObject newUnit = Instantiate(newGameObject, location, Quaternion.identity, parent); gameController.SyncSceneUnitToDictionaryUnit(unit, newUnit); }
public void SetUnitHUDValues(RUnit unit) { unitHUDType.text = unit.unitType.ToString(); unitHUDStrength.text = "Strength: " + unit.strength.ToString(); unitHUDMoves.text = "Moves Left: " + unit.numMoves.ToString(); unitHUDDefensiveBonus.text = "Defensive Bonus: " + unit.defensiveBonus.ToString(); }
void SelectThisUnit() { RUnit squareDictionaryRunit = gameController.game.squareDictionary [coords].unitOccupyingSquare; board.DeselectPiece(); //deslect the original piece, hide the movement squares etc. InstantiateUnitMount(); //create the spinning gold circle that shows what unit is selected //select the unit in gameController gameController.selectedUnit = squareDictionaryRunit; gameController.unitSelected = true; gameController.selectedGameObject = this.gameObject; //update the unit HUD and show it uiController.SetUnitHUDValues(squareDictionaryRunit); uiController.ShowHUD(uiController.UnitHUD); //If the unit has a move left, show possible squares, if not flash red on the unitHUD number of moves. if (numMoves > 0) { int[] intCoords = gameController.ConvertStringToArray(squareDictionaryRunit.coords, 2); board.ShowPossibleSquares(intCoords, squareDictionaryRunit); } else { StartCoroutine(uiController.MakeTextFlashRed(uiController.unitHUDMoves)); Debug.Log("You don't have enough moves left for this piece"); } }
public void PlaceUnit(RUnit unit) { int[] coords = gameController.ConvertStringToArray(unit.coords, 2); RArmySpawner armySpawner = unit.allegiance == Mark.CON ? CONArmySpawner : USArmySpawner; Vector3 location = new Vector3(coords [0] + 0.5f, 0.05f, coords [1] + 0.5f); armySpawner.InstantiatePrefab(location, unit); }
public void DestroyUnitByUnitDictionary(RUnit unitToDestroy){ RUnit[] allUnits = FindObjectsOfType<RUnit> (); foreach (RUnit thisUnit in allUnits) { if (thisUnit.coords == unitToDestroy.coords) { Destroy (thisUnit.gameObject); } } }
public void SyncSceneUnitToDictionaryUnit(RUnit squareDictionaryRUnit, GameObject unitInScene){ UnitObject unitInstanceInScene = unitInScene.GetComponent<UnitObject> (); unitInstanceInScene.allegiance = squareDictionaryRUnit.allegiance; unitInstanceInScene.coords = squareDictionaryRUnit.coords; unitInstanceInScene.numMoves = squareDictionaryRUnit.numMoves; unitInstanceInScene.unitType = squareDictionaryRUnit.unitType; unitInstanceInScene.defensiveBonus = squareDictionaryRUnit.defensiveBonus; unitInstanceInScene.strength = squareDictionaryRUnit.strength; }
public GameObject FindSceneUnitGameObjectBySquareDictionaryRUnit(RUnit unitToFind){ RUnit[] allUnits = FindObjectsOfType<RUnit> (); foreach (RUnit thisUnit in allUnits) { if (thisUnit.coords == unitToFind.coords) { //Debug.Log ("successfully found gameobject"); return thisUnit.gameObject; } } Debug.Log ("did not find a gameobject of the coords " + unitToFind.coords); return null; }
public void MovePiece(RUnit pieceToMove, string coordsToMoveTo) { string originalCoords = pieceToMove.coords; squareDictionary [coordsToMoveTo].unitOccupyingSquare = pieceToMove; squareDictionary [coordsToMoveTo].squareOccupied = true; squareDictionary [coordsToMoveTo].unitOccupyingSquare.coords = coordsToMoveTo; squareDictionary [coordsToMoveTo].unitOccupyingSquare.numMoves -= 1; squareDictionary[originalCoords].unitOccupyingSquare = null; squareDictionary [originalCoords].squareOccupied = false; //Debug.Log ("Unit has been moved from " + selectedPieceCoords + " to " + squareClickedCoords + " and this is confirmed in the squareDictionary because the new square we clicked on has this unit on it " + squareDictionary [squareClickedCoords].unitOccupyingSquare + " and the original square is now empty (false if true) " + squareDictionary [selectedPieceCoords].squareOccupied); }
public void MergePiece(string coordsOfOriginalPiece, string coordsOfPieceToMergeWith) { RUnit mergePiece = squareDictionary [coordsOfPieceToMergeWith].unitOccupyingSquare; RUnit originalPiece = squareDictionary [coordsOfOriginalPiece].unitOccupyingSquare; if (mergePiece.numMoves > 0 && originalPiece.numMoves > 0) { mergePiece.strength += originalPiece.strength; mergePiece.numMoves -= 1; } DestroyPiece(coordsOfOriginalPiece); }
public void CheckDefensiveBonus(RUnit squareDictionaryUnit){ if (game.squareDictionary [squareDictionaryUnit.coords].isCitySquare) { int defensiveBonus = game.squareDictionary [squareDictionaryUnit.coords].cityOccupyingSquare.baseDefence; squareDictionaryUnit.AddDefensiveBonus (defensiveBonus); } else { squareDictionaryUnit.RemoveDefensiveBonus (); } SyncSceneUnitToDictionaryUnit (squareDictionaryUnit, FindSceneUnitGameObjectBySquareDictionaryRUnit (squareDictionaryUnit)); }
IEnumerator DequeuePieces() { foreach (KeyValuePair <string, int[]> keyValue in enquedPieceMovement) { string originalCoords = keyValue.Key; int[] coordsToMoveTo = keyValue.Value; Debug.Log("dequeue pieces" + "original coords: " + originalCoords + " , coordsToMoveTo: " + coordsToMoveTo[0] + " , " + coordsToMoveTo[1]); RUnit unit = gameController.game.squareDictionary [originalCoords].unitOccupyingSquare; GameObject gameObjectOfUnit = gameController.FindSceneUnitGameObjectBySquareDictionaryRUnit(unit); yield return(StartCoroutine(WaitAndMove(1.0f, gameObjectOfUnit, coordsToMoveTo))); } ClearEnqueuedItems(); yield return(StartCoroutine(WaitAndRefreshBoard(1.0f))); uiController.ToggleShowPreventUserInputPanel(""); //Should toggle off }
//DEBUG ZONE public void InstantiateConUnit(string coords) { //allows creation of CON units from the UI RBoard board = FindObjectOfType <RBoard> (); if (gameController.game.squareDictionary [coords].squareOccupied) { Debug.Log("ERROR: can't create unit here as it is already occupied!"); } else { gameController.game.ConstructNewUnit(coords, RLookout.Mark.CON, RLookout.UnitType.Army, 5000); RUnit newUnit = gameController.game.squareDictionary [coords].unitOccupyingSquare; board.PlaceUnit(newUnit); board.RegenerateFogOfWar(); } }
public void DestroyPiece(string coords) { RUnit squareUnit = gameController.game.squareDictionary [coords].unitOccupyingSquare; RUnit[] allunits = FindObjectsOfType <RUnit> (); GameObject theUnit = null; foreach (RUnit unit in allunits) { if (unit.coords == squareUnit.coords) { theUnit = unit.gameObject; } } Destroy(theUnit); }
// public IEnumerator CoroutineMoveTowards (int[] intCoords){ // yield return new WaitForSeconds (3); // Debug.Log ("coroutineMoveTowardscalled"); // float[] newCords = new float[2]; // newCords [0] = intCoords [0] + 0.5f; // newCords [1] = intCoords [1] + 0.5f; // //// moveToCoords[0] = intCoords[0] + 0.5f; //// moveToCoords[1] = intCoords[1] + 0.5f; // startMoving = true; // // if (startMoving) { // float step = speed * Time.deltaTime; // Vector3 TargetPosition = new Vector3 (newCords [0], 0.05f, newCords [1]); // transform.position = Vector3.MoveTowards (transform.position, TargetPosition, step); // // if (transform.position == TargetPosition) { // startMoving = false; // moveToCoords = null; // // } // // } // // } public void SplitUnit() { Debug.Log("Unit split requested"); RUnit squareDictionaryRUnit = gameController.FindSquareDictionrayUnitByCoords(coords); strength = strength / 2; squareDictionaryRUnit.strength = strength; //Get a random square that is available for this unit to move into , in order to instantiate the new piece into. int[] coordsToInstantiateSplitUnit = board.possibleMovementCoords [Random.Range(0, board.possibleMovementCoords.Count)]; // get a random avaialbe square that this piece could have moved into that we can place the piece in, string stringCoordsToInstantiateSplitUnit = gameController.ConvertArrayToString(coordsToInstantiateSplitUnit); //convert these coords to string gameController.game.ConstructNewUnit(stringCoordsToInstantiateSplitUnit, allegiance, unitType, strength); //create a new unit in the SquareDictionary gameController.game.squareDictionary [stringCoordsToInstantiateSplitUnit].unitOccupyingSquare.numMoves = 0; // set the new units numMOves to 0; board.PlaceUnit(gameController.game.squareDictionary [stringCoordsToInstantiateSplitUnit].unitOccupyingSquare); // and now instantiate this piece on the actual board board.RegenerateFogOfWar(); //regenerate fog of war (as the unit might have been placed on the border //Take a move and sync this unit to the game.squareDictionary RUnit. squareDictionaryRUnit.numMoves -= 1; //take a move gameController.SyncSceneUnitToDictionaryUnit(squareDictionaryRUnit, this.gameObject); // and sync this unit's value to the dictionary above. board.DeselectPiece(); //clear the selector squares, hide the UnitHUD and deselect the unit in gameController. }
public void ConstructNewUnit(string Coords, Mark allegiance, UnitType unitType, int strength) { //GameObject obj = new GameObject (); RUnit newUnit = new RUnit(); newUnit.allegiance = allegiance; newUnit.strength = strength; newUnit.unitType = unitType; newUnit.coords = Coords; //newUnit.name = "New " + allegiance.ToString () + " Army"; if (unitType == UnitType.Army) { newUnit.numMoves = 1; } else if (unitType == UnitType.Fortress) { newUnit.numMoves = 0; } else if (unitType == UnitType.None) { newUnit.numMoves = 0; } else if (unitType == UnitType.Spy) { newUnit.numMoves = 2; } else { Debug.Log("RGame says that you haven't defined the number of moves for the unit type you are trying to construct in ConstructNewUnit. The unitType is " + unitType); } squareDictionary [Coords].unitOccupyingSquare = newUnit; squareDictionary [Coords].squareOccupied = true; //Debug.Log ("this is new" + squareDictionary [Coords].squareOccupied); //Debug.Log("Construct New Unit: " + squareDictionary[Coords].unitOccupyingSquare.ToString()); }
void OnBoardSquareClicked(object args){ //the args are teh coords of the square clicked on. Debug.Log ("onboardsquareclicked"); if (!enqueueSystem.preventInput) { //prevents bug where user could click in a millisecond before the prevent input panel came up. This panel comes up to prevent user from taking moves before ethey's seen the other player's moves. int[] squareClickedIntCoords = (int[]) args; string squareClickedStringCoords = ConvertArrayToString (squareClickedIntCoords); //Debug.Log ("boardsquareclicked and enque system hasn't prevented input"); if (unitSelected) { // Debug.Log ("unit selected"); // A piece is currently selected if (game.control == localPlayerController.myAllegiance) { //if it is my turn; // Debug.Log (" a piece is selected"); for (int i = 0; i < board.possibleMovementCoords.Count; i++) { //if there is a square which this piece can move to int[] possibleMovementCoords = board.possibleMovementCoords [i]; if (possibleMovementCoords [0] == squareClickedIntCoords [0] && possibleMovementCoords [1] == squareClickedIntCoords [1]) { //Move piece to location GameObject gameObjectRunitOfSelectedPiece = FindSceneUnitGameObjectBySquareDictionaryRUnit (selectedUnit); enqueueSystem.enquedPieceMovement.Add (selectedUnit.coords, squareClickedIntCoords); //enqueues movement for next player so they can see what moves the enemy took; selectedGameObject.GetComponent<UnitObject> ().MoveTowardsAPlace (squareClickedIntCoords); //physicallymoveunit game.MovePiece (selectedUnit, squareClickedStringCoords); //move the unit in the unitDictionary - may be worth putting this in its own method here. SyncSceneUnitToDictionaryUnit (selectedUnit, selectedGameObject); //syncs the values in the Runit component on the board with the SquareDictionary values in the Game. CheckDefensiveBonus (selectedUnit); board.DeselectPiece (); //hides the unit info HUD, deselects the piece in here and sets the gameController unitSelected values etc to null; game.CheckForGameOver (); } } for (int i = 0; i < board.mergeableSquareCoords.Count; i++) { int[] intArray = board.mergeableSquareCoords [i]; if (intArray [0] == squareClickedIntCoords [0] && intArray [1] == squareClickedIntCoords [1]) { //Debug.Log("merge piece requested"); mergeUnit = FindSquareDictionrayUnitByCoords(squareClickedStringCoords); //Debug.Log (mergeUnit.coords + " merge unit coords are this and is there a unit occupying square? " + game.squareDictionary[stringCoords].squareOccupied + " and stringcoords are " + stringCoords); if (selectedUnit.numMoves > 0 && mergeUnit.numMoves > 0) { //tells UI controlelr to request merge or not. UnityAction mergeAction = new UnityAction (() => { uiController.MergeUnits (); //hides hUD and calls Gamecontroller.MergeUnits }); UnityAction cancelAction = new UnityAction (() => { uiController.CancelInput(); //cancels the merge; }); uiController.PromptUser("Do you want to merge units of strength " + selectedUnit.strength + " and new unit " + mergeUnit.strength + "?", mergeAction, cancelAction); } else { uiController.SetBasicInfoText ("Both units don't have enough moves to merge!", "Sorry!"); uiController.ShowHUD (uiController.BasicInfoPopup); } } } for (int i = 0; i < board.battleSquareCoords.Count; i++) { //loop through all the squares that have been identified as battle squares int[] thisSquareIntCoords = board.battleSquareCoords [i]; //the coords of this partciular battle square if (thisSquareIntCoords [0] == squareClickedIntCoords [0] && thisSquareIntCoords [1] == squareClickedIntCoords [1]) { //if this is the same square that has been clicked on enqueueSystem.enquedPieceMovement.Add (selectedGameObject.GetComponent<RUnit> ().coords, squareClickedIntCoords); selectedGameObject.GetComponent<UnitObject> ().MoveTowardsAPlace (squareClickedIntCoords); Debug.Log ("battle square coords are " + ConvertArrayToString(squareClickedIntCoords)); selectedGameObject.GetComponent<UnitObject> ().ShowBattle (squareClickedIntCoords); RUnit defender = FindSquareDictionrayUnitByCoords (squareClickedStringCoords); RUnit attacker = selectedUnit; Mark battleWinner = game.DoBattle (attacker, defender); int defenderStartStrength = defender.strength; int attackerStartStrength = attacker.strength; if (battleWinner == attacker.allegiance) { //then it is the attacker that has won Battle thisBattle = game.battleHistory [game.battleHistory.Count - 1]; uiController.SetBasicInfoText ("Glorious Victory! Your losses were " + thisBattle.GetLossLevel (attacker.allegiance) + "!", "For God and Country!!"); uiController.ShowHUD (uiController.BasicInfoPopup); uiController.HideHUD (uiController.UnitHUD); DestroyUnitByUnitDictionary (defender); CheckDefensiveBonus (attacker); //as the attacker may have just taken over a city, check their defensive bonus; SyncSceneUnitToDictionaryUnit (attacker, selectedGameObject); } else if (battleWinner == Mark.None) { Battle thisBattle = game.battleHistory [game.battleHistory.Count - 1]; uiController.SetBasicInfoText ("Stalemate! Your losses were " + thisBattle.GetLossLevel (attacker.allegiance) + ". Spies report that enemy losses were " + thisBattle.GetLossLevel(defender.allegiance), "Okay"); uiController.ShowHUD (uiController.BasicInfoPopup); uiController.HideHUD (uiController.UnitHUD); Debug.Log ("stalemate and attacker original coords are " + attacker.coords); int[] coordsToMoveTo = new int[2]; coordsToMoveTo = ConvertStringToArray(attacker.coords, 2); selectedGameObject.GetComponent<UnitObject> ().MoveTowardsAPlace (coordsToMoveTo); SyncSceneUnitToDictionaryUnit (attacker, selectedGameObject); SyncSceneUnitToDictionaryUnit (defender, FindSceneUnitGameObjectBySquareDictionaryRUnit (defender)); }else{ uiController.SetBasicInfoText ("Disaster! Your troops have been routed!", "Retreat!"); uiController.ShowHUD (uiController.BasicInfoPopup); DestroyUnitByUnitDictionary (attacker); SyncSceneUnitToDictionaryUnit (defender, FindSceneUnitGameObjectBySquareDictionaryRUnit (defender)); } board.DeselectPiece (); game.CheckForGameOver (); } } // a piece is currently selected } } } board.RegenerateFogOfWar (); CheckCityOccupiedStatus (); }
public void ShowPossibleSquares(int[] intCoords, RUnit unit) { //After clicking on one of your units, show the squares that you can move to, take and merge with. //Debug.Log ("Show Possible Squares called"); ClearAllSelectorSquares(); // if any are already instantiated for any reason, clear this and the lists that contain the movement squares etc. GameObject selectionSquare; if (unit.unitType == UnitType.Army) { for (int x = -1; x <= 1; x++) { for (int z = -1; z <= 1; z++) { Vector3 selectorCoord = new Vector3(); selectorCoord.x = intCoords [0] + x + 0.5f; selectorCoord.z = intCoords [1] + z + 0.5f; int[] positionCoords = new int[] { intCoords[0] + x, intCoords[1] + z }; string coordsAsString = gameController.ConvertArrayToString(positionCoords); if (selectorCoord.x < 0.5f || selectorCoord.z < 0.5f || selectorCoord.x > gameController.game.boardWidth || selectorCoord.z > gameController.game.boardHeight) { // don't instantiate out of range ie. do nothing (return cancels the loop) } else if (gameController.game.squareDictionary [coordsAsString].squareOccupied) { //if there is a unit there if (gameController.game.squareDictionary [coordsAsString].unitOccupyingSquare.allegiance == unit.allegiance && gameController.game.squareDictionary [coordsAsString].unitOccupyingSquare.unitType == UnitType.Army) { //if it is a unit of my allegiance there if (unit.coords != coordsAsString) { //stops a blue square forming on original position; selectionSquare = blueSelectionSquarePrefab; mergeableSquareCoords.Add(positionCoords); GameObject newUnit = Instantiate(selectionSquare, selectorCoord, Quaternion.identity, selectionSquaresSpawner); newUnit.tag = "selectorSquare"; } else { //if we want to instantiate a special square that says where it came from. } } else if (gameController.game.squareDictionary [coordsAsString].unitOccupyingSquare.allegiance == unit.allegiance && gameController.game.squareDictionary [coordsAsString].unitOccupyingSquare.unitType == UnitType.Fortress) { //If the unit in that space is a fortress of my allegiance then do nothing } else { //if it is an enemy unit there selectionSquare = redSelectionSquarePrefab; battleSquareCoords.Add(positionCoords); GameObject newUnit = Instantiate(selectionSquare, selectorCoord, Quaternion.identity, selectionSquaresSpawner); newUnit.tag = "selectorSquare"; } } else { //there is no unit there and it is a moveable square selectionSquare = greenSelectionSquarePrefab; GameObject newUnit = Instantiate(selectionSquare, selectorCoord, Quaternion.identity, selectionSquaresSpawner); newUnit.tag = "selectorSquare"; possibleMovementCoords.Add(positionCoords); } } } } }
public Mark DoBattle(RUnit attacker, RUnit defender) { //Definitions Mark battleWinner = Mark.None; //overall winner (can be stalemate) // Mark winner = Mark.None; //nominal winner (i.e. they lost fewer troops) // Mark loser = Mark.None; //nominalloser string attackerCoords = attacker.coords; string defenderCoords = defender.coords; Battle newBattle = new Battle(); //Set relative strengths of attacker and defender. Defenders might have an additional defensive bonus in place (e.g. if in a city). int attackerStrength = attacker.strength; int defenderStrength = defender.strength + defender.defensiveBonus; Debug.Log("attacker strength is " + attackerStrength + " and defender strength is " + defenderStrength); //Set the advantage multipliers. By default attacker is set to 1 and defender is set to 1.333 to simulate defensive bonus // the attackers multiplier could be changed by other factors (e.g. leadership etc) in future. float attackerAdvantageMultiplier = 1f; float defenderAdvantageMultiplier = 4f / 3f; Debug.Log("attacker advantage is " + attackerAdvantageMultiplier + " and defender advantage is " + defenderAdvantageMultiplier); // randomizers give a random advantage to either defender or attacker and are separated in case we wish to further give more advantages float attackerRandomizer = Random.Range(0.1f, 10f); float defenderRandomizer = Random.Range(0.1f, 10f); Debug.Log("attacker randomizer is " + attackerRandomizer + " and defender randomizer is " + defenderRandomizer); //Odds are the relative proporiton of strength once al the above variables are added in. // For now it is based aroudn the attacker strength divided by defender strength times by multiplier and randomizer. float attackerOdds = ((0.5f * (attackerStrength / defenderStrength)) * attackerAdvantageMultiplier) * attackerRandomizer; float defenderOdds = ((0.5f * (defenderStrength / attackerStrength)) * defenderAdvantageMultiplier) * defenderRandomizer; Debug.Log("Attacker odds are: " + attackerOdds + " but defender odds are " + defenderOdds); //defines the nominal winner (i.e. who technically lost fewer percent of troops) - N.B. not the Battle winner (as an indecisive victory has the same technical effect as a stalemate). // if (attackerOdds > defenderOdds) { // //Then it is an attacker win; // winner = attacker.allegiance; // loser = defender.allegiance; // // } else { // //Then it is a defefnder win; // winner = defender.allegiance; // loser = attacker.allegiance; // } //To determine the proportion of losses in line with caclulated odds, identify what prportion of the total both are as a percentage //N.B. may want to throw a further randomizer in there so it is not always in total proprtion ( to allow for pyhrric victories etc). float totalOddsValue = attackerOdds + defenderOdds; float attackerPercent = (attackerOdds / totalOddsValue); float defenderPercent = (defenderOdds / totalOddsValue); //if the attacker has lost 90% of it is troops, destroy the unit. if (attackerPercent < 0.1) { DestroyPiece(attacker.coords); battleWinner = defender.allegiance; //if the defender has lost 90% of its troops, destroy the unit and declare attacker the battle winner } else if (defenderPercent < 0.1) { battleWinner = defender.allegiance; DestroyPiece(defender.coords); MovePiece(attacker, defender.coords); } else { //it was really a stalemate rather than an outright win, though there is a nominal winner. battleWinner = Mark.None; attacker.strength = Mathf.RoundToInt(attackerStrength * attackerPercent); defender.strength = Mathf.RoundToInt(defenderStrength * defenderPercent); } //create a "Battle" instance, and set relative loss levles for each player. // add the battle to a list of battles (BattleHistory) so that we can access this info whenever we want. newBattle.SetWinner(battleWinner); newBattle.SetBattleTime(); newBattle.SetLosses(attacker.allegiance, Mathf.RoundToInt((1 - attackerPercent) * attackerStrength), attacker.strength); newBattle.SetLosses(defender.allegiance, Mathf.RoundToInt((1 - defenderPercent) * defenderStrength), defender.strength); battleHistory.Add(newBattle); return(battleWinner); }