public void FireAt(Entity target) { if (refireTime > 0 || sustainTarget != null) { return; } var dist = entity.Range(target); if (dist > range) { return; } World.current.eventListener.Animate(entity, "Fire"); if (sustainTime == 0) { target.Damage(damage); refireTime = fireRate; World.current.eventListener.HitscanBurstFire(this, effect, target); } else { World.current.eventListener.HitscanSustainedFire(this, effect, target, sustainTime); sustainRemaining = sustainTime; sustainTarget = target; } }
public override void OnTick() { if (refireTime > 0) { refireTime -= World.deltaTime; } if (sustainTarget != null) { if (!sustainTarget.isAlive) { sustainTarget = null; refireTime = fireRate + sustainRemaining; return; } var dist = entity.Range(sustainTarget); Logger.Log("distance {0} range {1} target {3} possible damage {2}", dist, range, damage * World.deltaTime, entity.modelName); if (dist <= range) { sustainTarget.Damage(damage * World.deltaTime); } sustainRemaining -= World.deltaTime; if (sustainRemaining <= 0) { sustainTarget = null; refireTime = fireRate; } } }
public Collider(Entity entity, ComponentPrototype proto) : base(entity) { height = DReal.Parse(proto.data["height"]); radius = DReal.Parse(proto.data["radius"]); fixedPosition = proto.data["fixedPosition"] == "true"; pushy = proto.data["pushy"] == "true"; }
public Projectile(Entity entity, ComponentPrototype proto) : base(entity) { speed = DReal.Parse(proto.data["speed"]); directDamage = DReal.Parse(proto.data["directDamage"]); splashDamage = DReal.Parse(proto.data["splashDamage"]); splashRadius = DReal.Parse(proto.data["splashRadius"]); }
public DReal Take(DReal count) { var n = DReal.Min(remainingCount, count); remainingCount -= n; return(n); }
public void Tick() { currentTick += 1; // Call OnCreate on each new entity. while (new_entities.Count != 0) { var e = new_entities[new_entities.Count - 1]; new_entities.RemoveAt(new_entities.Count - 1); e.OnCreate(); _entities.Add(e); eventListener.EntityCreated(e); } // OnTick. foreach (var e in entities) { e.OnTick(); } // Perform collision detection. for (var i = 0; i < colliders.Count; i += 1) { var ci = colliders[i]; var i_bot = ci.entity.position.y; var i_top = i_bot + ci.height; for (var j = i + 1; j < colliders.Count; j += 1) { var cj = colliders[j]; var j_bot = cj.entity.position.y; var j_top = j_bot + cj.height; var size = ci.radius + cj.radius; var dist_sqr = map.DistanceSqr(ci.entity.position, cj.entity.position); if (dist_sqr > size * size) { continue; } if (DReal.Max(i_bot, j_bot) > DReal.Min(i_top, j_top)) { continue; } ci.entity.OnCollision(cj.entity); cj.entity.OnCollision(ci.entity); } } // Call OnDestroy on each dead entity. while (dead_entities.Count != 0) { var e = dead_entities[dead_entities.Count - 1]; dead_entities.RemoveAt(dead_entities.Count - 1); if (new_entities.Contains(e)) { new_entities.Remove(e); } else { e.OnDestroy(); _entities.Remove(e); eidToEntityMap.Remove(e.eid); eventListener.EntityDestroyed(e); } } }
public bool CheckBuildPlacement(int id, DVector3 position) { // Eugh. Poke around in the prototype for the collider (if any). var radius = (DReal)0; var proto = World.current.entityPrototypes[buildables[id]]; foreach (var cproto in proto.components) { if (cproto.kind == "Collider") { radius = DReal.Parse(cproto.data["radius"]); } } if (World.current.FindEntitiesWithinRadius(position, radius * 2).Any()) { return(false); } // Must be within a build radius. foreach (var ent in World.current.entities.Where(e => e.team == entity.team)) { var br = ent.GetComponent <BuildRadius>(); if (br != null && br.Contains(position, radius)) { return(true); } } return(false); }
public Wizard(Entity entity, ComponentPrototype proto) : base(entity) { towerPrototype = proto.data["tower"]; towerBuildCooldown = DReal.Parse(World.current.entityPrototypes[towerPrototype].data["buildTime"]); towerBuildCooldownRemaining = towerBuildCooldown; tower = null; }
public override void OnTick() { if (fireTime > 0) { fireTime -= World.deltaTime; } }
public WizardTower(Entity entity, ComponentPrototype proto) : base(entity) { harvesterPrototype = proto.data["harvester"]; harvesterBuildCooldown = DReal.Parse(World.current.entityPrototypes[harvesterPrototype].data["buildTime"]); wizardPrototype = proto.data["wizard"]; wizardBuildCooldown = DReal.Parse(World.current.entityPrototypes[harvesterPrototype].data["buildTime"]); }
public ResourceHarvester(Entity entity, int resourceId, DReal capacity, DReal fillRate) : base(entity) { this.motor = entity.GetComponent <IMotor>(); this.resourceId = resourceId; this.capacity = capacity; this.fillRate = fillRate; this.fill = 0; }
public ResourceHarvester(Entity entity, ComponentPrototype proto) : base(entity) { this.motor = entity.GetComponent <IMotor>(); resourceId = World.current.resourceNameToId[proto.data["resource"]]; capacity = DReal.Parse(proto.data["capacity"]); fillRate = DReal.Parse(proto.data["rate"]); this.fill = 0; }
public override void OnTick() { if (health != null) { var missing_health = health.max - health.current; health.max = DReal.Max(1, realMaxHealth * buildProgress); health.current = health.max - missing_health; } }
public Mine(Entity entity, ComponentPrototype proto) : base(entity) { this.rate = DReal.Parse(proto.data["rate"]); var resource = World.current.resourceNameToId[proto.data["resource"]]; var team_ent = World.current.entities.First(e => e.team == entity.team && e.GetComponents <ResourcePool>().Any(p => p.resourceId == resource)); pool = team_ent.GetComponents <ResourcePool>().First(p => p.resourceId == resource); }
public override void OnCreate() { health = entity.GetComponent <Health>(); if (health != null) { realMaxHealth = health.max; health.max = 1; health.current = 1; } }
public AirMotor(Entity entity, ComponentPrototype proto) : base(entity) { moveSpeed = DReal.Parse(proto.data["speed"]); wobbleFrequency = DReal.Parse(proto.data["wobbleFrequency"]); wobbleAmplitude = DReal.Parse(proto.data["wobbleAmplitude"]); floatOffset = DReal.Parse(proto.data["floatOffset"]); verticalSpeed = DReal.Parse(proto.data["verticalSpeed"]); wobbleOffset = World.current.RandomValue() * DReal.PI; }
void Splash() { foreach (var hit in World.current.FindEntitiesWithinRadius(entity.position, splashRadius, entity.team)) { var dist = entity.Range(hit); Logger.Log("Splash on entity {0} at {1}, dist {2} ({3}), damage {4}", hit, hit.position, dist, dist / splashRadius, splashDamage * (1 - DReal.Clamp01(dist / splashRadius))); hit.Damage(splashDamage * (1 - DReal.Clamp01(dist / splashRadius)), entity); } entity.Destroy(); World.current.eventListener.Animate(entity, "Impact"); }
public HitscanWeapon(Entity entity, ComponentPrototype proto) : base(entity) { range = DReal.Parse(proto.data["range"]); damage = DReal.Parse(proto.data["damage"]); fireRate = DReal.Parse(proto.data["fireRate"]); sustainTime = DReal.Parse(proto.data["sustainTime"]); effect = proto.data["effect"]; refireTime = 0; sustainRemaining = 0; sustainTarget = null; }
public ProjectileWeapon(Entity entity, ComponentPrototype proto) : base(entity) { projectile = proto.data["projectile"]; range = DReal.Parse(proto.data["range"]); fireRate = DReal.Parse(proto.data["fireRate"]); randomOffset = new DVector3(DReal.Parse(proto.data["randomOffsetX"]), DReal.Parse(proto.data["randomOffsetY"]), DReal.Parse(proto.data["randomOffsetZ"])); fireTime = 0; }
public void FireAt(Entity target) { if (fireTime > 0) { return; } var dist = entity.Range(target); if (dist > range) { return; } var target_position = target.position; // Aim for the middle. var target_collider = target.GetComponent <Collider>(); if (target_collider != null) { target_position += new DVector3(0, target_collider.height / 2, 0); } var projectile_spawn = entity.position; if (collider != null) { // Spawn from front middle of the collider. projectile_spawn += new DVector3(0, collider.height / 2, 0); projectile_spawn += entity.faceDirection * collider.radius; } // Offset the origin slightly to make it less repetative. projectile_spawn += new DVector3(randomOffset.x * World.current.RandomRange(-1, 1), randomOffset.y * World.current.RandomRange(-1, 1), randomOffset.z * World.current.RandomRange(-1, 1)); var dir = World.current.map.Direction(projectile_spawn, target_position); fireTime = fireRate; var ent = World.current.Instantiate(projectile, entity.team, projectile_spawn); var proj = ent.GetComponent <Projectile>(); if (proj != null) { proj.spawner = entity; proj.target = target_position; } World.current.eventListener.Animate(entity, "Fire"); }
public IEnumerable <Entity> FindEntitiesWithinRadius(DVector3 position, DReal radius, int ignoreTeam = -1) { foreach (Collider c in colliders) { if (c.entity.team == ignoreTeam) { continue; } var dist = map.Distance(c.entity.position, position); if (dist < radius + c.radius) { yield return(c.entity); } } }
public override void OnCreate() { motor = entity.GetComponent <IMotor>(); weapons = entity.GetComponents <IWeapon>().ToArray(); weaponRange = weapons.Aggregate((DReal)0, (x, y) => DReal.Max(x, y.Range())); Logger.Log("Weapon range is {0}", weaponRange); if (weapons.Length == 0) { stance = Stance.Passive; } else { stance = Stance.Active; } }
public DReal Height(DVector3 position) { var ix = (int)position.x; var iz = (int)position.z; // Corner heights. var ha = RawHeight(ix, iz); var hb = RawHeight(ix + 1, iz); var hc = RawHeight(ix, iz + 1); var hd = RawHeight(ix + 1, iz + 1); // Interpolation offsets. var tx = position.x - ix; var tz = position.z - iz; return(DReal.BilinearLerp(ha, hb, hc, hd, tx, tz)); }
public void Damage(DReal amount, Entity source = null) { var health = GetComponent <Health>(); if (health != null) { health.current -= amount; if (source != null) { if (!health.damageDealers.ContainsKey(source)) { health.damageDealers.Add(source, 0); } health.damageDealers[source] += amount; } } }
public override void OnTick() { if (tower != null && !tower.isAlive) { tower = null; } if (tower == null) { tower = World.current.entities .FirstOrDefault(e => { return(e.team == entity.team && e.modelName == towerPrototype); }); } if (towerBuildCooldownRemaining > 0) { towerBuildCooldownRemaining -= World.deltaTime; } }
public DVector3 RandomSpawnPosition(DReal min, DReal max) { for (var attempt = 0; attempt < 100; attempt += 1) { var angle = World.current.RandomValue() * 360; var radius = World.current.RandomRange(min, max); var x = this.position.x + DReal.Cos(angle) * radius; var z = this.position.z + DReal.Sin(angle) * radius; var height = World.current.map.Height(new DVector3(x, 0, z)); var p = new DVector3(x, height, z); if (World.current.navigation.Reachability(this.position) == World.current.navigation.Reachability(p)) { return(p); } } UnityEngine.Debug.Log("Failed to generate random position."); return(this.position); }
public override void OnTick() { var remaining_movement = moveSpeed * World.deltaTime; while (remaining_movement > 0 && currentPath != null && currentPath.Count != 0) { // If there is something in the way, then ignore this waypoint. if (currentPath.Count > 1 && World.current.FindEntitiesWithinRadius(new DVector3(currentPath[0].x, 0, currentPath[0].z), 0).Where(e => e != entity).Any()) { currentPath.RemoveAt(0); continue; } var dist = World.current.map.Distance(new DVector3(entity.position.x, 0, entity.position.z), new DVector3(currentPath[0].x, 0, currentPath[0].z)); var dir = World.current.map.Direction(new DVector3(entity.position.x, 0, entity.position.z), new DVector3(currentPath[0].x, 0, currentPath[0].z)); var px = (DReal)0; var pz = (DReal)0; if (dist > remaining_movement) { var motion = dir * remaining_movement; px = DReal.Repeat(entity.position.x + motion.x, World.current.map.width); pz = DReal.Repeat(entity.position.z + motion.z, World.current.map.depth); remaining_movement = 0; } else { px = currentPath[0].x; pz = currentPath[0].z; currentPath.RemoveAt(0); remaining_movement -= dist; } var new_height = World.current.map.Height(new DVector3(px, 0, pz)); entity.position = new DVector3(px, new_height, pz); entity.faceDirection = dir; } entity.position = new DVector3(entity.position.x, World.current.map.Height(entity.position), entity.position.z); }
public override void OnTick() { if (harvesterBuildCooldownRemaining > 0) { harvesterBuildCooldownRemaining -= World.deltaTime; } if (harvester != null && !harvester.isAlive) { harvester = null; } if (harvester == null && harvesterBuildCooldownRemaining <= 0) { // TODO: Respect the harvester's build mode. harvester = World.current.Instantiate(harvesterPrototype, entity.team, entity.RandomSpawnPosition(10, 20)); harvesterBuildCooldownRemaining = harvesterBuildCooldown; } if (wizardBuildCooldownRemaining > 0) { wizardBuildCooldownRemaining -= World.deltaTime; } if (wizard != null && !wizard.isAlive) { wizard = null; } if (wizard == null) { wizard = World.current.entities .FirstOrDefault(e => { return(e.team == entity.team && e.modelName == wizardPrototype); }); } if (wizard == null && wizardBuildCooldownRemaining <= 0) { // TODO: Respect the wizard's build mode. wizard = World.current.Instantiate(wizardPrototype, entity.team, entity.RandomSpawnPosition(10, 20)); wizardBuildCooldownRemaining = wizardBuildCooldown; } }
public override void DeployCommand(DVector3 position) { if (tower != null && tower.isAlive) { return; } if (towerBuildCooldownRemaining > 0) { return; } if (!CheckBuildPlacement(position)) { return; } // TODO: Respect the tower's build mode. tower = World.current.Instantiate(towerPrototype, entity.team, position); towerBuildCooldownRemaining = towerBuildCooldown; }
// Range to target, adjusted by collider size. public DReal Range(Entity target) { var ent2d = new DVector3(position.x, 0, position.z); var targ2d = new DVector3(target.position.x, 0, target.position.z); var dist = World.current.map.Distance(ent2d, targ2d); var local_collider = GetComponent <Collider>(); if (local_collider != null) { dist -= local_collider.radius; } var target_collider = target.GetComponent <Collider>(); if (target_collider != null) { dist -= target_collider.radius; } return(DReal.Max(0, dist)); }