public CharacterRangedAttackAbillityAction(RangedAttackAbility ability, RangedWeapon weapon) { this.target = ability.target; this.velocity = ability.targetVelocity; this.timeOfFlight = ability.timeOfFlight; this.spawnDelay = ability.spawnDelay; this.projectile = ability.projectile; this.baseDamage = weapon.baseDamage + ability.baseDamage; this.damageModifer = ability.damageModifier; this.projectileSpawn = ability.weapon.projectileSpawn; }
private bool tryHitTarget(RangedAttackAbility rangedAttack, Vector3 position, Frame target, out Vector3 force, int steps) { float velocity = rangedAttack.weapon.range / 2.0f; float velocityStep = velocity / (float)steps; Vector3 direction = target.position - position; direction.y = 0.0f; float distance = direction.magnitude; direction.Normalize(); for (int i = 0; i < steps + 1; i++) { if (ProjectileUtils.canHitCoordinate(distance, 0.0f, velocity)) { float angle1 = ProjectileUtils.calculateAngle1ToHitCoordinate(distance, 0.0f, velocity); float angle2 = ProjectileUtils.calculateAngle2ToHitCoordinate(distance, 0.0f, velocity); if (ProjectileUtils.tryHitWithBallisticCast(target, position, velocity * direction, angle1, out force)) { return(true); } if (ProjectileUtils.tryHitWithBallisticCast(target, position, velocity * direction, angle2, out force)) { return(true); } if (!hasFallback) { fallbackPosition = position; fallBackVelocity = force; hasFallback = true; } } velocity += velocityStep; } force = Vector3.negativeInfinity; return(false); }
public override void UpdateCombatControls() { if (GameController.state == GameState.Combat) { if (character.isIdle) { if (obstacle.enabled) { obstacle.enabled = false; return; } if (character.remainingActions > 0) { RangedAttackAbility rangedAttack = character.GetCastableAbilities <RangedAttackAbility>() .OrderByDescending(m => m.threatRating).FirstOrDefault(); if (rangedAttack != null) { target = CharacterUtils.GetClosestCharacter(GameController.instance.party, character.position); if (target != null) { NeverdawnCamera.AddTargetLerped(target.transform); hasFallback = false; float distance = Vector3.Distance(character.position, target.position); if (distance > rangedAttack.weapon.estimatedRange + character.remainingSteps) { if (character.remainingSteps > 0.0f) { character.PushAction(new CharacterNavigateToAction(target.position, character.remainingSteps, false, rangedAttack.weapon.estimatedRange - 0.1f)); } else { GameController.instance.combatController.EndTurn(this); return; } } else { // Get positions and sort by strategic value (furthest away from target!) List <Vector3> positions = sampleSurroundings(20, character.remainingSteps); positions = positions.OrderByDescending(p => Vector3.Distance(p, target.position)).ToList(); // No position found yet! bool hasPosition = false; Vector3 targetPosition = Vector3.negativeInfinity; Vector3 targetVelocity = Vector3.negativeInfinity; Vector3 force; foreach (Vector3 position in positions) { Vector3 direction = target.position - position; direction.y = 0.0f; direction.Normalize(); launchTransform.position = position; launchTransform.forward = direction; Vector3 launchPosition = launchTransform.TransformPoint(rangedAttack.weapon.projectileSpawn); if (tryHitTarget(rangedAttack, launchPosition, target.frame, out force, 5)) { targetPosition = position; targetVelocity = force; hasPosition = true; break; } } if (hasPosition) { rangedAttack.targetVelocity = targetVelocity; rangedAttack.caster = character; character.PushAction(new CharacterNavigateToAction(targetPosition, character.remainingSteps, false)); character.PushAction(rangedAttack.Prepare()); character.PushAction(rangedAttack.Cast()); } else { if (hasFallback) { rangedAttack.targetVelocity = fallBackVelocity; rangedAttack.caster = character; character.PushAction(new CharacterNavigateToAction(fallbackPosition, character.remainingSteps, false)); character.PushAction(rangedAttack.Prepare()); character.PushAction(rangedAttack.Cast()); } else { GameController.instance.combatController.EndTurn(this); } } } } else { GameController.instance.combatController.EndTurn(this); } } else { EndCombatTurn(); } } else { if (target) { NeverdawnCamera.RemoveTargetLerped(target.transform); } EndCombatTurn(); } } } if (character.isIdle) { if (!obstacle.enabled) { obstacle.enabled = true; } } }