Ejemplo n.º 1
0
        public override void DeployCommand(DVector3 position)
        {
            if (!buildInProgress)
            {
                return;
            }
            if (currentMode != BuildMode.BUILD_THEN_PLACE)
            {
                return;
            }
            if (remainingTime > 0)
            {
                return;
            }

            position = new DVector3(position.x,
                                    World.current.map.Height(position),
                                    position.z);

            if (!CheckBuildPlacement(buildingWhat, position))
            {
                return;
            }

            World.current.Instantiate(buildables[buildingWhat],
                                      entity.team,
                                      position);
            buildInProgress = false;
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        //  c (+0,+1)      d (+1,+1)
        //    +--x-------+
        //    |  | icd   |   Interpolate between a and b, producing iab.
        //    |  x       |   Interpolate between c and d, producing icd.
        //    |  | i     |   Interpolate between iab and icd, producing the interpolated result.
        //    |  |       |
        //    |  | iab   |
        //    +--x-------+
        //  a (+0,+0)      b (+1,+0)
        public static DVector3 BilinearLerp(DVector3 a, DVector3 b, DVector3 c, DVector3 d, DReal x, DReal y)
        {
            var iab = Lerp(a, b, x);
            var icd = Lerp(c, d, x);

            return(Lerp(iab, icd, y));
        }
Ejemplo n.º 4
0
 public override void DeployCommand(DVector3 position)
 {
     World.current.Instantiate(deployPrototype,
                               entity.team,
                               entity.position);
     entity.Destroy();
 }
Ejemplo n.º 5
0
 public void BuildCommand(int id, DVector3 position)
 {
     position = World.current.map.WrapPosition(position);
     foreach (var c in components)
     {
         c.BuildCommand(id, position);
     }
 }
Ejemplo n.º 6
0
    public void SendDeployCommand(int eid, Game.DVector3 point)
    {
        var message = new NetworkMessage(NetworkMessage.Type.CommandDeploy);

        message.entityId = eid;
        message.position = point;
        SendMessageToServer(message);
    }
Ejemplo n.º 7
0
 public void DeployCommand(DVector3 position)
 {
     position = World.current.map.WrapPosition(position);
     foreach (var c in components)
     {
         c.DeployCommand(position);
     }
 }
Ejemplo n.º 8
0
    public void SendBuildCommand(int eid, int buildId, Game.DVector3 point)
    {
        var message = new NetworkMessage(NetworkMessage.Type.CommandBuild);

        message.entityId = eid;
        message.buildId  = buildId;
        message.position = point;
        SendMessageToServer(message);
    }
Ejemplo n.º 9
0
 public override void MoveCommand(DVector3 position)
 {
     if (motor != null)
     {
         motor.MoveTo(position);
     }
     attackTarget        = null;
     passiveAttackTarget = null;
 }
Ejemplo n.º 10
0
 public Entity(int team, DVector3 position, EntityPrototype prototype)
 {
     this.eid       = World.current.RegisterEntity(this);
     this.team      = team;
     this.position  = position;
     this.isAlive   = true;
     this.prototype = prototype;
     this.modelName = prototype.name;
 }
Ejemplo n.º 11
0
 public Entity(int team, DVector3 position, string modelName)
 {
     this.eid       = World.current.RegisterEntity(this);
     this.team      = team;
     this.position  = position;
     this.modelName = modelName;
     this.isAlive   = true;
     this.prototype = null;
 }
Ejemplo n.º 12
0
        // Cast a line from A to B, checking for collisions with other entities.
        public IEnumerable <LineCastResult> LineCastAll(DVector3 start, DVector3 end, int ignoreTeam = -1)
        {
            var start2d = new DVector2(start.x, start.z);
            var end2d   = new DVector2(end.x, end.z);

            foreach (Collider c in colliders)
            {
                if (c.entity.team == ignoreTeam)
                {
                    continue;
                }

                var position2d = new DVector2(c.entity.position.x, c.entity.position.z);

                DVector2 result;

                // FIXME: Need to adjust positions to correct for wrap.
                // FIXME: Some cases still not handled properly.
                //
                //      _______________
                //      |   /         |
                //      ---X-----------
                //        /
                //       /
                //      O
                //     /
                //    /
                // Circle intersects at O, which is a miss, but a real intersect happens at X.
                if (Utility.IntersectLineCircle(position2d, c.radius, start2d, end2d, out result))
                {
                    // Possible hit, work out the correct 3D position at the intersect.
                    var result3d       = new DVector3(result.x, start.y, result.y);
                    var a              = result3d - start;
                    var bhat           = (end - start).normalized;
                    var ab             = DVector3.Dot(a, bhat);
                    var intersectPoint = start + bhat * ab;
                    var height         = intersectPoint.y;
                    var bottom         = c.entity.position.y;
                    var top            = bottom + c.height;
                    Logger.Log("result3d: {0}  a: {1}  bhat: {2}  ab: {3}  height: {4}  bottom: {5}  top:{6}",
                               result3d, a, bhat, ab, height, bottom, top);
                    DebugExtension.DebugPoint((UnityEngine.Vector3)intersectPoint, UnityEngine.Color.blue, 10, 10);
                    UnityEngine.Debug.DrawLine((UnityEngine.Vector3)start, (UnityEngine.Vector3)end, UnityEngine.Color.green, 10);
                    UnityEngine.Debug.DrawLine((UnityEngine.Vector3)start, (UnityEngine.Vector3)result3d, UnityEngine.Color.green, 10);
                    if (bottom <= height && height <= top)
                    {
                        var r = new LineCastResult();
                        r.entity   = c.entity;
                        r.position = intersectPoint;
                        yield return(r);
                    }
                }
            }
        }
Ejemplo n.º 13
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;
        }
Ejemplo n.º 14
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");
        }
Ejemplo n.º 15
0
        public Entity LineCast(DVector3 start, DVector3 end, out DVector3 hitPosition, int ignoreTeam = -1)
        {
            var result = LineCastAll(start, end, ignoreTeam)
                         .OrderBy(r => map.Distance(start, r.position))
                         .FirstOrDefault();

            if (result == null)
            {
                hitPosition = new DVector3(0, 0, 0);
                return(null);
            }
            hitPosition = result.position;
            return(result.entity);
        }
Ejemplo n.º 16
0
        public override bool Equals(System.Object obj)
        {
            // If parameter is null return false.
            if (obj == null)
            {
                return(false);
            }

            // If parameter cannot be cast to Point return false.
            DVector3 p = (DVector3)obj;

            // Return true if the fields match:
            return(this == p);
        }
Ejemplo n.º 17
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);
                }
            }
        }
Ejemplo n.º 18
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));
        }
Ejemplo n.º 19
0
        public DVector3 Normal(DVector3 position)
        {
            var ix = (int)position.x;
            var iz = (int)position.z;

            // Corner normals.
            var ha = RawNormal(ix, iz);
            var hb = RawNormal(ix + 1, iz);
            var hc = RawNormal(ix, iz + 1);
            var hd = RawNormal(ix + 1, iz + 1);

            // Interpolation offsets.
            var tx = position.x - ix;
            var tz = position.z - iz;

            return(DVector3.BilinearLerp(ha, hb, hc, hd, tx, tz).normalized);
        }
Ejemplo n.º 20
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);
 }
Ejemplo n.º 21
0
        IEnumerable <DVector3> neighbors(DVector3 point)
        {
            yield return(map.WrapPosition(point + new DVector3(0, 0, +1) * granularity));

            yield return(map.WrapPosition(point + new DVector3(0, 0, -1) * granularity));

            yield return(map.WrapPosition(point + new DVector3(+1, 0, 0) * granularity));

            yield return(map.WrapPosition(point + new DVector3(-1, 0, 0) * granularity));

            yield return(map.WrapPosition(point + new DVector3(+1, 0, +1) * granularity));

            yield return(map.WrapPosition(point + new DVector3(+1, 0, -1) * granularity));

            yield return(map.WrapPosition(point + new DVector3(-1, 0, +1) * granularity));

            yield return(map.WrapPosition(point + new DVector3(-1, 0, -1) * granularity));
        }
Ejemplo n.º 22
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;
 }
Ejemplo n.º 23
0
        public bool MoveTo(DVector3 position)
        {
            if (currentPath != null && currentPath.Count != 0)
            {
                // Try to avoid recomputing path.
                var dist = World.current.map.Distance(position, currentPath[currentPath.Count - 1]);
                if (dist < 1)
                {
                    return(true);
                }
            }
            var newPath = World.current.navigation.BuildPath(entity.position, position);

            if (newPath == null)
            {
                return(false);
            }
            currentPath = newPath;
            return(true);
        }
Ejemplo n.º 24
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));
        }
Ejemplo n.º 25
0
        public override void OnTick()
        {
            var p2d  = new DVector3(entity.position.x, 0, entity.position.z);
            var targ = new Game.DVector3(target.x, 0, target.z);
            var dist = World.current.map.Distance(p2d, targ);
            var dir  = World.current.map.Direction(p2d, targ);

            if (dist < moveSpeed * World.deltaTime)
            {
                entity.position = new DVector3(target.x, entity.position.y, target.z);
            }
            else
            {
                var d = p2d + dir * moveSpeed * World.deltaTime;
                entity.position      = new DVector3(d.x, entity.position.y, d.z);
                entity.faceDirection = dir;
            }

            var terrainHeight = DReal.Max(0, World.current.map.Height(entity.position));
            var wobble        = DReal.Sin((World.current.time + wobbleOffset) * wobbleFrequency) * wobbleAmplitude;
            var targetHeight  = terrainHeight + floatOffset + wobble;

            var height_diff = DReal.Abs(targetHeight - entity.position.y);
            var newHeight   = (DReal)0;

            if (targetHeight > entity.position.y)
            {
                newHeight = entity.position.y + DReal.Min(height_diff, verticalSpeed * World.deltaTime);
            }
            else
            {
                newHeight = entity.position.y - DReal.Min(height_diff, verticalSpeed * World.deltaTime);
            }

            entity.position = new DVector3(entity.position.x,
                                           DReal.Max(terrainHeight, newHeight),
                                           entity.position.z);
        }
Ejemplo n.º 26
0
 // Directly examine the map to determine if a tile is passible.
 bool MapPassable(int x, int z)
 {
     for (int xoff = 0; xoff < granularity; xoff += 1)
     {
         for (int zoff = 0; zoff < granularity; zoff += 1)
         {
             var pos    = new DVector3(x + xoff + DReal.Half, 0, z + zoff + DReal.Half);
             var normal = map.Normal(pos);
             var up     = new DVector3(0, 1, 0);
             var slope  = DVector3.Dot(normal, up);
             if (slope < slopeLimit)
             {
                 // Too sloped.
                 return(false);
             }
             if (map.Height(pos) < 0)
             {
                 // Underwater.
                 return(false);
             }
         }
     }
     return(true);
 }
Ejemplo n.º 27
0
        public DVector3 WrappedVectorSub(DVector3 lhs, DVector3 rhs)
        {
            var dx = lhs.x - rhs.x;
            var dy = lhs.y - rhs.y;
            var dz = lhs.z - rhs.z;

            if (dx > width / 2)
            {
                dx = dx - width;
            }
            else if (dx < -width / 2)
            {
                dx = dx + width;
            }
            if (dz > depth / 2)
            {
                dz = dz - depth;
            }
            else if (dz < -depth / 2)
            {
                dz = dz + depth;
            }
            return(new DVector3(dx, dy, dz));
        }
Ejemplo n.º 28
0
 public override void MoveCommand(DVector3 position)
 {
     is_idle = true;
     motor.MoveTo(position);
 }
Ejemplo n.º 29
0
        public bool Contains(DVector3 point, DReal thing_radius)
        {
            var dist = World.current.map.Distance(point, entity.position);

            return(dist < radius + thing_radius);
        }
Ejemplo n.º 30
0
    void DoFire(Game.DVector3 targetPoint, Game.DVector3 origin)
    {
        Debug.Log("Firing at " + targetPoint + " from " + origin);
        var dist = navMesh.map.Distance(new Game.DVector3((Game.DReal)origin.x, 0, (Game.DReal)origin.z),
                                        new Game.DVector3((Game.DReal)targetPoint.x, 0, (Game.DReal)targetPoint.z));
        var dir = navMesh.map.Direction(new Game.DVector3((Game.DReal)origin.x, 0, (Game.DReal)origin.z),
                                        new Game.DVector3((Game.DReal)targetPoint.x, 0, (Game.DReal)targetPoint.z));

        Debug.Log("Distance to target is " + dist);
        Debug.DrawRay((Vector3)origin, (Vector3)(dir * dist), Color.white, 10.0f);
        // Walk the line to check for collisions against the terrain.
        // ### Walking the projectile's whole path feels dubious for performance...
        // At least it only needs to be done once. Line/terrain intersect algorithms?
        // This computes X, the highest point of the arc (actually triangle) to clear the terrain.
        //        X
        //       / \
        //      /   \
        //     /    t\
        //    /    tt \
        //   /t   ttt  \
        //  / t  tttt t \
        // / tttttttttt  \
        // Actual rendering uses an arc that passes through X to look nice, and the projectile travel
        // time is computed as though the line was flat.
        var position          = origin;
        var midpoint          = dist / 2;
        var angle             = (Game.DReal) 0;
        var intesects_terrain = false;

        for (var offset = (Game.DReal) 0; offset < dist; offset += projSpeed * timeStep)
        {
            var old         = position;
            var next_offset = offset + projSpeed * timeStep;
            if (next_offset >= dist)
            {
                break;
            }
            position += dir * projSpeed * timeStep;
            var terrain_height = navMesh.map.Height(position);
            if (terrain_height > position.y)
            {
                Debug.DrawLine((Vector3)old,
                               (Vector3)position,
                               Color.red, 10.0f, false);
                intesects_terrain = true;
                if (offset > midpoint)
                {
                    angle = Game.DReal.Max(angle, Game.DReal.Atan2(terrain_height - position.y + 1, dist - offset));
                }
                else
                {
                    angle = Game.DReal.Max(angle, Game.DReal.Atan2(terrain_height - position.y + 1, offset));
                }
            }
        }
        if (intesects_terrain)
        {
            Debug.Log("Intersect angle: " + Game.DReal.Degrees(angle) + "  cos: " + Game.DReal.Cos(angle));
            var foo    = dir * midpoint;
            var leg    = Game.DReal.Half * dist * ((Game.DReal) 1 / Game.DReal.Cos(angle));
            var height = Game.DReal.Sqrt((4 * leg * leg - dist * dist) / 4);
            Debug.Log("Height: " + height);
            var middle = new Game.DVector3(foo.x, foo.y + height, foo.z);
            Debug.DrawLine((Vector3)origin, (Vector3)(origin + middle), Color.blue, 10.0f, false);
            Debug.DrawLine((Vector3)(origin + middle), (Vector3)targetPoint, Color.blue, 10.0f, false);
        }
    }