Пример #1
0
        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;
            }
        }
Пример #2
0
 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;
         }
     }
 }
Пример #3
0
 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";
 }
Пример #4
0
 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"]);
 }
Пример #5
0
        public DReal Take(DReal count)
        {
            var n = DReal.Min(remainingCount, count);

            remainingCount -= n;
            return(n);
        }
Пример #6
0
 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);
         }
     }
 }
Пример #7
0
        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);
        }
Пример #8
0
 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;
 }
Пример #9
0
 public override void OnTick()
 {
     if (fireTime > 0)
     {
         fireTime -= World.deltaTime;
     }
 }
Пример #10
0
 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"]);
 }
Пример #11
0
 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;
 }
Пример #12
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;
 }
Пример #13
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;
     }
 }
Пример #14
0
        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);
        }
Пример #15
0
 public override void OnCreate()
 {
     health = entity.GetComponent <Health>();
     if (health != null)
     {
         realMaxHealth  = health.max;
         health.max     = 1;
         health.current = 1;
     }
 }
Пример #16
0
        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;
        }
Пример #17
0
 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");
 }
Пример #18
0
        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;
        }
Пример #19
0
        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;
        }
Пример #20
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");
        }
Пример #21
0
        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);
                }
            }
        }
Пример #22
0
        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;
            }
        }
Пример #23
0
        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));
        }
Пример #24
0
        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;
                }
            }
        }
Пример #25
0
 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;
     }
 }
Пример #26
0
 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);
 }
Пример #27
0
        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);
        }
Пример #28
0
 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;
     }
 }
Пример #29
0
 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;
 }
Пример #30
0
        // 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));
        }