// Quarter Circle Forward public void QCF() { // Step 1: Down movement if (AI.doingQCF == 1) { MaxInput.Crouch("Player2"); AI.doingQCF = 2; AI.delayTimer = .1f; AI.keepInput = true; } // Step 2: Down Left/Right movement else if (AI.doingQCF == 2) { if (AI.faceLeft == true) { MaxInput.DownLeft("Player2"); } else { MaxInput.DownRight("Player2"); } AI.doingQCF = 3; AI.delayTimer = .1f; } // Step 3: Left/Right movement else if (AI.doingQCF == 3) { MaxInput.DownMove("Player2"); if (AI.faceLeft == true) { MaxInput.MoveLeft("Player2"); } else { MaxInput.MoveRight("Player2"); } AI.doingQCF = 4; AI.delayTimer = .1f; } // Step 4: Pressing Attack button else if (AI.doingQCF == 4) { if (AI.keepAction == "Square") { MaxInput.Square("Player2"); } if (AI.keepAction == "Triangle") { MaxInput.Triangle("Player2"); } if (AI.keepAction == "Circle") { MaxInput.Circle("Player2"); } if (AI.keepAction == "Cross") { MaxInput.Cross("Player2"); } if (AI.keepAction == "RTrigger") { MaxInput.RTrigger("Player2"); } if (AI.keepAction == "RBumper") { MaxInput.RBumper("Player2"); } AI.doingQCF = 0; AI.keepAction = ""; AI.keepInput = false; } }
// Update is called once per frame void Update() { //Practice Mode Handler if (GameObject.Find("PlayerData").GetComponent <SelectedCharacterManager>().gameMode == "Practice" || GameObject.Find("PlayerData").GetComponent <SelectedCharacterManager>().gameMode == "Tutorial") { //Check Settings from Practice Pause Menu //CPUState Check switch (PracticeModeSettings.GetComponent <PauseMenu>().CPUState) { case 0: dummyState = "Stand"; break; case 1: dummyState = "Crouch"; break; case 2: dummyState = "Jump"; break; case 3: dummyState = "StandGuard"; break; case 4: dummyState = "LowGuard"; break; case 5: dummyState = "GuardAll"; break; case 6: dummyState = "CPU"; break; case 7: dummyState = "Player"; break; } switch (PracticeModeSettings.GetComponent <PauseMenu>().ArmorRefill) { case 0: enableArmorRefill = true; break; case 1: enableArmorRefill = false; break; } switch (PracticeModeSettings.GetComponent <PauseMenu>().CPUAirRecover) { case 0: enableCPUAirTech = false; break; case 1: enableCPUAirTech = true; break; } switch (PracticeModeSettings.GetComponent <PauseMenu>().CPUGroundGuard) { case 0: enableGuardAfterFirstHit = false; break; case 1: enableGuardAfterFirstHit = true; break; } // If we are NOT paused if (!PracticeModeSettings.GetComponent <PauseMenu>().isPaused) { //Refill Armor Meters Option if (enableArmorRefill) { //Refill P1 Armor when P1 combo finishes if (HUD.combogauge1.enabled == false && P2inCombo && P1Prop.HitDetect.comboCount == 0) { P1Prop.armor = 4; P1Prop.durability = 100; } //Refill P2 Armor when P2 combo finishes if (HUD.combogauge1.enabled == false && P1inCombo && P2Prop.HitDetect.comboCount == 0) { P2Prop.armor = 4; P2Prop.durability = 100; } //Refill P1 armor after move whiffed if (P1Prop.HitDetect.Actions.acceptSuper && !P2inCombo && (P1Prop.HitDetect.anim.GetCurrentAnimatorStateInfo(0).IsName("IdleStand") || P1Prop.HitDetect.anim.GetCurrentAnimatorStateInfo(0).IsName("Jump") || P1Prop.HitDetect.anim.GetCurrentAnimatorStateInfo(0).IsName("IdleCrouch"))) { P1Prop.armor = 4; P1Prop.durability = 100; } //Refill P2 armor after move whiffed if (P2Prop.HitDetect.Actions.acceptSuper && !P1inCombo && (P2Prop.HitDetect.anim.GetCurrentAnimatorStateInfo(0).IsName("IdleStand") || P2Prop.HitDetect.anim.GetCurrentAnimatorStateInfo(0).IsName("Jump") || P2Prop.HitDetect.anim.GetCurrentAnimatorStateInfo(0).IsName("IdleCrouch"))) { P2Prop.armor = 4; P2Prop.durability = 100; } } //Update Health settings from menu P1ValorSetting = PracticeModeSettings.GetComponent <PauseMenu>().P1Valor; P2ValorSetting = PracticeModeSettings.GetComponent <PauseMenu>().P2Valor; //Refill Health Meters/Manage whiff detection for Armor refill //Refill P1 HP after P2 combo finishes if (P1Prop.HitDetect.hitStun > 0) { P1inCombo = true; } if (P2Prop.HitDetect.comboCount == 0) { P1Prop.currentHealth = P1Prop.maxHealth * (P1ValorSetting / 100f); P1inCombo = false; P2CurrentHitDamage = 0; P1PrevHealth = P1Prop.currentHealth; P2CurrentComboTotalDamage = 0; } //Refill P2 HP after P1 combo finishes if (P2Prop.HitDetect.hitStun > 0 && refillCPUHealth) { P2inCombo = true; InputTimer = 0.0f; } if (P1Prop.HitDetect.comboCount == 0 && refillCPUHealth) { P2Prop.currentHealth = P2Prop.maxHealth * (P2ValorSetting / 100f); P2inCombo = false; P1CurrentHitDamage = 0; P2PrevHealth = P2Prop.currentHealth; P1CurrentComboTotalDamage = 0; } //Manage Hit/Combo Damage/Hit Type Display //Display Current hit damage/Current Combo damage/Current Hit Type if (P2Prop.currentHealth < P2PrevHealth) { P1CurrentHitDamage = P2PrevHealth - P2Prop.currentHealth; P1CurrentComboTotalDamage += P1CurrentHitDamage; P1HitDamage.text = "Damage: "; P1HitDamage.text += P1CurrentHitDamage; P1ComboDamage.text = "Total Damage: "; P1ComboDamage.text += P1CurrentComboTotalDamage; P1HitType.text = "Guard Level: "; if (P1Prop.HitDetect.guard == "Unblockable") { P1HitType.text += "Grab"; } else { P1HitType.text += P1Prop.HitDetect.guard; } P2PrevHealth = P2Prop.currentHealth; P2CurrentHitDamage = P2PrevHealth - P2Prop.currentHealth; P2CurrentComboTotalDamage += P1CurrentHitDamage; P2HitDamage.text = "Damage: "; P2HitDamage.text += P1CurrentHitDamage; P2ComboDamage.text = "Total Damage: "; P2HitType.text = "Guard Level: "; if (P1Prop.HitDetect.guard == "Unblockable") { P2HitType.text += "Grab"; } else { P2HitType.text += P1Prop.HitDetect.guard; } P2ComboDamage.text += P1CurrentComboTotalDamage; } if (HUD.Player1Hits.text == "" && P1Prop.HitDetect.comboCount != 1) { P1HitDamage.text = ""; P1HitType.text = ""; } if (HUD.Player2Hits.text == "" && P1Prop.HitDetect.comboCount != 1) { P2HitDamage.text = ""; P2HitType.text = ""; } //Update Highest Combo Damage if (P1CurrentComboTotalDamage > P1HighestComboDamage) { P1HighestComboDamage = P1CurrentComboTotalDamage; P1HighComboDamage.text = "Highest Combo Damage: "; P1HighComboDamage.text += P1HighestComboDamage; P2HighestComboDamage = P1CurrentComboTotalDamage; P2HighComboDamage.text = "Highest Combo Damage: "; P2HighComboDamage.text += P1HighestComboDamage; } //Handle Dummy State p1x = GameObject.Find("Player1").transform.GetChild(0).transform.position.x; p2x = GameObject.Find("Player2").transform.GetChild(0).transform.position.x; if (InputTimer > 0) { InputTimer -= Time.deltaTime; } else { InputTimer = 0; } //Determine P1 Current attack type to determine proper Guard guardLevel = Player1.GetComponentInChildren <AcceptInputs>().hitType; switch (dummyState) { case "CPU": MaxInput.enableAI(); MaxInputObject.GetComponent <AI>().enabled = true; break; case "Stand": MaxInput.ClearInput("Player2"); MaxInput.enableAI(); MaxInputObject.GetComponent <AI>().enabled = false; break; case "Crouch": MaxInput.ClearInput("Player2"); MaxInput.enableAI(); MaxInputObject.GetComponent <AI>().enabled = false; MaxInput.Crouch("Player2"); break; case "Jump": MaxInput.ClearInput("Player2"); MaxInput.enableAI(); MaxInputObject.GetComponent <AI>().enabled = false; if (InputTimer == 0 && !P2inCombo) { MaxInput.Jump("Player2"); InputTimer = 1.0f; } break; case "StandGuard": MaxInput.ClearInput("Player2"); MaxInput.enableAI(); MaxInputObject.GetComponent <AI>().enabled = false; if (p1x - p2x < 0) { MaxInput.MoveRight("Player2"); } else { MaxInput.MoveLeft("Player2"); } break; case "LowGuard": MaxInput.ClearInput("Player2"); MaxInput.enableAI(); MaxInputObject.GetComponent <AI>().enabled = false; if (p1x - p2x < 0) { MaxInput.DownRight("Player2"); } else { MaxInput.DownLeft("Player2"); } break; case "GuardAll": MaxInput.ClearInput("Player2"); MaxInput.enableAI(); MaxInputObject.GetComponent <AI>().enabled = false; if (p1x - p2x < 0) { if (guardLevel == "Low" && (p1x - p2x > -2)) { MaxInput.DownRight("Player2"); } else { MaxInput.MoveRight("Player2"); } } else { if (guardLevel == "Low" && (p1x - p2x < 2)) { MaxInput.DownLeft("Player2"); } else { MaxInput.MoveLeft("Player2"); } } break; case "Player": MaxInput.ClearInput("Player2"); MaxInput.disableAI(); break; } //CPU Air Tech Option if (enableCPUAirTech && dummyState != "Player" && dummyState != "CPU") { //Air tech if in combo and hitstun = 0 if (P2Prop.HitDetect.hitStun > 0 && Player2.transform.GetComponentInChildren <AcceptInputs>().airborne) { P2inAirTrueCombo = true; } else if (P2Prop.HitDetect.hitStun <= 0 && Player2.GetComponentInChildren <AcceptInputs>().airborne&& P2inAirTrueCombo) { MaxInput.Cross("Player2"); P2inAirTrueCombo = false; } } //CPU ground guard after first hit if (enableGuardAfterFirstHit && dummyState != "Player" && dummyState != "CPU") { //(On Ground) Guard if in combo, hitstun = 0, and Player is still in the middle of an attack if (P2Prop.HitDetect.hitStun > 0) { P2inGroundTrueCombo = true; } if (P2Prop.HitDetect.hitStun <= 0 && P2inGroundTrueCombo) { guardAfterTrueCombo = true; P2inGroundTrueCombo = false; } if (guardAfterTrueCombo) { if (p1x - p2x < 0) { if (guardLevel == "Low" && (p1x - p2x > -2)) { MaxInput.DownRight("Player2"); } else { MaxInput.MoveRight("Player2"); } } else { if (guardLevel == "Low" && (p1x - p2x < 2)) { MaxInput.DownLeft("Player2"); } else { MaxInput.MoveLeft("Player2"); } } if (!P1Prop.HitDetect.Actions.attacking) { guardAfterTrueCombo = false; } } } //Fix Animation bug with resetting positions if (fixAnimBug) { switch (GameObject.Find("PlayerData").GetComponent <SelectedCharacterManager>().P1Character) { case "Dhalia": resetDhalia(Player1); break; case "Achealis": resetAchealis(Player1); break; } switch (GameObject.Find("PlayerData").GetComponent <SelectedCharacterManager>().P2Character) { case "Dhalia": resetDhalia(Player2); break; case "Achealis": resetAchealis(Player2); break; } fixAnimBug = false; InputTimer = 0.0f; } //Reset Positions back to start if (Input.GetButtonDown(inputSelect)) // Temporarily changed to P2 { resetPositions(); //Reset Character Specific things switch (GameObject.Find("PlayerData").GetComponent <SelectedCharacterManager>().P1Character) { case "Dhalia": resetDhalia(Player1); break; case "Achealis": resetAchealis(Player1); break; } switch (GameObject.Find("PlayerData").GetComponent <SelectedCharacterManager>().P2Character) { case "Dhalia": resetDhalia(Player2); break; case "Achealis": resetAchealis(Player2); break; } fixAnimBug = true; } if (GameObject.Find("PlayerData").GetComponent <SelectedCharacterManager>().gameMode == "Practice") { // Recording if (Input.GetButtonDown(inputL3) && !isReplaying) { recording++; //L3 } switch (recording) { case 1: // Switch player controls RecordingDisplay.SetActive(true); RecordingState.text = "Recording Armed"; isRecording = true; switchControls(true); break; case 2: // Get inputs from MaxInput. returnMovement() returnInputs() RecordingState.text = "Now Recording " + recordingFrame; recordingFrame++; List <float> getMoves = MaxInput.returnMovement("Player1"); List <bool> getInputs = MaxInput.returnInputs("Player1"); movement.Add(getMoves); inputs.Add(getInputs); break; case 3: // Create a txt file that has all the inputs for each frame RecordingState.text = "Recording Saved"; switchControls(false); saveRecording(); isRecording = false; recording = 0; recordingFrame = 0; break; } // Replaying the Recording if (Input.GetButtonDown(inputR3) && !isReplaying && !isRecording) //R3 { isReplaying = true; reader = new StreamReader(path); string temp = reader.ReadLine(); if (temp == "True") { faceLeft = true; } else { faceLeft = false; } } if (isReplaying) { // Read file, execute MaxInput actions every frame string line; if ((line = reader.ReadLine()) != null) { RecordingState.text = "Replaying " + recordingFrame; MaxInput.ClearInput("Player2"); replay(line); } else { isReplaying = false; recordingFrame = 0; reader.Close(); } } } } } }
// AI attacking player, attacking has it's own internal state system void attack() { calculateAttackWeights(); var rand = new System.Random().Next(101); // Random int from 0 to 100 var maxAttack = attackStates.Aggregate((l, r) => l.Value > r.Value ? l : r).Key; // Gets key with highest value Debug.Log(maxAttack); if (aiCharacter == "Dhalia") { // Attacks that hit low if (maxAttack == "Low") { // 5M if (rand <= 25 && triangleTimer <= 0) { MaxInput.Triangle("Player2"); circleTimer = .5f; } else { MaxInput.Crouch("Player2"); // 2L (doesn't actually hit low) if (rand > 25 && rand <= 50 && squareTimer <= 0) { MaxInput.Square("Player2"); crossTimer = .5f; } // 2M else if (rand > 50 && rand <= 70 && triangleTimer <= 0) { MaxInput.Triangle("Player2"); circleTimer = .5f; } // 2B else if (rand > 70 && rand <= 85 && crossTimer <= 0) { MaxInput.Cross("Player2"); squareTimer = .5f; if (noBreakTimer <= 0) { holdBreak(.8f); } } // Head rush (63214M) else if (rand > 85) { keepAction = "Triangle"; doingHCB = 1; AIInput.HCB(); if (noBreakTimer <= 0) { holdBreak(1.2f); } } else { MaxInput.Square("Player2"); } } } // Attacks that hit mid if (maxAttack == "Mid") { // 5L if (rand <= 35 && squareTimer <= 0) { doing5L_1 = 1; AIInput.combo5L_1(); //MaxInput.Square("Player2"); crossTimer = .5f; } // 2H else if (rand > 35 && rand <= 60 && circleTimer <= 0) { doing2H_1 = 1; AIInput.combo2H_1(); triangleTimer = .5f; } // 5H else if (rand > 60 && rand <= 85 && circleTimer <= 0) { MaxInput.Circle("Player2"); triangleTimer = .5f; } // 5B else if (rand > 85 && rand <= 98 && crossTimer <= 0) { MaxInput.Cross("Player2"); squareTimer = .5f; if (noBreakTimer <= 0) { holdBreak(.8f); } } // Judgment Sabre else if (rand > 98 && !isAirborne) { keepAction = "RBumper"; doingQCB = 1; AIInput.HCB(); } else { MaxInput.Square("Player2"); } } if (maxAttack == "Overhead") { // 6B if (rand > 50) { if (faceLeft == true) { MaxInput.MoveLeft("Player2"); } else { MaxInput.MoveRight("Player2"); } MaxInput.Cross("Player2"); if (noBreakTimer <= 0) { holdBreak(.8f); } } // Blood brave (214H) else { keepAction = "Circle"; doingQCB = 1; AIInput.QCB(); } } // If very close to the player, attempt to grab if (maxAttack == "Grab") { MaxInput.LBumper("Player2"); } // Attacking from a distance if (maxAttack == "Zone") { // Pastry Throw (236L) if (rand >= 1 && pastryTimer <= 0) { keepAction = "Square"; doingQCF = 1; AIInput.QCF(); pastryTimer = 3f; } // Toaster (236HB) else if (rand < 1 && armor >= 2) { keepAction = "RTrigger"; doingQCF = 1; AIInput.QCF(); } // If a pastry is already out, just move forward else if (pastryTimer > 0) { approach(); } } } else if (aiCharacter == "Achealis") { // Attacks that hit low if (maxAttack == "Low") { MaxInput.Crouch("Player2"); // 2L (doesn't actually hit low) if (rand <= 25 && squareTimer <= 0) { MaxInput.Square("Player2"); crossTimer = .5f; } // 2M else if (rand > 25 && rand <= 50 && triangleTimer <= 0) { MaxInput.Triangle("Player2"); circleTimer = .5f; } // 2H else if (rand > 50 && rand <= 75 && circleTimer <= 0) { MaxInput.Circle("Player2"); triangleTimer = .5f; } // 2B else if (rand > 75 && rand <= 90 && crossTimer <= 0) { MaxInput.Cross("Player2"); squareTimer = .5f; } // Level Hell (236M) else if (rand > 90) { keepAction = "Triangle"; doingQCF = 1; AIInput.QCF(); } else { MaxInput.Square("Player2"); } } // Attacks that hit mid if (maxAttack == "Mid") { // 5L if (rand <= 35 && squareTimer <= 0) { doing5L_1 = 1; AIInput.combo5L_1(); //MaxInput.Square("Player2"); crossTimer = .5f; } // 5M else if (rand > 35 && rand <= 70 && triangleTimer <= 0) { MaxInput.Triangle("Player2"); circleTimer = .5f; } // 5H else if (rand > 70 && rand <= 90 && circleTimer <= 0) { MaxInput.Circle("Player2"); triangleTimer = .5f; } // Heaven Climber (DP H/B) else if (rand > 90 && rand <= 95) { doingDP = 1; if (rand > 97) { keepAction = "Circle"; } else { keepAction = "Cross"; } AIInput.DP(); } // Starfall (214B) else if (rand > 95 && isAirborne) { keepAction = "Cross"; doingQCB = 1; AIInput.QCB(); } else { MaxInput.Square("Player2"); } } if (maxAttack == "Overhead") { if (crossTimer <= 0) { MaxInput.Cross("Player2"); squareTimer = .5f; } } // If very close to the player, attempt to grab if (maxAttack == "Grab") { MaxInput.LBumper("Player2"); } // Attacking from a distance if (maxAttack == "Zone") { approach(); } } }