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 (ComSat.EntityExists(target)) { var dir = target.position - entity.position; // also vector to dest. var targetAngle = DVector2.ToAngle(dir); var baseAngle = Utility.CalculateNewAngle(entity.rotation, targetAngle, DReal.Radians(turnSpeed)); entity.rotation = baseAngle; } entity.velocity = DVector2.FromAngle(entity.rotation) * speed; DVector2 newPosition = entity.position + entity.velocity * ComSat.tickRate; // FIXME: this should do something to account for hitting fast-moving projectiles. DVector2 hitPosition; Entity hit = ComSat.LineCast(entity.position, newPosition, out hitPosition, entity.team); if (hit != null && (!hit.hitOnlyIfTargetted || hit == target)) { hit.Damage((int)ComputeDamage()); var position = new Vector3((float)hitPosition.y, 0, (float)hitPosition.x); var rotation = Quaternion.AngleAxis((float)entity.rotation, Vector3.up); if (impactPrefab != null && ComSat.RateLimit()) { ObjectPool.Instantiate(impactPrefab, position, rotation); } //if(trail) { // trail.transform.parent = null; // trail.autodestruct = true; // trail = null; //} if (!penetrates || speed < minPenetrationSpeed) { ComSat.DestroyEntity(entity, DestroyReason.HitTarget); return; } else { speed -= penetrationSpeedReduction; } } }
// This could be smarter. If dest is too close & perpendicular, then the tank // can end up circling around. public void MoveTowards(DVector2 dest) { ComSat.Trace(this, "MoveTowards"); var dir = dest - entity.position; // also vector to dest. var targetAngle = DVector2.ToAngle(dir); var baseAngle = Utility.CalculateNewAngle(entity.rotation, targetAngle, DReal.Radians(turnSpeed)); entity.rotation = baseAngle; // Move along current heading. Ramp speed up as the angle gets closer. // Augh. // [-pi,pi] => [0,2pi] if (targetAngle < 0) { targetAngle += DReal.TwoPI; } // Get targetAngle within +/- pi of baseAngle. if (targetAngle < baseAngle - DReal.PI) { targetAngle += DReal.TwoPI; } else if (targetAngle > baseAngle + DReal.PI) { targetAngle -= DReal.TwoPI; } var diff = DReal.Abs(baseAngle - targetAngle); if (canMoveWithoutTurning || diff < maxMoveAngle) { var distance = dir.magnitude; //print("Distance: " + distance + " speed is: " + tickSpeed); var speed = minSpeed + (maxSpeed - minSpeed) * (1 - (diff / DReal.PI)); if (distance < speed) { speed = DReal.Max(minSpeed, distance); } entity.velocity = canMoveWithoutTurning ? dir.normalized * speed : DVector2.FromAngle(baseAngle) * speed; } else { Stop(); } }
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); } } } }