/// <summary> /// Action for this option in the menu. /// </summary> /// <param name="item">Item.</param> public void Action(CharAbility ability) { //Update index for next dialogue thread //Dialogue option selected so close callout SpeechUIManager._instance.CloseResponseBox(); }
public void SetAbility(GameObject abilityPrefab) { GameObject abilitySelected = Instantiate(abilityPrefab, new Vector2(0f, 0f), Quaternion.identity) as GameObject; abilitySelected.transform.SetParent(playerCharacter.GetCombatController().transform, false); currentAbility = abilitySelected.GetComponent <CharAbility>(); currentAbility.InitialiseMe(playerCharacter); SetAttackCursor(); }
public NPCCombatTurn ChooseCombatAction(CharMgrScript npc, List <CharMgrScript> possibleTargets) { NPCCombatTurn thisTurn = new NPCCombatTurn(); //TODO: Implement logic for NPC combat action selection int actChoiceProb = Random.Range(0, 100); int subSelectionProb = Random.Range(0, 100); //Choose action based on the NPC's internal logic GameConstants.ActionOptionIndices selectedAction = this.ChooseAction(npc, actChoiceProb); //Create list that will hold targets and their priority List <PrioritizedTarget> weightedTargets = new List <PrioritizedTarget>(); List <CharMgrScript> randomTargets = new List <CharMgrScript>(); CharAbility turnAbility = new CharAbility(); /*Generate list of all targets based on a conditional statement based off the chosen action by the NPC*/ switch (selectedAction) { case (GameConstants.ActionOptionIndices.Ability): break; case (GameConstants.ActionOptionIndices.Attack): //Get reference to the npc's attack turnAbility = npc.GetBasicAttack(); //Get list of targets that the attack effects randomTargets = this.GetNPCTargets(turnAbility, CombatMgr._instance.PlayerParty); break; default: Debug.Log("Selected action was" + selectedAction.ToString() + " and NPC Turn Switch Fell through - Performing default action"); break; } //Add priorities to targets from above selection and put them into a list TODO: prioitize via function foreach (CharMgrScript target in randomTargets) { weightedTargets.Add(new PrioritizedTarget(100, target)); } //TODO perform some function to prioritize list of targets and grab the preffered one List <CharMgrScript> turnTargets = new List <CharMgrScript>(); foreach (PrioritizedTarget t in weightedTargets) { turnTargets.Add(t.target); } //Set the fields of the created turn and return it thisTurn.SelectedAbility = turnAbility; thisTurn.SelectedTargets = turnTargets; thisTurn.SelectedAction = selectedAction; //return the created turn data return(thisTurn); }
/// <summary> /// Sets the display elements. /// </summary> /// <param name="item">The item to which this object corresponds.</param> public void SetDisplayElements(CharAbility ability) { if (bgImage == null) { bgImage = GetComponentInChildren <Image>(); } //Get color to be used for selection state StartingColor = bgImage.color; //Set display text to match response text this.gameObject.GetComponent <Text>().text = ability.AbilityName; }
public void OnMouseOver() { Inspect(); if (!clicked) { if (selectionCircle == null) { combatUI = FindObjectOfType <CombatUI>(); abilitySelected = combatUI.GetCurrentAbility(); DisplayCircle(); } } }
/// <summary> /// Gets the basic attack of this character. /// </summary> /// <returns>The basic attack.</returns> public CharAbility GetBasicAttack() { CharAbility attack = new CharAbility(); //Iterate through the character's abilities and find the ability with type => basic attack foreach (CharAbility a in this.stats.CombatAbilities) { if (a.aType == GameConstants.AbilityType.BasicAttack) { attack = a; return(a); } } Debug.LogWarning("No attack found!"); return(attack); }
public List <CharMgrScript> GetPossibleTargets(CharMgrScript currChar, CharAbility ability, bool playerParty) { //Pass in ability script, check who is taking their tun and the ability to get the possible targets, then return them as a list List <CharMgrScript> possTargets = new List <CharMgrScript>(); /*Check the target type of the ability and based on the type return the correct targets*/ switch (ability.TType) { case (GameConstants.TargetType.EnemyParty): //Case for hitting whole party break; case (GameConstants.TargetType.SingleEnemy): //Single enemy attack type so get next item in correct list and return it if (playerParty) { //If it's the player's party then the npc party of enemies are possible targets - NOTE: Excluding downed/dead characters possTargets = this.EnemyParty.FindAll(x => x.stats.Status != GameConstants.StatusType.Downed); if (TestScript._instance.TestMode) { Debug.Log("POSSIBLE TARGETS OBTAINED! cOUNT IS:" + possTargets.Count); } } else { } break; case (GameConstants.TargetType.Party): break; case (GameConstants.TargetType.Ally): break; case (GameConstants.TargetType.Self): break; default: break; } return(possTargets); }
public void ProcessAbilityTest(CharAbility ability) { //queuedAbility = ability; EnableSubmitBtn(); SetSubmitBtnText("Submit answer"); SetObjectPortrait(playerCharacter.GetCombatController().GetCurrentEnemyTarget().CharacterPortrait); SetDialogueReasonSymbol(ability.myIcon); InsertSpacer(); TestTrigger testTrigger = new TestTrigger(ability.GetMyName(), ability.GetMyIcon(), TestTrigger.TriggerType.Ability); currentDialogueTestData = new DialogueTestDataController(testTrigger, playerCharacter.CharacterName); GameObject dialogueNode = BuildDialogueNode(currentDialogueTestData.GetVocabIntro()); //text instruction to player InsertDialogueNode(dialogueNode); InsertVocabTestNode(currentDialogueTestData.GetPlayerVocab()); DisplayGrammar(); InsertPlayerInputField(); SetInUse(); }
public List <CharMgrScript> GetNPCTargets(CharAbility currAbility, List <CharMgrScript> possibleTargets) { //populate the values from the list into an array so that there aren't unintended side effects List <CharMgrScript> pTargets = new List <CharMgrScript>(); for (int i = 0; i < possibleTargets.Count; i++) { pTargets.Add(possibleTargets[i]); } //Instantiate a base number of targets to use int numTargets = 0; //Determine the number of targets based off the given ability's targeting type switch (currAbility.TType) { case (GameConstants.TargetType.SingleEnemy): numTargets = 1; break; case (GameConstants.TargetType.EnemyParty): numTargets = pTargets.Count; break; default: break; } //List to hold the targets selected List <CharMgrScript> selectedTargets = new List <CharMgrScript>(); for (int i = 0; i < numTargets; i++) { //Generate a random index to grab the associated unit int selectedIndex = Random.Range(0, pTargets.Count); //Add the unit associated with the randomly selected index selectedTargets.Add(pTargets[selectedIndex]); //remove the selected target from the list of possible targets to avoid overlapping selection pTargets.RemoveAt(selectedIndex); } //Return the list of generated targets return(selectedTargets); }
/// <summary> /// Handles the logic of a character making an attack. /// </summary> /// <param name="attack">Attack.</param> /// <param name="targets">Targets.</param> public void PerformAttack(CharAbility attack, List <CharMgrScript> targets) { //Hide selection arrows CombatUIManager._instance.HideSelectionArrows(); //Handle animation and dynamic input in coroutine CombatUIManager._instance.MenuLevel = GameConstants.CombatMenuPage.AnimationAction; if (targets != null) { Debug.Log("In Perform Attack and target count is: " + targets.Count.ToString()); } else { Debug.Log("In Perform attack and Targets list is null!!"); } if (attack != null) { Debug.Log("In Perform Attack and attack is: " + attack.AbilityName.ToString()); } //TODO: fix error here StartCoroutine(CombatAnimInput(attack, targets)); }
public void RemoveCurrentAbility() { currentAbility = null; SetCursorDefault(); }
IEnumerator CombatAnimInput(CharAbility attack, List <CharMgrScript> targets) { float runTime = 2.0f; float holdTime = 1.0f; bool combatantsChecked = false; List <CharMgrScript> downedCombatants = new List <CharMgrScript>(); //Star position of the casting caracter Vector3 startPos = this.currentTurnChar.transform.position; //Target move position of the casting character Vector3 charTargetPos = Vector3.zero; //Position of an enemy that will be used for positioning the character currently using an ability Vector3 enemyPos = Vector3.zero; //multiplied by the offset subtracted during positioning to offset the character in the right direction int combatOffsetDir = this.PlayerParty.Contains(currentTurnChar) ? 1 : -1; //Make an evaluation of the attack's range type for positioning the character switch (attack.RType) { case (GameConstants.RangeType.Melee): /*Create target position vector in melee range by offseting from the target's position by half the character's sprite width*/ //Get reference to the first target as a starting point if (targets[0] != null) { enemyPos = targets[0].transform.position; } //Offset character's x half a sprite size to avoid overlap - TODO: Establish 'battle sides' for characters set at at start of battle Debug.Log("Rect width in offset is: " + this.currentTurnChar.stats.charSprite.rect.width.ToString()); float boundsWidth = this.currentTurnChar.gameObject.GetComponent <SpriteRenderer>().bounds.center.x - this.currentTurnChar.gameObject.GetComponent <SpriteRenderer>().bounds.extents.x; Debug.Log("Bound width in offset is: " + boundsWidth.ToString()); float extentsWidth = this.currentTurnChar.gameObject.GetComponent <SpriteRenderer>().bounds.extents.x; Debug.Log("Extents width IS: " + extentsWidth.ToString()); charTargetPos = new Vector3(enemyPos.x - (extentsWidth * 4 * combatOffsetDir), enemyPos.y); break; case (GameConstants.RangeType.Ranged): break; default: //No match found so case fell through Debug.LogWarning("No Range Type found in Case Statement"); break; } //Estimated one way travel time for this character to reach the float travelTime = Vector3.Distance(startPos, charTargetPos) / this.combatAnimMoveSpeed; //Determine end time by adding travel time to current time float endTime = Time.time + travelTime; //Mark start time for lerp step float startTime = Time.time; //Debug statement Debug.Log(" ### Travel Time: " + travelTime); Debug.Log(" ### End Time calculated: " + endTime); //Lerp move the attacking character to the necessary position while (Time.time < endTime) { //Obtain new position via lerp between start and target pos Vector3 newPos = Vector3.Lerp(startPos, charTargetPos, (Time.time - startTime) / travelTime); //Update the ability using character's psoition this.currentTurnChar.transform.position = newPos; //Yield control during loop yield return(null); } //Make sure end pos is full movement this.currentTurnChar.transform.position = charTargetPos; //Handle the lerp pushback of affected character // Hold attacking character at the target location for the duration necessary to animate and perform ability effects float holdEndTime = Time.time + holdTime; while (Time.time < holdEndTime) { yield return(null); } //Apply damage to characters foreach (CharMgrScript c in targets) { //TODO: Move this to separate method, add alpha flash if (c.TeamDirection == GameConstants.COMBAT_DIR_RIGHT_SIDE) { //Play hit animation and alpha flash c.GetComponent <Animator>().SetTrigger("HitImpRight"); } else { //Play hit animation and alpha flash c.GetComponent <Animator>().SetTrigger("HitImpLeft"); } //Damage for basic attacks is the attacks base damage * the character's offense => TODO: May be better to pass characters as reference, not saved as a variable c.stats.HP -= attack.BaseDamage * this.currentTurnChar.stats.Strength; } //Check for any combatants who were downed in the ability while (combatantsChecked == false) { downedCombatants = CheckDownedCombatants(ref combatantsChecked); yield return(null); } //Iterate through list of downed combatants, if there are any, play dying animation if (downedCombatants != null && downedCombatants.Count != 0) { foreach (CharMgrScript c in downedCombatants) { c.EnterDownedState(); //Remove downed enemies for now - note that may need to keep them here if we want to revive them //Note - may need to add a check for animation completions yield return(null); } } CombatUIManager._instance.UpdateHPText(); //TODO: Handle reset of UI and end of turn checks (character's removed from battle, battle win/loss conditions) **** //Reset ending time to current time plus travel time endTime = Time.time + travelTime; //Reset start time to current time startTime = Time.time; //Lerp character for the necessary duration while (Time.time < endTime) { //Obtain new position via lerp between start and target pos Vector3 newPos = Vector3.Lerp(charTargetPos, startPos, (Time.time - startTime) / travelTime); //Update the ability using character's psoition this.currentTurnChar.transform.position = newPos; //Yield control from this while loop yield return(null); } //Make sure end pos is full movement this.currentTurnChar.transform.position = startPos; /*Handle UI menu reset and other flag resolutions so next character can start thier turn*/ EndCombatTurn(); }
/// <summary> /// Gets the next targets. /// </summary> /// <returns>The next targets.</returns> /// <param name="currChar">Curr char.</param> /// <param name="ability">Ability.</param> /// <param name="currTargets">Curr targets.</param> /// <param name="playerParty">If set to <c>true</c> then attacking character is a member of the player party.</param> /// <param name="dir">Value should be either 1 or -1. This is the direction the selection is moving in the list</param> public List <CharMgrScript> GetNextTargets(CharMgrScript currChar, CharAbility ability, List <CharMgrScript> currTargets, List <CharMgrScript> possTargets, bool playerParty, int dir) { //Pass in ability script, check who is taking their tun and the ability to get the possible targets, then return them as a list List <CharMgrScript> nextTargets = new List <CharMgrScript>(); int numTargets; /*Check the target type of the ability and based on the type return the correct targets*/ switch (ability.TType) { case (GameConstants.TargetType.EnemyParty): numTargets = EnemyParty.Count; //Case for hitting whole party break; case (GameConstants.TargetType.SingleEnemy): //For now, use hard coded value, later can look into building this into the ability class numTargets = 1; //Single enemy attack type so get next item in correct list and return it if (playerParty) { //If it's the player's party then get a script from npc party as the enemy if (currTargets == null || currTargets.Count == 0) { if (TestScript._instance.TestMode) { Debug.Log("GetNextTargets -> retreived first from list because currTargets was null"); } //IF no targets currently just grab the first item from the list //CharMgrScript nTarget = this.EnemyParty[0]; CharMgrScript nTarget = possTargets[0]; nextTargets.Add(nTarget); } else { /* * Otherwise find the greatest index of the curr targets, * use it as starting index, increase count by 'number of targets' */ int startingIndex = -1; //Find the 'largest' index from current targets to use as a starting point foreach (CharMgrScript c in currTargets) { // if (this.EnemyParty.IndexOf(c) > startingIndex) // { // startingIndex = this.EnemyParty.IndexOf(c); // } if (possTargets.IndexOf(c) > startingIndex) { startingIndex = possTargets.IndexOf(c); } } for (int i = 0; i < numTargets; i++) { if (startingIndex + dir >= possTargets.Count) { //Reset starting index to avoid being out of bounds startingIndex = 0; //Remove dir because we've rotated around the list dir = 0; } else if (startingIndex + dir < 0) { //Reset starting index to avoid being out of bounds startingIndex = possTargets.Count - 1; //Remove dir because we've rotated around the list dir = 0; } CharMgrScript nTarget = possTargets[startingIndex + dir]; nextTargets.Add(nTarget); } } } else { //Handle enemy attack selection? } break; case (GameConstants.TargetType.Party): numTargets = PlayerParty.Count; break; case (GameConstants.TargetType.Ally): numTargets = 1; break; case (GameConstants.TargetType.Self): break; default: break; } return(nextTargets); }
public NPCCombatTurn(GameConstants.ActionOptionIndices sAction, List <CharMgrScript> targets, CharAbility cAbility) { this.SelectedAction = sAction; this.SelectedTargets = targets; this.SelectedAbility = cAbility; }
//Is this being used? TODO public CharAbility ChooseAbility() { CharAbility selectedAbility = new CharAbility(); return(selectedAbility); }