// current = current angle, radians. // target = target angle, radians. // speed = max radians turned per second. // Returns the new angle in radians, range [0,2pi]. public static DReal CalculateNewAngle(DReal currentAngle, DReal targetAngle, DReal speed) { var turnSpeedTicks = speed * ComSat.tickRate; targetAngle = DReal.Mod(targetAngle, DReal.TwoPI); // Turn towards heading. var angleDiff = DReal.Mod(currentAngle - targetAngle, DReal.TwoPI); int sign; DReal distance; if (angleDiff > DReal.PI) { sign = 1; distance = DReal.TwoPI - angleDiff; } else { sign = -1; distance = angleDiff; } if (distance > turnSpeedTicks) { currentAngle += turnSpeedTicks * sign; } else { currentAngle = targetAngle; } return(DReal.Mod(currentAngle, DReal.TwoPI)); }
void TickUpdate() { ComSat.Trace(this, "TickUpdate"); if(!powerSink.poweredOn) { target = null; audio.Stop(); return; } if(!ComSat.EntityExists(target)) { // Magic. Destroyed GameObjects compare against null. // Explicitly set to null to avoid keeping it around. target = null; audio.Stop(); // Search for victims. target = ComSat.FindEntityWithinRadius(entity.position, attackRange, entity.team); if(target != null) { audio.Play(); } } else { var dp = target.position - entity.position; DReal targetTurretAngle; var projectileProjectile = projectilePrefab.GetComponent<Projectile>(); if(projectileProjectile != null && powerSink.Powered()) { var aimSpot = Utility.PredictShot(entity.position, projectileProjectile.initialSpeed, target.position, target.velocity); targetTurretAngle = DReal.Mod(DVector2.ToAngle(aimSpot - entity.position) - entity.rotation, DReal.TwoPI); } else { targetTurretAngle = DReal.Mod(DVector2.ToAngle(dp) - entity.rotation, DReal.TwoPI); } // Turn turret to point at target. TurnTurret(targetTurretAngle); // Fire when pointing the gun at the target. if(targetTurretAngle == turretRotation) { Fire(); } // Stop shooting when out of range. if(dp.sqrMagnitude >= attackRange * attackRange) { audio.Stop(); target = null; } } if(fireDelay > 0) { fireDelay -= ComSat.tickRate; } }
void TickUpdate() { ComSat.Trace(this, "TickUpdate"); if (combatVehicle.mode == CombatVehicle.Mode.IDLE) { combatVehicle.mode = CombatVehicle.Mode.MOVE; combatVehicle.destination = entity.position; } if (ComSat.EntityExists(combatVehicle.target)) { var dist = combatVehicle.target.position - entity.position; var sqrDist = dist.sqrMagnitude; var targetAngle = DReal.Mod(DVector2.ToAngle(dist), DReal.TwoPI); // Get targetAngle within +/- pi of entity.rotation. if (targetAngle < entity.rotation - DReal.PI) { targetAngle += DReal.TwoPI; } else if (targetAngle > entity.rotation + DReal.PI) { targetAngle -= DReal.TwoPI; } if (sqrDist < missileRange * missileRange) { FireMissile(); } if (sqrDist < gunRange * gunRange && DReal.Abs(entity.rotation - targetAngle) < 1) { FireGun(); if (!gunFireSound.isPlaying) { gunFireSound.Play(); } } else { gunFireSound.Stop(); } } else { gunFireSound.Stop(); } if (missilesLoaded < maxMissiles) { if (missileReloadTime <= 0) { missileReloadTime = missileReloadDelay; } else { missileReloadTime -= ComSat.tickRate; if (missileReloadTime <= 0) { missilesLoaded += 1; } } } if (missileRecycleDelay > 0) { missileRecycleDelay -= ComSat.tickRate; } if (gunRecycleDelay > 0) { gunRecycleDelay -= ComSat.tickRate; } }
private void PickNewTarget() { if (targets == null) { targets = new Entity[] {} } ; targets = targets.Where(t => ComSat.EntityExists(t)).OrderBy(t => (t.position - entity.position).sqrMagnitude).ToArray(); if (targets.Count() > 0) { target = targets[0]; mode = Mode.ATTACK; } else { target = null; mode = Mode.IDLE; } } void TickUpdate() { ComSat.Trace(this, "TickUpdate"); if (mode == Mode.ATTACK && !ComSat.EntityExists(target)) { PickNewTarget(); if (!ComSat.EntityExists(target)) { vehicle.Stop(); } } if (mode == Mode.ATTACK) { var distVec = target.position - entity.position; var dist = distVec.magnitude; DReal targetTurretAngle; var projectileProjectile = projectilePrefab != null?projectilePrefab.GetComponent <Projectile>() : null; if (projectileProjectile != null) { var aimSpot = Utility.PredictShot(entity.position, projectileProjectile.initialSpeed, target.position, target.velocity); targetTurretAngle = DReal.Mod(DVector2.ToAngle(aimSpot - entity.position) - entity.rotation, DReal.TwoPI); } else { targetTurretAngle = DReal.Mod(DVector2.ToAngle(distVec) - entity.rotation, DReal.TwoPI); } // Turn turret to point at target when close. if (dist >= attackRange * 2) { targetTurretAngle = turretAutoResets ? 0 : turretRotation; } turretRotation = Utility.CalculateNewAngle(turretRotation, targetTurretAngle, turretTurnSpeed); SendMessage("TurnTurret", turretRotation); if (dist < attackDistance) { // Close enough. movingToTarget = false; vehicle.Stop(); } else if (movingToTarget || (dist >= attackRange)) { movingToTarget = true; // Approach target. vehicle.MoveTowards(target.position); } // Fire when in range and pointing the gun at the target. if (dist < attackRange && targetTurretAngle == turretRotation) { SendMessage("Fire"); } } else if (mode == Mode.MOVE) { // Move towards. if ((destination - entity.position).sqrMagnitude < sqrPositioningAccuracy) { // Close enough. mode = Mode.IDLE; vehicle.Stop(); } else { vehicle.MoveTowards(destination); } if (turretAutoResets) { turretRotation = Utility.CalculateNewAngle(turretRotation, 0, turretTurnSpeed); SendMessage("TurnTurret", turretRotation); } } else if (mode == Mode.IDLE) { vehicle.Stop(); if (turretAutoResets) { turretRotation = Utility.CalculateNewAngle(turretRotation, 0, turretTurnSpeed); SendMessage("TurnTurret", turretRotation); } } } }