IEnumerator ExecuteTurn() { while (actionsRemaining) { StartCoroutine(AssessActions()); if (currentAction != null) { inAction = true; if (currentAction.moveTarget != actor.currentLocation) { path = Pathfinder.GetPath(actor.currentLocation, currentAction.moveTarget); movementPenalty = actor.MovementLockPenalty(); actor.Move(path, currentAction.moveTarget, movementPenalty); yield return(new WaitForSeconds(2f)); } string text = actor.unitName + " used " + actor.abilityController.GetAbilityName(currentAction.abilityIndex) + "."; actor.guiController.ClearLogText(); actor.guiController.SetBattleLogText(text); bool crit = actor.abilityController.HasCrit(currentAction.abilityIndex); targetCells = actor.abilityController.GetArea(currentAction.abilityIndex, currentAction.abilityTarget); actor.abilityController.UseAbility(currentAction.abilityIndex, targetCells, currentAction.abilityTarget, crit); currentAction = null; inAction = false; yield return(new WaitForSeconds(2f)); } } }
private int EstimateDamage(Unit actor, AiAction action) { int damage = actor.abilityController.EstimateTotalDamage(action.abilityIndex, action.abilityTarget.currentUnit); //float percentOfRemainingHealth = ((float)damage / (float)action.abilityTarget.currentUnit.stats.hp) * 100f; //int score = Mathf.RoundToInt (percentOfRemainingHealth * 0.5f); return(damage); }
private IEnumerator AssessActions() { if (!inAction) { actions.Clear(); movementPenalty = actor.MovementLockPenalty(); movementRange = Pathfinder.GetMoveRange(actor.currentLocation, actor.stats.mp - movementPenalty); movementRange.Add(actor.currentLocation); for (int i = 0; i < actor.abilityController.abilityInfo.Count; i++) { if (actor.abilityController.CanUse(i)) { foreach (GridCell moveCell in movementRange) { HashSet <GridCell> abilityRange = actor.abilityController.GetRangeFrom(i, moveCell, true); foreach (GridCell rangeCell in abilityRange) { if (actor.abilityController.CanUseOnCell(i, rangeCell)) { if (actor.abilityController.HasArea(i)) { targetCells = actor.abilityController.GetArea(i, rangeCell); // foreach (GridCell areaCell in targetCells) { // if (areaCell.currentUnit != null) { // if (!actor.IsAlly (areaCell.currentUnit)) { // AddAction (i, moveCell, rangeCell, targetCells); // } // } // } } else { if (rangeCell.currentUnit != null) { AddAction(i, moveCell, rangeCell); } } } } } } } //Debug.Log ("Assesment Complete - Action count: " + actions.Count); if (actions.Count > 0) { actions = actions.OrderByDescending(x => x.actionScore).ToList(); currentAction = actions [0]; } else { actionsRemaining = false; CheckFinalMovementOptions(); } } yield return(null); }
void DetectSmartObject() { RaycastHit hit; _RayDirection = _FollowTransform.position - transform.position; if ((Vector3.Angle(_RayDirection, transform.forward)) < _FieldOfView) { if (Physics.Raycast(transform.position, _RayDirection, out hit, _ViewDistance)) { enum_SmartObject smartObject = hit.collider.GetComponent <enum_SmartObject>(); Debug.Log(gameObject.name + ": " + hit.collider.gameObject.name); if (smartObject != null) { if (smartObject.GetSmartObject() == _SmartObject) { switch (_SmartObject) { case SmartObject.TRAFFIC_LIGHT: if (hit.transform.gameObject.GetComponent <scr_Traffic_Light>().GetIsGreen()) { gameObject.GetComponentInParent <scr_moving_object>().enabled = true; } else { gameObject.GetComponentInParent <scr_moving_object>().enabled = false; } break; case SmartObject.PLAYER: Debug.Log("Player"); aiAction = cls_AI_Action.Chase; break; default: ; break; } } } else { ResetAction(); } } else { ResetAction(); } } else { ResetAction(); } }
public void StartTurn() { movementPenalty = 0; currentAction = null; path.Clear(); actionsRemaining = true; inAction = false; if (actor.stats.ap > 0) { StartCoroutine(ExecuteTurn()); } }
public override void AssessAction(Unit actor, AiAction action) { float score = action.actionScore; int actionCostPenalty = (action.apCost * 2) + (action.mpCost * 2); score -= actionCostPenalty; action.actionScore = Mathf.RoundToInt(score); }
private void AddAction(int index, GridCell move, GridCell target, HashSet <GridCell> area = null) { int mpCost = 0; if (move != actor.currentLocation) { mpCost = Pathfinder.GetPath(actor.currentLocation, move).Count(); } AiAction act = new AiAction(index, move, actor.abilityController.GetApCost(index), mpCost, target, area); aiBehaviour.AssessAction(actor, act); actions.Add(act); }
private void ResetNextActTimes(AiAction currentAction) { // 只有移動不需要等待延遲(且移動不算是實際的行動數) if (lastAction.actionType == AiActionType.Move) { return; } float delay = currentAction.offsetActionDelay + currentAction.AdditionActionDelay; if (delay <= 0) { delay = 0.02f; // 行動下限延遲 } nextActTimes = Time.time + delay; cumulativeActionCount++; // 行動次數+1 }
public void ReturnDefaultAction(bool setToLastAction = false) { if (defaultAction == null) { return; } if (lastAction != null && lastAction.actionType == AiActionType.Idle) { return; } defaultAction.GetCurrentAIHavior(this); defaultAction.StartActHaviour(); if (setToLastAction) { lastAction = defaultAction; } }
private int EstimateDamageInArea(Unit actor, AiAction action) { int allyDamage = 0; int enemyDamage = 0; foreach (GridCell cell in action.area) { if (cell.currentUnit != null) { if (cell.currentUnit.IsAlly(actor)) { allyDamage += EstimateDamage(actor, action); } else { enemyDamage += EstimateDamage(actor, action); } } } //Debug.Log (enemyDamage + " - " + allyDamage); return(enemyDamage - allyDamage); }
/// <summary> /// 動作執行 /// </summary> /// <param name="action">要執行的動作</param> public void DoAction(AiAction action, bool influenceWeight) { // Start Action lastActionSuccess = action.StartActHaviour(); if (lastActionSuccess) { lastAction = action; // To do linked actions bool trigger. if (lastAction.linkedActions.Length > 0) { toDoLinkedActions = true; } // Reset action delay. ResetNextActTimes(action); } if (influenceWeight) { float amount; if (lastActionSuccess) { amount = action.minusWeightAmountAfterAction; } else { amount = action.minusWeightAmountWhenNotSuccess; } if (amount > 0) { // 動作結束後,權重將下降N點,降低這個對於動作的慾望 action.currentActionWeight -= amount; action.AddDiffCount(amount); } } }
private void ResetAction() { switch (_InitialAction) { case AI_ACTIONS.DO_NOTHING: aiAction = cls_AI_Action.DoNothing; break; case AI_ACTIONS.WANDER: aiAction = cls_AI_Action.Wander; break; case AI_ACTIONS.CHASE: cls_AI_Action.GetNextPosition(); aiAction = cls_AI_Action.Chase; break; default: aiAction = cls_AI_Action.DoNothing; break; } Debug.Log("reset"); }
private void Think() { if (Brain == null || !Brain.MoveNext()) this.SelectBehavior(); var result = Brain.Current; if (result is bool && !(bool)result) { CurrentAction = null; } }
protected void SelectBehavior() { var matches = GetPotentialActions(); CurrentAction = matches.Count == 0 ? null : matches[rnd.Next(0, matches.Count)].Key; if (CurrentAction == null) { //Logger.Warning("AI " + this.Creature.RaceInfo.AI + " does not define a condition. Using wait instead"); // TODO: Dump state CurrentAction = new AiAction(null, NullBehavior); } }
public abstract void AssessAction(Unit actor, AiAction action);