public PartyTurnActor() { MoveAction moveAction = new MoveAction(m_activeActions); RotateAction rotateAction = new RotateAction(m_activeActions); RestAction restAction = new RestAction(); InteractAction interactAction = new InteractAction(); SelectNextInteractiveObjectAction selectNextInteractiveObjectAction = new SelectNextInteractiveObjectAction(); m_actions = new BaseAction[4][]; for (Int32 i = 0; i < m_actions.Length; i++) { m_actions[i] = new BaseAction[11]; m_actions[i][0] = moveAction; m_actions[i][1] = rotateAction; m_actions[i][6] = restAction; m_actions[i][2] = interactAction; m_actions[i][10] = selectNextInteractiveObjectAction; m_actions[i][3] = new MeleeAttackAction(i); m_actions[i][4] = new RangedAttackAction(i); m_actions[i][9] = new CastSpellAction(i); m_actions[i][5] = new ConsumeItemAction(i); m_actions[i][8] = new DefendAction(i); m_actions[i][7] = new EquipAction(i); } }
private static bool ResolveRangedAttack(RangedAttackAction action, EncounterState state) { Entity attacker = state.GetEntityById(action.ActorId); Entity defender = action.TargetEntity; var attackerComponent = attacker.GetComponent <AttackerComponent>(); var defenderComponent = defender.GetComponent <DefenderComponent>(); if (defenderComponent.IsInvincible) { var logMessage = string.Format("[b]{0}[/b] hits [b]{1}[/b], but the attack has no effect!", attacker.EntityName, defender.EntityName); LogAttack(attacker, defender, defenderComponent, logMessage, state); } else { // We don't allow underflow damage, though that could be a pretty comical mechanic... int damage = Math.Max(0, attackerComponent.Power - defenderComponent.Defense); defenderComponent.RemoveHp(damage); if (defenderComponent.CurrentHp <= 0) { var logMessage = string.Format("[b]{0}[/b] hits [b]{1}[/b] for {2} damage, destroying it!", attacker.EntityName, defender.EntityName, damage); // Assign XP to the entity that fired the projectile var projectileSource = state.GetEntityById(attackerComponent.SourceEntityId); var xpValueComponent = defender.GetComponent <XPValueComponent>(); if (projectileSource != null && xpValueComponent != null && projectileSource.GetComponent <XPTrackerComponent>() != null) { projectileSource.GetComponent <XPTrackerComponent>().AddXP(xpValueComponent.XPValue, attackerComponent, defenderComponent, state); logMessage += String.Format(" [b]{0}[/b] gains {1} XP!", projectileSource.EntityName, xpValueComponent.XPValue); } LogAttack(attacker, defender, defenderComponent, logMessage, state); ResolveAction(new DestroyAction(defender.EntityId), state); } else { var logMessage = string.Format("[b]{0}[/b] hits [b]{1}[/b] for {2} damage!", attacker.EntityName, defender.EntityName, damage); LogAttack(attacker, defender, defenderComponent, logMessage, state); } } return(true); }
public override Boolean CheckSpellConditions(Character p_sorcerer) { RangedAttackAction rangedAttackAction = new RangedAttackAction(p_sorcerer.Index); return(rangedAttackAction.ActionAvailable()); }
public override IEnumerator DetermineAction() { if (InputTracking.HasNextAction()) { Player.player.view.CollectEntities(Map.current); PlayerAction action = InputTracking.PopNextAction(); switch (action) { //Handle Movement code case PlayerAction.MOVE_UP: nextAction = new MoveAction(monster.location + Vector2Int.up); break; case PlayerAction.MOVE_DOWN: nextAction = new MoveAction(monster.location + Vector2Int.down); break; case PlayerAction.MOVE_LEFT: nextAction = new MoveAction(monster.location + Vector2Int.left); break; case PlayerAction.MOVE_RIGHT: nextAction = new MoveAction(monster.location + Vector2Int.right); break; case PlayerAction.MOVE_UP_LEFT: nextAction = new MoveAction(monster.location + new Vector2Int(-1, 1)); break; case PlayerAction.MOVE_UP_RIGHT: nextAction = new MoveAction(monster.location + new Vector2Int(1, 1)); break; case PlayerAction.MOVE_DOWN_LEFT: nextAction = new MoveAction(monster.location + new Vector2Int(-1, -1)); break; case PlayerAction.MOVE_DOWN_RIGHT: nextAction = new MoveAction(monster.location + new Vector2Int(1, -1)); break; case PlayerAction.WAIT: nextAction = new WaitAction(); break; case PlayerAction.DROP_ITEMS: Debug.Log("Dropping items!"); UIController.singleton.OpenInventoryDrop(); yield return(new WaitUntil(() => !UIController.WindowsOpen)); break; case PlayerAction.PICK_UP_ITEMS: //Intelligently pick up items, opening dialouge box if needed. PickupSmartDetection(); //Check if dialouge box is opened; if so, freeze until transaction is done if (UIController.WindowsOpen) { yield return(new WaitUntil(() => !UIController.WindowsOpen)); } break; case PlayerAction.OPEN_INVENTORY: UIController.singleton.OpenInventoryInspect(); yield return(new WaitUntil(() => !UIController.WindowsOpen)); break; case PlayerAction.EQUIP: UIController.singleton.OpenEquipmentInspect(); yield return(new WaitUntil(() => !UIController.WindowsOpen)); break; case PlayerAction.UNEQUIP: UIController.singleton.OpenEquipmentUnequip(); yield return(new WaitUntil(() => !UIController.WindowsOpen)); break; case PlayerAction.APPLY: UIController.singleton.OpenInventoryApply(); yield return(new WaitUntil(() => !UIController.WindowsOpen)); break; case PlayerAction.CAST_SPELL: UIController.singleton.OpenAbilities(); yield return(new WaitUntil(() => !UIController.WindowsOpen)); break; case PlayerAction.FIRE: nextAction = new RangedAttackAction(); break; case PlayerAction.ASCEND: if (AutoStairs(true)) { nextAction = new ChangeLevelAction(true); } else { //TODO: Highlight path to nearest stair! yield return(new WaitUntil(() => InputTracking.HasNextAction())); PlayerAction newAction = InputTracking.PopNextAction(); if (newAction == PlayerAction.ASCEND) { PathToNearestStair(true); } } break; case PlayerAction.DESCEND: if (AutoStairs(false)) { nextAction = new ChangeLevelAction(false); } else { //TODO: Highlight path to nearest stair! //TODO: This whole waiting and checking thing should be reworked //as a variant of the FindNearest Action yield return(new WaitUntil(() => InputTracking.HasNextAction())); PlayerAction newAction = InputTracking.PopNextAction(); if (newAction == PlayerAction.DESCEND) { PathToNearestStair(false); } } break; case PlayerAction.AUTO_ATTACK: nextAction = new AutoAttackAction(); break; case PlayerAction.AUTO_EXPLORE: nextAction = new AutoExploreAction(); break; //Handle potentially weird cases (Thanks, Nethack design philosophy!) case PlayerAction.ESCAPE_SCREEN: //TODO: Open up the pause menu screen here RogueUIPanel.ExitTopLevel(); //This really, really shouldn't do anything. Let it happen, though! break; case PlayerAction.ACCEPT: case PlayerAction.NONE: Debug.Log("Player read an input set to do nothing", this); break; default: Debug.LogError($"Player read an input that has no switch case: {action}"); break; } } }