//fire main weapon public void FireWeapon() { if (destroyed || IsStunned()) { return; } if (!thisObj.activeInHierarchy) { return; } int fireState = CanFire(); if (fireState == 0) { if (weaponList[weaponID].RequireAiming()) { Vector2 cursorPos = Input.mousePosition; if (weaponList[weaponID].RandCursorForRecoil()) { float recoil = GameControl.GetPlayer().GetRecoil() * 4; cursorPos += new Vector2(Random.value - 0.5f, Random.value - 0.5f) * recoil; } Ray ray = Camera.main.ScreenPointToRay(cursorPos); RaycastHit hit; //LayerMask mask=1<<TDS.GetLayerTerrain(); //Physics.Raycast(ray, out hit, Mathf.Infinity, mask); Physics.Raycast(ray, out hit, Mathf.Infinity); ShootObject.AimInfo aimInfo = new ShootObject.AimInfo(hit); StartCoroutine(ShootRoutine(aimInfo)); } else { StartCoroutine(ShootRoutine()); } weaponList[weaponID].Fire(); } else { string text = ""; if (fireState == 1) { text = "attack disabled"; } if (fireState == 2) { text = "weapon's on cooldown"; } if (fireState == 3) { text = "weapon's out of ammo"; } if (fireState == 4) { text = "weapon's reloading"; } TDS.FireFail(text); if (GetCurrentClip() == 0 && GameControl.EnableAutoReload()) { weaponList[weaponID].Reload(); } } }
public bool ContinousFire() { return(GameControl.EnableContinousFire() & weaponList[weaponID].continousFire); }
public override void Update() { if (GameControl.IsGameOver() || destroyed || IsStunned()) { return; } //get player as target target = GameControl.GetPlayer(); if (target != null && !target.thisObj.activeInHierarchy) { target = null; } //reduce the attack cooldown currentCD -= Time.deltaTime; contactCurrentCD -= Time.deltaTime; //base.Update(); //if shootPeriodically, then shoot if (shootPeriodically) { ShootTarget(); } //if there's not target, reset the turret to origin if (target == null) { ResetTurret(); return; } //calculate the target dist, this is for later use float targetDist = Vector3.Distance(thisT.position, target.thisT.position); //now depend on the unit behaviour, act accordingly if (behaviour == _Behaviour.Aggressive) { EngageHostile(targetDist); //engage the target } else if (behaviour == _Behaviour.Aggressive_Trigger) { //if target is close enough to trigger a respond, set behaviour to aggressive if (Vector3.Distance(thisT.position, target.thisT.position) <= aggroRange) { behaviour = _Behaviour.Aggressive; } } else if (behaviour == _Behaviour.StandGuard) { if (guardTriggered) //if the unit is aggro'ed { EngageHostile(targetDist); //engage the target //this line is irrelevant atm since anchor to point is not in used //if(anchorToPoint) dist=Vector3.Distance(anchorPoint, target.thisT.position); //if target is out of range already, set aggro status to false if (targetDist > aggroRange * 2) { guardTriggered = false; //if(anchorToPoint) GenerateNewAnchor(); } } else { //if(anchorToPoint) MoveToPoint(currentAnchor, 0.5f); //if target is close enough to aggor the unit, set guardTriggered to true so the target can be engaged in next frame if (targetDist <= aggroRange) { guardTriggered = true; } } } }
//apply the effect to player void ApplyEffectSelf(UnitPlayer player) { //gain life if (life > 0) { GameControl.GainLife(); } //gain hit-point if (hitPoint > 0) { float hitPointGained = player.GainHitPoint(hitPoint); Vector3 offsetPos = new Vector3(0, Random.value + 0.5f, 0); new TextOverlay(transform.position + offsetPos, "+" + hitPointGained.ToString("f0"), new Color(0.3f, 1f, 0.3f, 1)); } //gain energy if (energy > 0) { float energyGained = player.GainEnergy(energy); Vector3 offsetPos = new Vector3(0, Random.value + 0.5f, 0); new TextOverlay(transform.position + offsetPos, "+" + energyGained.ToString("f0"), new Color(.3f, .3f, 1f, 1)); } //not in used if (credit > 0) { GameControl.GainCredits(credit); Vector3 offsetPos = new Vector3(0, Random.value + 0.5f, 0); new TextOverlay(transform.position + offsetPos, "+$" + credit.ToString("f0"), new Color(.5f, .75f, 1, 1)); } //gain score if (score > 0) { GameControl.GainScore(score); Vector3 offsetPos = new Vector3(0, Random.value + 0.5f, 0); new TextOverlay(transform.position + offsetPos, "+" + score.ToString("f0"), new Color(.1f, 1f, 1, 1)); } //gain ammo if (ammo != 0) { player.GainAmmo(ammoID, ammo); Vector3 offsetPos = new Vector3(0, Random.value + 0.5f, 0); new TextOverlay(transform.position + offsetPos, "+ammo"); } //gain exp if (exp != 0) { player.GainExp(exp); Vector3 offsetPos = new Vector3(0, Random.value + 0.5f, 0); new TextOverlay(transform.position + offsetPos, "+exp", new Color(1f, 1f, 1, 1)); } //gain perk currency if (perkCurrency != 0) { player.GainPerkCurrency(perkCurrency); Vector3 offsetPos = new Vector3(0, Random.value + 0.5f, 0); new TextOverlay(transform.position + offsetPos, "+perk points", new Color(1f, 1f, 1, 1)); } //effects if (effectIdx >= 0) { player.ApplyEffect(EffectDB.CloneItem(effectIdx)); } //if(effect!=null && effect.duration>0) player.ApplyEffect(effect); //gain weapon if (gainWeapon && weaponList.Count > 0) { int playerWeaponID = player.weaponList[player.weaponID].ID; int rand = randomWeapon ? Random.Range(0, weaponList.Count) : 0; if (randomWeapon && weaponList.Count > 1) { int count = 0; while (weaponList[rand].ID == playerWeaponID) { rand = Random.Range(0, weaponList.Count); count += 1; if (count > 50) { break; } } } bool replaceWeapon = weaponType == _WeaponType.Replacement; bool temporaryWeapon = weaponType == _WeaponType.Temporary; player.AddWeapon(weaponList[rand], replaceWeapon, temporaryWeapon, tempWeapDuration); } }
//launch the ability, at the position given public void Activate(Vector3 pos = default(Vector3), bool useCostNCD = true) { if (useCostNCD) { currentCD = GetCooldown(); //set the cooldown GameControl.GetPlayer().energy -= GetCost(); //deduct player energy by the ability cost } AudioManager.PlaySound(launchSFX); //instantiate the launch object, if there's any if (launchObj != null) { GameObject obj = (GameObject)MonoBehaviour.Instantiate(launchObj, pos, Quaternion.identity); if (autoDestroyLaunchObj) { MonoBehaviour.Destroy(obj, launchObjActiveDuration); } } //for aoe ability if (type == _AbilityType.AOE || type == _AbilityType.AOESelf) { //get all the collider in range Collider[] cols = Physics.OverlapSphere(pos, GetAOERadius()); for (int i = 0; i < cols.Length; i++) { Unit unitInstance = cols[i].gameObject.GetComponent <Unit>(); //only continue if the collider is a unit and is not player if (unitInstance != null && unitInstance != GameControl.GetPlayer()) { //create an AttackInstance and mark it as AOE attack AttackInstance aInstance = new AttackInstance(GameControl.GetPlayer(), GetRuntimeAttackStats()); aInstance.isAOE = true; aInstance.aoeDistance = Vector3.Distance(pos, cols[i].transform.position); //apply the AttackInstance unitInstance.ApplyAttack(aInstance); } } //apply explosion force TDSPhysics.ApplyExplosionForce(pos, aStats); } //for ability that affects all hostile unit in game else if (type == _AbilityType.All) { //get all hostile unit for unit tracker List <Unit> unitList = new List <Unit>(UnitTracker.GetAllUnitList()); //loop through all unit, create an AttackInstance and apply the attack for (int i = 0; i < unitList.Count; i++) { AttackInstance aInstance = new AttackInstance(GameControl.GetPlayer(), GetRuntimeAttackStats()); unitList[i].ApplyAttack(aInstance); } } //for ability that meant to be cast on player unit else if (type == _AbilityType.Self) { //apply the attack on player AttackInstance aInstance = new AttackInstance(GameControl.GetPlayer(), GetRuntimeAttackStats()); GameControl.GetPlayer().ApplyAttack(aInstance); } //for ability that fires a shoot object else if (type == _AbilityType.Shoot) { //get the position and rotation to fire the shoot object from Transform srcT = GetShootObjectSrcTransform(); Vector3 shootPos = srcT.TransformPoint(shootPosOffset); pos.y = shootPos.y; Quaternion shootRot = Quaternion.LookRotation(pos - shootPos); //create the AttackInstance AttackInstance aInstance = new AttackInstance(GameControl.GetPlayer(), GetRuntimeAttackStats()); //Instantiate the shoot-object and fires it GameObject soObj = (GameObject)MonoBehaviour.Instantiate(shootObject, shootPos, shootRot); ShootObject soInstance = soObj.GetComponent <ShootObject>(); soInstance.Shoot(GameControl.GetPlayer().thisObj.layer, GetRange(), srcT, aInstance); } else if (type == _AbilityType.Movement) { if (moveType == _MoveType.Blink) { GameControl.GetPlayer().thisT.position += GameControl.GetPlayer().thisT.TransformVector(Vector3.forward * range); } else if (moveType == _MoveType.Dash) { //GameControl.GetPlayer().thisT.position+=GameControl.GetPlayer().thisT.TransformPoint(Vector3.z)*range; GameControl.GetPlayer().Dash(range, duration); } else if (moveType == _MoveType.Teleport) { Transform playerT = GameControl.GetPlayer().thisT; Vector3 tgtPos = new Vector3(pos.x, playerT.position.y, pos.z); if (Vector3.Distance(playerT.position, tgtPos) > range) { tgtPos = playerT.position + (tgtPos - playerT.position).normalized * range; } playerT.position = tgtPos; } } }
public void Completed() { cleared = true; GameControl.GainCredits(creditGain); GameControl.GainScore(scoreGain); }
//function call to check all the objective has been completed public void CheckObjectiveComplete() { bool cleared = true; //objective status set to true by default, it will be set to false if any of the objective condition is not full-filled //cleared flag will then be use when calling GameControl.GameOver, indicate if player win/lose the level //if require to wait for timer but time is not up yet, dont proceed if (waitForTimer && !GameControl.TimesUp()) { return; } //if scoring criteria not full filled, set cleared to false if (enableScoring && !scored) { cleared = false; } if (colPrefabList.Count > 0) { for (int i = 0; i < colPrefabList.Count; i++) { if (colPrefabCountList[i] > colPrefabCollectedCountList[i]) { cleared = false; break; } } } //if(clearAllCol){ //if clear all collectible is required and not all collectible is collected, set clear to false // if(GetAllCollectibleCount>0) cleared=false; //} if (collectibleList.Count > 0) { cleared = false; //if not all require collectible required has been collectible } //if either of the prefab kill count is not adequate, set cleared to false if (prefabList.Count > 0) { for (int i = 0; i < prefabList.Count; i++) { if (prefabCountList[i] > prefabKillCountList[i]) { cleared = false; break; } } } if (clearAllHostile) //if clear all hostile is required and not all unit is destroyed, set clear to false { if (UnitTracker.GetUnitCount() > 0) { cleared = false; } } else //if not all the target unit has been destroyed, set clear to false { if (unitList.Count > 0) { cleared = false; } } if (clearAllSpawner) //if clear all spawner is required and not all spawner is cleared/destroyed, set clear to false { if (UnitSpawnerTracker.GetSpawnerCount() > 0) { cleared = false; } } else //if not all the spawner has been cleared/destroyed, set clear to false { if (spawnerList.Count > 0) { cleared = false; } } //if time is up, consider game is complete and call GameOver if (GameControl.TimesUp()) { isComplete = true; GameControl.GameOver(cleared); } //else if we dont need to wait for timer and the objective is cleared, call GameOver else if (!waitForTimer) { if (cleared) { isComplete = true; GameControl.GameOver(cleared); } } }
//to get the player turret object (for shooting ability) public Transform GetShootObjectSrcTransform() { return(GameControl.GetPlayer().turretObj != null?GameControl.GetPlayer().turretObj : GameControl.GetPlayer().thisT); }
void Awake() { instance = (GameControl)target; LoadDB(); }
//for when the unit is destroy by game mechanic public void Destroyed(UnitPlayer player = null) { if (destroyed) { return; } //if(player==null) Debug.LogWarning("unit destroyed by not source player has been detected", null); destroyed = true; //spawn a unit if spawnUponDestroy is assigned if (spawnUponDestroy != null) { //loop as many as required for (int i = 0; i < spawnUponDestroyCount; i++) { //instantiate the unit //GameObject unitObj=(GameObject)Instantiate(spawnUponDestroy.gameObject, thisT.position, thisT.rotation); GameObject unitObj = ObjectPoolManager.Spawn(spawnUponDestroy.gameObject, thisT.position, thisT.rotation); unitObj.layer = thisObj.layer; //pass on the wave info Unit unitInstance = unitObj.GetComponent <Unit>(); if (waveID >= 0) { unitInstance.SetWaveID(spawner, waveID); spawner.AddUnitToWave(unitInstance); } else if (spawner != null) { spawner.AddUnit(unitInstance); } } } //check if the unit is going to drop any collectible if (useDropManager) //if useDropManager is enabled, inform CollectibleDropManager { CollectibleDropManager.UnitDestroyed(thisT.position); } else { //check chance and spawn the item if (dropObject != null && Random.value < dropChance) { ObjectPoolManager.Spawn(dropObject.gameObject, thisT.position, Quaternion.identity); } } if (player != null) { //applies the bonus value for when the unit is destroyed. //if(valueCredits>0) GameControl.GainCredits(valueCredits); if (valueScore > 0) { GameControl.GainScore(valueScore); } if (valuePerkC > 0) { player.GainPerkCurrency(valuePerkC); } if (valueExp > 0) { player.GainExp(valueExp); } if (valueHitPoint > 0) { player.GainHitPoint(valueHitPoint); } if (valueEnergy > 0) { player.GainEnergy(valueEnergy); } } //if(isPlayer) GetUnitPlayer().DeleteSave(); //shake camera TDS.CameraShake(destroyCamShake); float delay = uAnimation != null?uAnimation.Destroyed() : 0; ClearUnit(true, delay); }
//called when shootobject hit something void OnTriggerEnter(Collider col) { if (state == _State.Hit) { return; //if the shootobject has hit something before this, return } //if the shootobject hits another shootobject from friendly unit if (!GameControl.SOHitFriendly() && col != null) { if (srcLayer == col.gameObject.layer) { return; } } //register the state of the shootobject as hit state = _State.Hit; TDS.CameraShake(impactCamShake); //when hit a shootObject if (col != null && col.gameObject.layer == TDS.GetLayerShootObject()) { //if this is a beam shootobject, inform the other shootobject that it has been hit (beam doesnt use a collider) if (type == _SOType.Beam) { col.gameObject.GetComponent <ShootObject>().Hit(); } } //when hit a collectible, destroy the collectible if (col != null && col.gameObject.layer == TDS.GetLayerCollectible()) { ObjectPoolManager.Unspawn(col.gameObject); return; } //if there's a attack instance (means the shootobject has a valid attacking stats and all) if (attInstance != null) { float aoeRadius = attInstance.aStats.aoeRadius; //for area of effect hit if (aoeRadius > 0) { Unit unitInstance = null; //get all the potental target in range Collider[] cols = Physics.OverlapSphere(thisT.position, aoeRadius); for (int i = 0; i < cols.Length; i++) { //if the collider in question is the collider the shootobject hit in the first place, apply the full attack instance if (cols[i] == col) { unitInstance = col.gameObject.GetComponent <Unit>(); if (unitInstance != null) { unitInstance.ApplyAttack(attInstance.Clone()); } continue; } //no friendly fire, then skip if the target is a friendly unit if (!GameControl.SOHitFriendly()) { if (cols[i].gameObject.layer == srcLayer) { continue; } } unitInstance = cols[i].gameObject.GetComponent <Unit>(); //create a new attack instance and mark it as aoe attack, so diminishing aoe can be applied if enabled AttackInstance aInstance = attInstance.Clone(); aInstance.isAOE = true; aInstance.aoeDistance = Vector3.Distance(thisT.position, cols[i].transform.position); //apply the attack if (unitInstance != null) { unitInstance.ApplyAttack(aInstance); } } } else { if (col != null) { //get the unit and apply the attack Unit unitInstance = col.gameObject.GetComponent <Unit>(); if (unitInstance != null) { unitInstance.ApplyAttack(attInstance); } } } if (col != null) { //apply impact force to the hit object Vector3 impactDir = Quaternion.Euler(0, thisT.eulerAngles.y, 0) * Vector3.forward; TDSPhysics.ApplyAttackForce(thisT.position, impactDir, col.gameObject, attInstance.aStats); } } //add collider to the condition so the shootobject wont split if the shootObject didnt hit anything (it could have just reach the range limit) if (splitUponHit && col != null) { Split(col); } Hit(); }
//function call to fire the object public void Shoot(int srcL, float srcR, Transform shootPoint, AttackInstance aInstance = null, AimInfo aimInfo = null) { Init(); thisObj.SetActive(true); //cached all the passed information lcoally attInstance = aInstance; srcLayer = srcL; //the layer of the shooting unit (so we know it's from player or AI) srcRange = srcR; //the range of the shooting unit (so we know when to stop) state = _State.Shot; shootTime = Time.time; //to track how long the shoot object is has been travelledDistance = 0; //to track how far the shoot object is has been fired //if there's any hideObject, set it to true (it's probably set to false when the shoot-object last hit something) if (hideObject != null) { hideObject.SetActive(true); } //instantiate the shoot effect ShootEffect(thisT.position, thisT.rotation, shootPoint); if (type == _SOType.Simple || type == _SOType.Homing) { //if(aInstance!=null && thisCollider.enabled){ //~ Physics.IgnoreCollision(aInstance.srcUnit.GetCollider(), thisObj.GetComponent<Collider>(), true); //Debug.Log("collision avoidance with shooter unresolved"); //Physics.IgnoreCollision(srcCollider, thisCollider, true); //} // for homing shootobject, the shootobject needs to be aiming at some position, or a specific unit if (type == _SOType.Homing) { if (aimInfo.targetT != null) { targetUnit = aimInfo.unit; } targetPos = aimInfo.hitPoint + new Vector3(Random.value - 0.5f, 0, Random.value - 0.5f) * 2 * spread; initialPos = shootPoint.position; initialDist = Vector3.Distance(targetPos, initialPos); curveMod = Random.Range(0, 2f); dummyPos = thisT.TransformPoint(Vector3.forward * speed * 5); dummyPos = (targetPos + dummyPos) / 2; } } else if (type == _SOType.Beam) { //if(attachedToShootPoint) transform.parent=shootPoint; thisT.parent = shootPoint; ObjectPoolManager.Unspawn(thisObj, beamDuration - .01f); } else if (type == _SOType.Point) { StartCoroutine(PointRoutine(aimInfo)); } //update the layermask used to do the hit detection in accordance to rules set in GameControl UpdateSphereCastMask(!GameControl.SOHitFriendly(), !GameControl.SOHitShootObject(), !GameControl.SOHitCollectible()); }
public static void GainScore(int value) { instance.score += value; GameControl.GainScore(value); //if(instance.objective!=null) instance.objective.GainScore(); }
void Awake() { instance=this; Application.targetFrameRate=60; //get the unit in game player = (UnitPlayer)FindObjectOfType(typeof(UnitPlayer)); //setup the collision rules Physics.IgnoreLayerCollision(TDS.GetLayerShootObject(), TDS.GetLayerShootObject(), !shootObject); Physics.IgnoreLayerCollision(TDS.GetLayerShootObject(), TDS.GetLayerCollectible(), !collectible); Physics.IgnoreLayerCollision(TDS.GetLayerShootObject(), TDS.GetLayerTerrain(), true); Physics.IgnoreLayerCollision(TDS.GetLayerShootObject(), TDS.GetLayerTrigger(), true); //clear all the spawner and tracker sicne it's a new game UnitTracker.Clear(); UnitSpawnerTracker.Clear(); //this is not required, each individual unit and spawner will register itself to the tracker //UnitTracker.ScanForUnit(); //UnitSpawnerTracker.ScanForSpawner(); }