//Private helper method that allows a delay before having the assistFighter become the main selectedFighter // Pre: assistFighter is currently the only party member that is alive IEnumerator assistToSelected() { PKMNEntity prevFighter = selectedFighter; selectedFighter = assistFighter; animator = selectedFighter.GetComponent <Animator>(); player = selectedFighter.GetComponent <Transform>(); yield return(new WaitForSeconds(DEATH_WAIT)); //Switch UI elements secMoveIndex = 0; mainSwapper.switchAbilities(secMoveIndex); swapUIBars(selectedFighter, prevFighter); abilityUIMap[selectedFighter].swapIcons(abilityUIMap[prevFighter]); //Switches fighter mappings AbilityUI temp = abilityUIMap[selectedFighter]; abilityUIMap[selectedFighter] = abilityUIMap[prevFighter]; abilityUIMap[prevFighter] = temp; //Update UI abilityUIMap[prevFighter].updateStatus(); selectedFighter.GetComponent <SwitchState>().setUpState(abilityUIMap[selectedFighter]); prevFighter.GetComponent <SwitchState>().setUpState(abilityUIMap[prevFighter]); selectedFighter.GetComponent <SpriteRenderer>().enabled = true; //Disable character back selectedFighter.GetComponent <Collider2D>().enabled = true; canMove = true; }
//Private helper method for assistMoves: set selectedCharacter back to previous main character // Pre: assist move is already in execution and partyIndex changed to the previous mainIndex // Post: You are back to main character while a partner character is in execution private void goBackToMain(Vector3 originalPos) { PKMNEntity prevFighter = selectedFighter; //Set previous fighter //Enables new fighter selectedFighter = transform.GetChild(partyIndex).GetComponent <PKMNEntity>(); selectedFighter.transform.position = originalPos; selectedFighter.GetComponent <SpriteRenderer>().enabled = true; selectedFighter.GetComponent <Collider2D>().enabled = true; //Switch UI elements secMoveIndex = 0; mainSwapper.switchAbilities(secMoveIndex); swapUIBars(selectedFighter, prevFighter); abilityUIMap[selectedFighter].swapIcons(abilityUIMap[prevFighter]); //Switches fighter mappings AbilityUI temp = abilityUIMap[selectedFighter]; abilityUIMap[selectedFighter] = abilityUIMap[prevFighter]; abilityUIMap[prevFighter] = temp; selectedFighter.GetComponent <SwitchState>().setUpState(abilityUIMap[selectedFighter]); prevFighter.GetComponent <SwitchState>().setUpState(abilityUIMap[prevFighter]); //Set Main Character variables to fighter animator = selectedFighter.GetComponent <Animator>(); player = selectedFighter.GetComponent <Transform>(); }
//Switches to the character // Pre: fighterIndex must have been changed to a different value before hand IEnumerator rotateCharacters() { selectedFighter.GetComponent <SwitchState>().disableSwitch(true); //Disable switch state on selectedFighter //Do rotation swapMainCharUI(false); if (numPartners > 2) { swapPartnerUI(); } else if (numPartners == 2 && assistFighter != null) { int index = (partyIndex == 0) ? 1 : 0; PKMNEntity sidePartner = transform.GetChild(index).GetComponent <PKMNEntity>(); //Swap UI Elements swapUIBars(assistFighter, sidePartner); abilityUIMap[assistFighter].swapIcons(abilityUIMap[sidePartner]); //Update mappings AbilityUI temp = abilityUIMap[assistFighter]; abilityUIMap[assistFighter] = abilityUIMap[sidePartner]; abilityUIMap[sidePartner] = temp; assistFighter.GetComponent <SwitchState>().setUpState(abilityUIMap[assistFighter]); sidePartner.GetComponent <SwitchState>().setUpState(abilityUIMap[sidePartner]); } //Update UI states foreach (KeyValuePair <PKMNEntity, AbilityUI> entry in abilityUIMap) { entry.Value.updateStatus(); } //Do transition animation canMove = false; float animTimer = 0.0f; animator.SetBool("Charging", true); yield return(new WaitForSeconds(0.1f)); animator.SetBool("Charging", false); animator.SetBool("FinishedCharge", true); while (!selectedFighter.isStunned() && animTimer < TRANSITION_TIME && !attacking()) { yield return(new WaitForFixedUpdate()); animTimer += Time.deltaTime; combat(); } animator.SetBool("FinishedCharge", false); if (!selectedFighter.isStunned() && selectedFighter.isAlive()) { canMove = true; } }
//Execute Method public IEnumerator execute() { offCD = false; bool alreadyFull = false; float channelTimer = 0f; float totalTimer = 0f; float soundTimer = 0f; basis.soundFXs.clip = Resources.Load <AudioClip>("Audio/AttackSounds/Dash"); //Establish sound clip anim.SetBool("Dashing", true); anim.SetFloat("speed", 0f); basis.getController().canMove = false; progress.gameObject.SetActive(true); //Channeling while (Input.GetMouseButton(1) && !basis.isStunned() && totalTimer < MAX_CHANNEL) { channelTimer = (channelTimer < FULL_CHANNEL) ? channelTimer + Time.deltaTime : FULL_CHANNEL; progress.updateProgress(channelTimer / FULL_CHANNEL); totalTimer += Time.deltaTime; soundTimer += Time.deltaTime; //Sound effects if (channelTimer >= FULL_CHANNEL && !alreadyFull) { basis.soundFXs.Stop(); basis.soundFXs.clip = Resources.Load <AudioClip>("Audio/AttackSounds/Beep"); basis.soundFXs.Play(); alreadyFull = true; } else if (soundTimer >= CHARGE_SOUND_INTERVAL && !alreadyFull) { soundTimer = 0.0f; basis.soundFXs.Stop(); basis.soundFXs.Play(); } basis.GetComponent <Rigidbody2D>().velocity = Vector2.zero; Battle.updatePlayerAOrientation(basis.transform); yield return(new WaitForFixedUpdate()); } progress.gameObject.SetActive(false); if (!basis.isStunned() && basis.isAlive()) //If the fighter isn't stunned, execute dash //Calculate stats { curPwr = getChannelStat(MIN_PWR, MAX_PWR, channelTimer); curDashStrength = getChannelStat(MIN_DASH_STRENGTH, MAX_DASH_STRENGTH, channelTimer); basis.soundFXs.Stop(); basis.soundFXs.clip = Resources.Load <AudioClip>("Audio/AttackSounds/Dash"); basis.soundFXs.Play(); yield return(basis.StartCoroutine(dashBox.executeDash(this, curDashStrength, DASH_DURATION, PRIORITY))); } }
//Applies effects to enemy hit public void enactEffects(Collider2D tgt) { PKMNEntity enemy = tgt.GetComponent <PKMNEntity>(); int damage = Battle.damageCalc(basis.level, INITIAL_PWR, basis.accessStat(BaseStat.SPECIAL_ATTACK), basis.accessStat(BaseStat.SPECIAL_DEFENSE)); enemy.StartCoroutine(enemy.receiveDamage(damage, basis)); //Add debuff StatEffect debuff = new StatEffect(DEBUFF_DURATION, DEBUFF_FACTOR, DEBUFF_TYPE); debuff.applyEffect(enemy.GetComponent <PKMNEntity>()); }
//Constructor public QuickAttack(Animator anim, PKMNEntity basis) { //Set reference variables and any other variables concerning entity this.anim = anim; this.basis = basis; this.dashBox = basis.GetComponent <DashChargeHitBox>(); this.enemyTag = (basis.tag == "Player") ? "Enemy" : "Player"; //Establish any other variables numCharges = MAX_CHARGES; offCD = true; cTimer = 0f; }
//Constructor public ShellDash(Animator anim, PKMNEntity basis, ProgressBar progress) { //Set reference variables and any other variables concerning entity this.anim = anim; this.basis = basis; this.dashBox = basis.GetComponent <DashChargeHitBox>(); this.enemyTag = (basis.tag == "Player") ? "Enemy" : "Player"; this.progress = progress; //Establish any other variables cTimer = 0.0f; offCD = true; }
//Private helper method that switches characters if a main character is dead but partners (within rotation) are alive private IEnumerator mainMemberDeathFreePartners() { PKMNEntity prevFighter = selectedFighter; partyIndex %= numPartners; //Change partyIndex selectedFighter.transform.parent = null; //Detaches parent //Enable new partner the GameObject. If a GameObject shares a parent with other GameObjects and are on the same level (i.e. they share the same direct parent), these GameObjects are known as siblings. The sibling index shows where each GameObject sits in this sibling hierarchy. selectedFighter = transform.GetChild(partyIndex).GetComponent <PKMNEntity>(); animator = selectedFighter.GetComponent <Animator>(); player = selectedFighter.GetComponent <Transform>(); player.position = transform.position; canMove = false; yield return(new WaitForSeconds(DEATH_WAIT)); canMove = true; selectedFighter.GetComponent <SpriteRenderer>().enabled = true; selectedFighter.GetComponent <Collider2D>().enabled = true; //Switch UI elements secMoveIndex = 0; mainSwapper.switchAbilities(secMoveIndex); swapUIBars(selectedFighter, prevFighter); abilityUIMap[selectedFighter].swapIcons(abilityUIMap[prevFighter]); //Switches fighter mappings AbilityUI temp = abilityUIMap[selectedFighter]; abilityUIMap[selectedFighter] = abilityUIMap[prevFighter]; abilityUIMap[prevFighter] = temp; abilityUIMap[prevFighter].updateStatus(); setIsolation(false); yield return(StartCoroutine(recoveryFrames())); }
//Execute dash with a set vector already in mind // Pre: move == dashing move, dashVector != zero vector, time > 0, new Priority is between 1 & 10 public IEnumerator executeDash(IMove move, Vector2 dashVector, float time, int newPriority) { //Set general hitbox properties currentMove = move; priority = newPriority; Animator anim = entity.GetComponent <Animator>(); //Alter properties of character enemyTag = (transform.tag == "Player" || transform.tag == "PlayerRecovery") ? "Enemy" : "Player"; enemyAttackTag = (transform.tag == "Player" || transform.tag == "PlayerRecovery") ? "EnemyAttack" : "PlayerAttack"; transform.tag = (transform.tag == "Player" || transform.tag == "PlayerRecovery") ? "PlayerAttack" : "EnemyAttack"; if (!entity.getAssist()) { entity.getController().canMove = false; } //Set dashing variables dashing = true; float curTime = 0.0f; GetComponent <Rigidbody2D>().AddForce(dashVector); Battle.updatePlayerAOrientation(entity.transform); anim.SetBool("Dashing", true); //Dashing while (dashing && curTime < time && !entity.isStunned()) { yield return(new WaitForFixedUpdate()); curTime += Time.deltaTime; } //Check if player is recoiling (dash was interuppted) if (dashing) { dashing = false; GetComponent <Rigidbody2D>().velocity = Vector2.zero; } //Reset properties of character transform.tag = (transform.tag == "PlayerAttack") ? "Player" : "Enemy"; if (!entity.isStunned() && entity.isAlive()) { entity.getController().canMove = true; } anim.SetBool("Dashing", false); }
//Constructor public GattlerBlast(Animator anim, PKMNEntity basis) { //Set reference variables and any other variables concerning entity this.anim = anim; this.basis = basis; this.dashBox = basis.GetComponent <DashChargeHitBox>(); this.enemyTag = (basis.tag == "Player") ? "Enemy" : "Player"; this.mainHitbox = Resources.Load <Transform>("MoveHitboxes/TriangleHitbox"); //Set other variables canAttack = true; offCD = true; numCharges = MAX_CHARGES; }
//Update method that checks the status of fighter and make changes to correspond with status (Particularly with switch cooldown) public void updateStatus() { SwitchState thisState = fighter.GetComponent <SwitchState>(); GetComponent <Image>().color = (thisState.canSwitch()) ? defaultColor : cdSwitchColor; if (!fighter.isAlive()) { GetComponent <Image>().color = deathColor; fighterIcon.sprite = Resources.Load <Sprite>("Portraits/Death"); fighterIcon.color = deathColor; } updateExp(); }
//Private helper method that swaps the main character (selectedFighter) with a partner character // Pre: new partyIndex does not correspond with current selectedFighter in child array // Post: The UI for main character and a partner character is swapped private void swapMainCharUI(bool assist) { //Disables current SelectedFighter and stores prev fighter (if assist is false) if (!assist) { selectedFighter.GetComponent <SpriteRenderer>().enabled = false; selectedFighter.GetComponent <Collider2D>().enabled = false; } PKMNEntity prevFighter = selectedFighter; //Enables new fighter selectedFighter = transform.GetChild(partyIndex).GetComponent <PKMNEntity>(); selectedFighter.GetComponent <SpriteRenderer>().enabled = true; selectedFighter.GetComponent <Collider2D>().enabled = true; //Switch UI elements secMoveIndex = 0; mainSwapper.switchAbilities(secMoveIndex); swapUIBars(selectedFighter, prevFighter); abilityUIMap[selectedFighter].swapIcons(abilityUIMap[prevFighter]); //Switches fighter mappings AbilityUI temp = abilityUIMap[selectedFighter]; abilityUIMap[selectedFighter] = abilityUIMap[prevFighter]; abilityUIMap[prevFighter] = temp; selectedFighter.GetComponent <SwitchState>().setUpState(abilityUIMap[selectedFighter]); prevFighter.GetComponent <SwitchState>().setUpState(abilityUIMap[prevFighter]); //Set Main Character variables to fighter animator = selectedFighter.GetComponent <Animator>(); player = selectedFighter.GetComponent <Transform>(); player.position = transform.position; }
//Responsible for grab knockback IEnumerator grabKnockback(Transform enemy) { //Sets up knockback variable and needed reference variables Vector2 kVect = Battle.dirKnockbackCalc(enemy.position, basis.transform.position, KNOCKBACK_VAL); Rigidbody2D rb = enemy.GetComponent <Rigidbody2D>(); Rigidbody2D basisRB = basis.GetComponent <Rigidbody2D>(); PKMNEntity enemyFighter = enemy.GetComponent <PKMNEntity>(); Controller control = enemyFighter.getController(); //Disable movement until grab movement done if (!enemyFighter.getAssist()) { control.canMove = false; } yield return(new WaitForSeconds(STUN_DELAY)); //Overrides default knockback canceller (receiveDamage) rb.AddForce(kVect); float kbTimer = 0; while (kbTimer < KNOCKBACK_DURATION) { yield return(new WaitForFixedUpdate()); kbTimer += Time.deltaTime; } rb.velocity = Vector2.zero; basisRB.velocity = Vector2.zero; if (basis.tag == "Player" || basis.tag == "PlayerAttack" || basis.tag == "PlayerRecovery") { PlayerMovement mainControl = (PlayerMovement)(basis.getController()); mainControl.selectedFighter.GetComponent <Rigidbody2D>().velocity = Vector2.zero; } if (!enemyFighter.isStunned() && !enemy.GetComponent <DashChargeHitBox>().isDashing() && !enemy.GetComponent <Animator>().GetBool("Dashing")) { control.canMove = true; } //Add debuff StatEffect debuff = new StatEffect(DEBUFF_DURATION, DEBUFF_FACTOR, STAT_TYPE); debuff.applyEffect(enemy.GetComponent <PKMNEntity>()); }
// Start is called before the first frame update void Start() { //Set reference variables player = selectedFighter.GetComponent <Transform>(); animator = selectedFighter.GetComponent <Animator>(); //Set canMove to true canMove = true; assistMoveExecuted = false; //Secondary move index secMoveIndex = 0; //Teamwork variables partyIndex = 0; selectedFighter = transform.GetChild(partyIndex).GetComponent <PKMNEntity>(); numPartners = transform.childCount - 1; //Set UI Elements if (numPartners >= 2) { abilityIconSets[1].gameObject.SetActive(true); } if (numPartners >= 3) { abilityIconSets[2].gameObject.SetActive(true); } abilityUIMap = new Dictionary <PKMNEntity, AbilityUI>(); for (int i = 0; i < numPartners; i++) { PKMNEntity curFighter = transform.GetChild(i).GetComponent <PKMNEntity>(); SwitchState curSwitchState = curFighter.gameObject.AddComponent <SwitchState>(); abilityUIMap[curFighter] = abilityIconSets[i]; //Abilities abilityIconSets[i].setUp(curFighter); curSwitchState.setUpState(abilityIconSets[i]); curFighter.healthBar = healthBars[i]; //Stat bars curFighter.armorBar = armorBars[i]; statMenu.addFighter(curFighter); } }
//Execute method upon user input FOR PLAYER for charging a self-buff public IEnumerator execute() { Controller entityController = anim.GetComponent <PKMNEntity>().getController(); charging = true; //Set boolean locking variable to true to avoid decay while charging anim.SetFloat("speed", 0); //Set Animation anim.SetBool("Charging", true); entityController.canMove = false; //Disable movement float curHealth = unit.accessStat(BaseStat.HEALTH); //Get current health for checking progress.gameObject.SetActive(true); //Set progressbar to true unit.soundFXs.clip = Resources.Load <AudioClip>("Audio/AttackSounds/Charging"); //Establish sound clip float soundTimer = CHARGE_SOUND_INTERVAL; //Set sound to play immediately //While player holds key, update chargeProgress while (Input.GetMouseButton(1) && chargeProgress < CHARGE_REQ && unit.accessStat(BaseStat.HEALTH) >= curHealth) { chargeProgress += Time.deltaTime; soundTimer += Time.deltaTime; curHealth = unit.accessStat(BaseStat.HEALTH); progress.updateProgress(chargeProgress / CHARGE_REQ); if (soundTimer >= CHARGE_SOUND_INTERVAL) { soundTimer = 0.0f; unit.soundFXs.Stop(); unit.soundFXs.Play(); } yield return(new WaitForFixedUpdate()); } anim.SetBool("Charging", false); //If charge is successful, update animator and apply StatEffect to self if (chargeProgress >= CHARGE_REQ) { progress.gameObject.SetActive(false); chargeProgress = 0.0f; offCD = false; enactEffects(unit.GetComponent <Collider2D>()); //Sound effects unit.soundFXs.Stop(); unit.soundFXs.clip = Resources.Load <AudioClip>("Audio/AttackSounds/Beep"); unit.soundFXs.Play(); anim.SetBool("FinishedCharge", true); float animLength = anim.GetCurrentAnimatorStateInfo(0).length; yield return(new WaitForSeconds(animLength)); anim.SetBool("FinishedCharge", false); } charging = false; if (!unit.isStunned() && unit.isAlive()) { entityController.canMove = true; } }