void TickUpdate() { if (fireDelayTime > 0) { fireDelayTime -= ComSat.tickRate; } }
void Start() { for (DReal n = -DReal.TwoPI; n <= DReal.TwoPI; n += (DReal)1 / 10) { print(n + " D: " + DReal.Tan(n) + " F: " + Mathf.Tan((float)n) + " D: " + Mathf.Abs(Mathf.Tan((float)n) - (float)DReal.Tan(n))); } }
void TickUpdate() { if (sabotageTime > 0) { sabotageTime -= ComSat.tickRate; return; } if (!powerSink.Powered()) { return; } foreach (var p in ComSat.FindAllEntitiesWithinRadius <Projectile>(entity.position, radius, entity.team)) { if (p.kind != Projectile.Kind.KINETIC) { continue; } glowTime = glowLength; p.speed /= 30 * ComSat.tickRate; } }
// (Client) void SpawnCommand(string entityName, int team, DVector2 position, DReal rotation) { Log("{" + tickID + "} Spawn " + entityName + " on team " + team + " at " + position + ":" + rotation); GameObject go = Resources.Load <GameObject>(entityName); SpawnEntity(go, null, team, position, rotation, e => {}); }
// 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)); }
// Locate an entity within the given circle, not on the given team. // This includes all entities, not just collidable entities. public static List <T> FindAllEntitiesWithinRadius <T>(DVector2 origin, DReal radius, int ignoreTeam = -1, Func <T, DReal> getRadius = null) where T : MonoBehaviour { var result = new List <T>(); foreach (Entity e in currentInstance.worldEntityCache) { T thing = (typeof(T) == typeof(Entity)) ? e as T : e.GetComponent <T>(); if (thing == null) { continue; } if (e.team == ignoreTeam) { continue; } var r = getRadius != null?getRadius(thing) : e.collisionRadius; if ((e.position - origin).sqrMagnitude < radius * radius + r * r) { result.Add(thing); } } return(result); }
public static DReal RandomRange(DReal min, DReal max) { var range = DReal.Max(0, max - min); var n = RandomValue() / (uint)0xFFFFFFFF; return(n * range + min); }
void FireMissile() { if (missileRecycleDelay > 0) { return; } if (missilesLoaded <= 0) { return; } missileFireSound.PlayOneShot(missileFireSound.clip); ComSat.SpawnEntity(entity, missilePrefab, entity.position, entity.rotation, (Entity ent) => { var proj = ent.gameObject.GetComponent <Projectile>(); if (proj != null && ComSat.EntityExists(combatVehicle.target)) { proj.target = combatVehicle.target; } }); missileRecycleDelay = missileRecycleTime; missilesLoaded -= 1; }
void TickUpdate() { ComSat.Trace(this, "TickUpdate"); if (fireCycle != FireCycle.READY) { fireDelayTime -= ComSat.tickRate; if (fireDelayTime <= 0) { if (fireCycle == FireCycle.FIREDLEFT) { // Fire right. fireCycle = FireCycle.FIREDRIGHT; FireOneBarrel(-1); // This is enough time for the left barrel to recycle. fireDelayTime = barrelRecycleTime - barrelDelay; } else if (fireCycle == FireCycle.FIREDRIGHT) { // cycle complete. fireCycle = FireCycle.READY; } } } }
void TickUpdate() { ComSat.Trace(this, "TickUpdate"); age += ComSat.tickRate; if (age >= lifetime) { ComSat.DestroyEntity(entity, DestroyReason.OldAge); } }
void TickUpdate() { currentPower = (sabotageTime > 0) ? sabotageMaxPower : maximumPower; if (sabotageTime > 0) { sabotageTime -= ComSat.tickRate; } }
void TickUpdate() { timer += ComSat.tickRate; if (entity.team != -1 && timer > 1 && powerSink.poweredOn) { var amount = Math.Min(powerSink.Powered() ? mineRate : mineRate / 2, source.amount); resourceMan.AddResource(entity.team, resource, amount); source.amount -= amount; } timer %= 1; }
private void ResetBuildTime() { if (buildQueue.Any()) { delay = prefabs[buildQueue.Peek().what].buildTime; if (!dontManagePower) powerSink.poweredOn = true; } else { delay = 0; if (!dontManagePower) powerSink.poweredOn = false; } partialMetalUnit = partialSmokeUnit = 0; usedResources = new ResourceSet(); }
void Fire() { if (fireCycle != FireCycle.READY) { return; } // Fire left. fireCycle = FireCycle.FIREDLEFT; fireDelayTime = barrelDelay; FireOneBarrel(+1); }
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 Update() { if (teamColourRenderer != null) { teamColourRenderer.material.SetColor("_TeamColor", Utility.TeamColour(team)); } transform.localPosition = new Vector3((float)position.y, transform.localPosition.y, (float)position.x); transform.localRotation = Quaternion.AngleAxis((float)DReal.Degrees(rotation), Vector3.up); }
public bool CanBuildAt(DVector2 position, DReal radius) { foreach (var b in pendingBuilds) { var dist = (position - b.position).sqrMagnitude; if (dist < radius * radius + b.sqrRadius) { return(false); } } return(true); }
void TickUpdate() { ComSat.Trace(this, "TickUpdate"); if(sabotageTime > 0) { sabotageTime -= ComSat.tickRate; } if (buildQueue.Any()) { var buildMe = buildQueue.Peek(); var prefab = prefabs[buildMe.what]; if(delay > 0) { var advance = ComSat.tickRate; if(sabotageTime > 0) { advance /= sabotageTimeMultiplier; } if(!powerSink.Powered()) { advance /= 2; } var completion = advance / prefab.buildTime; var totalRemaining = prefab.buildCost - usedResources; partialMetalUnit += DReal.Min(completion * prefab.buildCost.Metal, totalRemaining.Metal); partialSmokeUnit += DReal.Min(completion * prefab.buildCost.MagicSmoke, totalRemaining.MagicSmoke); var rs = new ResourceSet { Metal = (int)partialMetalUnit, MagicSmoke = (int)partialSmokeUnit }; if (resourceMan.TakeResources(entity.team, rs)) { usedResources += rs; partialMetalUnit %= 1; partialSmokeUnit %= 1; delay -= advance; } else { partialMetalUnit -= completion * prefab.buildCost.Metal; partialSmokeUnit -= completion * prefab.buildCost.MagicSmoke; } } if(delay <= 0) { if (!resourceMan.TakeResources(entity.team, prefab.buildCost - usedResources)) return; // Timer expired and we're building something. print("Build new " + prefab); var prefabSize = (DReal)prefab.collisionRadiusNumerator / prefab.collisionRadiusDenominator; var wiggle = ((ComSat.RandomValue() % 5) / 5) * ((ComSat.RandomValue() % 2 == 0) ? 1 : -1); var position = prefab.buildAtPoint ? buildMe.position : (entity.position + DVector2.FromAngle(entity.rotation + wiggle) * (entity.collisionRadius + prefabSize + 2 + wiggle)); ComSat.SpawnEntity(entity, prefab.gameObject, position, 0); if(buildMe.buildCollider != null) { buildMan.RemovePendingBuild(buildMe.buildCollider); } if (!buildMe.repeat) buildQueue.Dequeue(); ResetBuildTime(); } } }
void Awake() { ComSat.Trace(this, "Awake"); entity = GetComponent<Entity>(); entity.AddUpdateAction(TickUpdate); powerSink = GetComponent<PowerSink>(); target = null; turretRotation = 0; fireDelay = 0; barrelRecycleTime = (DReal)barrelRecycleTimeNumerator / barrelRecycleTimeDenominator; }
void UIAction(int what) { ComSat.Trace(this, "UIAction"); if(what == clearQueue) { foreach(var data in buildQueue) { if(data.buildCollider != null) { buildMan.RemovePendingBuild(data.buildCollider); } } buildQueue.Clear(); delay = 0; resourceMan.AddResource(entity.team, ResourceType.Metal, usedResources.Metal); resourceMan.AddResource(entity.team, ResourceType.MagicSmoke, usedResources.MagicSmoke); ResetBuildTime(); } }
void Start() { DVector2 vec = new DVector2((DReal)transform.position.z, (DReal)transform.position.x); DReal rotation = DReal.Radians((DReal)transform.rotation.eulerAngles.y); /*Entity ent =*/ ComSat.Spawn(entityName, team, vec, rotation); //if(ent == null) return; //if(action == Action.MOVE) { // ComSat.IssueMove(ent, new DVector2((DReal)point.x, (DReal)point.y)); //} if (team == ComSat.localTeam) { FindObjectOfType <CameraController>().LookAt(vec); } }
public static T GetThingAt <T>(DVector2 position, DReal maxOffset) where T : MonoBehaviour { T rv = null; DReal nearestSourceDistance = DReal.MaxValue; foreach (var thing in GameObject.FindObjectsOfType <T>()) { var d = (position - thing.GetComponent <Entity>().position).sqrMagnitude; if (d < nearestSourceDistance && d < maxOffset * maxOffset) { rv = thing; nearestSourceDistance = d; } } return(rv); }
void Fire() { if(fireDelay > 0) { return; } fireDelay = barrelRecycleTime; ComSat.SpawnEntity(entity, projectilePrefab, entity.position, entity.rotation + turretRotation, (Entity ent) => { var proj = ent.gameObject.GetComponent<Projectile>(); if(proj != null && ComSat.EntityExists(target)) { proj.target = target; } }); turretBarrel.SendMessage("Fire"); }
void OnDrawGizmosSelected() { Gizmos.color = Color.red; Gizmos.DrawWireSphere(transform.position, (float)attackRange); // Projectile spawn location & stuff. Gizmos.color = Color.red; Vector3 turretPosition = new Vector3((float)turretAttachPoint.x, 0, (float)turretAttachPoint.y); Matrix4x4 rotationMatrix = Matrix4x4.TRS(transform.position, transform.rotation, transform.lossyScale) * Matrix4x4.TRS(turretPosition, Quaternion.AngleAxis((float)DReal.Degrees(turretRotation), Vector3.up), transform.lossyScale); Gizmos.matrix = rotationMatrix; Gizmos.DrawWireSphere(new Vector3(0,0,0), 0.5f); Gizmos.DrawWireCube(new Vector3(0, 0, (float)projectileSpawnDistance), new Vector3(0.5f, 0.5f, 0.5f)); }
public static DVector2 PredictShot(DVector2 origin, DReal projectileSpeed, DVector2 targetPosition, DVector2 targetVelocity) { var dp = targetPosition - origin; // Try to lead the target. var a = DVector2.Dot(targetVelocity, targetVelocity) - projectileSpeed * projectileSpeed; var b = 2 * DVector2.Dot(targetVelocity, dp); var c = DVector2.Dot(dp, dp); var p = -b / (2 * a); var discriminant = b * b - 4 * a * c; if (discriminant <= 0) { return(targetPosition); } DReal q; try { q = DReal.Sqrt(discriminant) / (2 * a); } catch (System.ArithmeticException) { return(targetPosition); } var t1 = p - q; var t2 = p + q; DReal t; if (t1 > t2 && t2 > 0) { t = t2; } else if (t1 > 0) { t = t1; } else { return(targetPosition); } return(targetPosition + targetVelocity * t); }
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; } } }
void FireGun() { if (gunRecycleDelay > 0) { return; } ComSat.SpawnEntity(entity, gunPrefab, entity.position, entity.rotation, (Entity ent) => { var proj = ent.gameObject.GetComponent <Projectile>(); if (proj != null && ComSat.EntityExists(combatVehicle.target)) { proj.target = combatVehicle.target; } }); gunRecycleDelay = gunRecycleTime; }
// Locate an entity within the given circle, not on the given team. public static Entity FindEntityWithinRadius(DVector2 origin, DReal radius, int ignoreTeam = -1, Func <Entity, DReal> getRadius = null) { getRadius = getRadius ?? (e => e.collisionRadius); foreach (Entity e in currentInstance.worldEntityCollisionCache) { if (e.team == ignoreTeam) { continue; } var r = getRadius(e); if ((e.position - origin).sqrMagnitude < radius * radius + r * r) { return(e); } } return(null); }
// 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(); } }
// Create a new entity at whereever. // Called by all, but ignored everywhere but the server. public static void Spawn(string entityName, int team, DVector2 position, DReal rotation) { if (currentInstance.replayInput != null) { return; } // Only spawn if the team exists or if generating scenery. if (team != spectatorTeam && !currentInstance.players.Any(p => p.team == team)) { return; } var m = new NetworkMessage(NetworkMessage.Type.SpawnEntity); m.entityName = entityName; m.teamID = team; m.position = position; m.rotation = rotation; currentInstance.net.SendMessageToServer(m); }