//doesnt have to be a remote procedure call, since only the defender calls such a function //instead we'll just make it public //[PunRPC] public GameObject upgradeTower() { //if already at max level, we can't upgrade anymore if (towerLevel == 3) { return(null); } //if we are not the defenders (owners of this tower, we cannot upgrade it) //this will prevent a malicious opponent from hacking and upgrading a weak tower to cost the defender money if (!photonView.isMine) { return(null); } //safety check on the defender manager if (dms == null) { dms = GameObject.Find("DefenderManager").GetComponent <DefenderManagerScript> (); Debug.Log("dms was null"); } //now that we're sure we want to upgrade the tower: int newTowerLevel = towerLevel + 1; //set free the spot that the old tower occupied, since we want to create a new upgraded tower dms.availableSpots [gridPositionX, gridPositionY] = true; //create a new tower (with a higher level) and destroy the old one GameObject newTower = dms.buildTower(towerName, newTowerLevel, gridPositionX, gridPositionY); if (gameObject.GetComponent <PhotonView> ().isMine) { PhotonNetwork.Destroy(this.gameObject); } return(newTower); }
//will help in spotting if humans are in range //RaycastHit hit; //Ray ray; // Use this for initialization void Start() { towerHealth = 100; isFiring = false; //first we need to find the defenderManager to tell it to create a tower in case of an upgrade DefenderManagerScript dms = GameObject.Find("DefenderManager").GetComponent <DefenderManagerScript>(); //note: this can be set to the current time to prevent towers from shooting at their creation or upgrade, but will be kept as a feature //this way so that players can upgrade to get a quick shot lastShootTime = 0; }
//when selling a tower, destroy the tower and give the player roughly 1/4 of its price public void sellTower() { //calculate money to be increased (based on tower type and level). implement formula //the increment was moved to the code in the "sell" button //safety check if (dms == null) { dms = GameObject.Find("DefenderManager").GetComponent <DefenderManagerScript> (); Debug.Log("dms was null"); } //free up where the sold tower used to be dms.availableSpots [gridPositionX, gridPositionY] = true; //destroy this tower using photon network destroy if (gameObject.GetComponent <PhotonView> ().isMine) { PhotonNetwork.Destroy(this.gameObject); } }
void Update() { //safety check if (dms == null) { dms = GameObject.Find("DefenderManager").GetComponent <DefenderManagerScript>(); Debug.Log("dms was null"); } //display the updated number of souls that the defender has gameObject.GetComponent <UILabel>().text = ("Souls: " + dms.souls); //Detect the winning condition of the aliens //TODO: game designer to choose threshold int winningSoulsThreshold = 5000; if (dms.souls >= winningSoulsThreshold) { //run the remote procedure call so that both players run the function GameObject.Find("Label - Winner").GetComponent <PhotonView>().RPC("DeclareVictory", PhotonTargets.All, new object[] { "aliens" }); } }
void Start() { dms = GameObject.Find("DefenderManager").GetComponent <DefenderManagerScript>(); }
// Use this for initialization void Start() { dms = defenderManager.GetComponent <DefenderManagerScript>(); }
public void spawnTower(string towerType) { //make sure the player is in a room if (!PhotonNetwork.inRoom) { return; } //safety check. if defender manager script is null, look for it if (dms == null) { dms = defenderManager.GetComponent <DefenderManagerScript> (); } //create a ray to see where the user is pointing Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hitInfo; //check on what the ray hits if (Physics.Raycast(ray, out hitInfo)) { //Debug.Log("Mouse is over: " + hitInfo.collider.name); float x, y, z; //storing the location of the collision x = hitInfo.point.x; y = hitInfo.point.y; z = hitInfo.point.z; //Debug.Log("at position: " + x + "," + y + "," + z); GameObject hitObject = hitInfo.transform.root.gameObject; //now we determine if they ray casted is on which of the cells. The details are in this comment: //the droppable area goes from (233,0.01,251) till (412,0.01,366) //it is divided into a grid of 6 cells by 9 cells. IE along the x-z axis it looks like: // (233,366) (412,366) // // (233, 251) (412,251) //if the mouse is on the grid dedicated for towers, then try to place a tower if (hitInfo.collider.name == "Droppable Area") { float xDifference = x - 233; //goes from 0 to 179 float zDifference = z - 251; //goes from 0 to 115 //adding a 5 to maximum differences as a safety margin const float maxXDifference = 412 - 233 + 5; //179 --> 184 const float maxZDifference = 366 - 251 + 5; //115 --> 120 int xCoordinate = (int)(xDifference * 9 / maxXDifference); //going form 0 to 8 int zCoordinate = (int)(zDifference * 6 / maxZDifference); //going from 0 to 5 //if (Input.GetMouseButtonDown (0)) { //TODO: ask a game designer for specific tower prices. This will do for now int towerBuildCost = 50; //if the tower is affordable, build it if (dms.souls >= towerBuildCost) { dms.souls -= towerBuildCost; dms.buildTower(towerType, 1, xCoordinate, zCoordinate); } //} } } }
//this method will split all the towers based on their name (type of tower) and make each tower behave differently //for simplicity the 4 shooting towers are running the same code void performFunctionality() { //safety check if (dms == null) { dms = GameObject.Find("DefenderManager").GetComponent <DefenderManagerScript> (); Debug.Log("dms was null"); } //check to see if this tower is dead if (towerHealth <= 0) { //free up where the dead tower used to be dms.availableSpots [gridPositionX, gridPositionY] = true; if (gameObject.GetComponent <PhotonView> ().isMine) { PhotonNetwork.Destroy(this.gameObject); } } //each tower casts a ray of length "shootingRange" and starts firing if there are enemies in that area RaycastHit[] hits = Physics.RaycastAll(transform.position, gameObject.transform.forward, shootingRange); isFiring = false; if (hits != null) { //if the ray collided with an object AND the object is a human, start firing, else stop firing (the stop firing is set above (2 lines before this)) foreach (RaycastHit hit in hits) { if (hit.collider.tag == "Human") { isFiring = true; //Debug.Log ("SUCCESS from turret " + towerName); } } } //for simplicity of the code, treat all towers that have the same logic of shooting particles together //and start by letting all of them fire the same particle at their perspective fireRate switch (towerName) { case "Tow_Cannon": case "Tow_Crossbow": case "Tow_Gatling": case "Tow_Mortar": //when no enemies(humans) are within this tower's range then just break if (!isFiring) { //can implement a penalty for idle towers by letting those that are not firing cost 1 soul per time interval as upkeep cost //this will make it harder for the defender and require more strategy from the player break; } //the delay between each bullet and the next, launched from this tower float fireDelay = 10f / fireRate; //if we already fired 'relatively' soon, dont fire now if (Time.realtimeSinceStartup - lastShootTime < fireDelay) { return; } //set this shot time to be the last shot time lastShootTime = Time.realtimeSinceStartup; //now that we want to shoot we have to fire an RPC for each projectile //RPCs are used because there will be alot of bullets in the scene and this way we cut down on number of gameObjects to update over the netwerk //since RPCs are only fired once //PhotonView.RPC("launchProjectile",PhotonTargets.All, new object[] {} ); gameObject.GetComponent <PhotonView>().RPC("launchProjectile", PhotonTargets.All, new object[] {}); break; case "Tow_Radar": //as fireRate increases with each upgrade, the boost delay will be less with each upgrade and tower will produce souls faster float boostDelay = 5 / fireRate; //the radars produce souls randomly at a rate based on their level if ((Time.realtimeSinceStartup - lastShootTime) < boostDelay) { return; } dms.souls = dms.souls + 10; lastShootTime = Time.realtimeSinceStartup; break; default: break; } }