Ejemplo n.º 1
0
 public async Task<GameRoom> StartGameAsync(HubCallerContext context)
 {
     var gameRoom = new GameRoom(context);
     // gameRoom.Towers = gameRoom.Towers.Union(TestingConstants.Maze).ToList(); // TODO remove test code
     this.scaleoutService.Subscribe(Persist.GameRoom, gameRoom.Id, context);
     this.scaleoutService.Store(Persist.GameRoom, gameRoom.Id, gameRoom);
     return gameRoom;
 }
Ejemplo n.º 2
0
 public void RemoveMobsAtEnding(Mob mob, GameRoom room, GameRound round)
 {
     if (Point.IsNear(mob.CurrentLocation, mob.EndingLocation, 0.5))
     {
         foreach (var player in room.Players)
         {
             if (mob.EndingLocation.X == player.EndingLocation.X && mob.EndingLocation.Y == player.EndingLocation.Y)
             {
                 player.CurrentLife -= 1;
                 round.Mobs.Remove(mob);
                 this.scaleoutService.Store(Persist.GameRoom, room.Id, room);
                 break;
             }
         }
     }
 }
Ejemplo n.º 3
0
        public void UpdateMobLocation(Mob mob, GameRoom room, GameRound round)
        {
            var span = DateTime.UtcNow.Subtract(mob.LastUpdated);

            if (span.Milliseconds > 0)
            {
                var next = mob.Path?.FirstOrDefault();
                if(next != null && Point.IsNear(mob.CurrentLocation, next, 0.1))
                {
                    mob.Path = mob.Path.Skip(1);
                    next = mob.Path?.FirstOrDefault();
                }

                if(mob.Path == null || next == null)
                {
                    next = this.CalculateMobPath(mob, room);
                }

                if (next != null)
                {
                    var moveSpeed = mob.CurrentSpeed;

                    // Adjust mob speed for slow effects
                    if ((mob.Status as IDictionary<string, object>)?.ContainsKey("slow") ?? false)
                    {
                        moveSpeed = (int)(moveSpeed * (double)mob.Status.slow.speed);

                        if (DateTime.UtcNow > (DateTime)mob.Status.slow.remaining)
                        {
                            var status = (IDictionary<string, object>)mob.Status;
                            status.Remove("slow");
                        }

                    }

                    mob.CurrentLocation = Point.TrackTo(mob.CurrentLocation, next, (span.TotalMilliseconds * moveSpeed / Constants.GameSpeed));
                    // mob.Path = path?.ToList(); // Debugging
                }
                else
                {
                    Console.WriteLine("No valid path found for mob");
                    mob.CurrentLocation = new Point(mob.EndingLocation.X, mob.EndingLocation.Y);
                }

                mob.LastUpdated = DateTime.UtcNow;
            }
        }
Ejemplo n.º 4
0
        public void TickDots(Mob mob, GameRoom room, GameRound round)
        {
            if((mob.Status as IDictionary<string, object>)?.ContainsKey("dot") ?? false)
            {
                var span = DateTime.UtcNow.Subtract((DateTime)mob.Status.dot.lastUpdated);

                if(span.TotalMilliseconds > 500)
                {
                    mob.Health -= (int)mob.Status.dot.damage;
                    mob.Status.dot.lastUpdated = DateTime.UtcNow;

                    if(DateTime.UtcNow > (DateTime)mob.Status.dot.remaining)
                    {
                        (mob.Status as IDictionary<string, object>).Remove("dot");
                    }

                    if(mob.Health <= 0)
                    {
                        round.Mobs.Remove(mob);
                    }
                }
            }
        }
Ejemplo n.º 5
0
        public void UpdateProjectiles(GameRoom room, GameRound round)
        {
            foreach (var tower in room.Towers.Values)
            {
                if (tower.Damage > 0 && tower.ReadyAt <= DateTime.UtcNow)
                {
                    foreach (Mob mob in round.Mobs)
                    {
                        if (Point.IsNear(tower.Location, mob.CurrentLocation, tower.Range))
                        {
                            round.Projectiles.Add(new Projectile(tower, mob));
                            tower.ReadyAt = DateTime.UtcNow.AddMilliseconds(tower.Speed); // TODO: Should have a Game constant scale modifier here
                            break;
                        }
                    }
                }
            }

            foreach(Projectile projectile in round.Projectiles.Reverse())
            {
                var span = DateTime.UtcNow.Subtract(projectile.LastUpdated);
                projectile.Location = Point.TrackTo(projectile.Location, projectile.Target.CurrentLocation, (span.Milliseconds * (projectile.Speed / Constants.GameSpeed)));
                if (Point.IsNear(projectile.Location, projectile.Target.CurrentLocation, 0.1))  // projectile.Location.X == projectile.Target.CurrentLocation)
                {
                    TowerType towerType;
                    switch(projectile.TowerType)
                    {
                        case Constants.TowerList.Slowing:
                            towerType = GameDataUtils.GetTowerTypeFromTowerList(projectile.TowerType);
                            projectile.Target.Status.slow = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(towerType.Effects.slow));
                            projectile.Target.Status.slow.remaining = DateTime.UtcNow.AddMilliseconds((int)towerType.Effects.slow.duration);
                            break;
                        case Constants.TowerList.Dot:
                            towerType = GameDataUtils.GetTowerTypeFromTowerList(projectile.TowerType);
                            projectile.Target.Status.dot = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(towerType.Effects.dot));
                            if(!((projectile.Target.Status.dot as IDictionary<string, object>)?.ContainsKey("lastUpdated") ?? false))
                            {
                                projectile.Target.Status.dot.lastUpdated = DateTime.UtcNow;
                            }
                            projectile.Target.Status.dot.remaining = DateTime.UtcNow.AddMilliseconds((int)towerType.Effects.dot.duration);
                            break;
                        default:
                            // No-op
                            break;
                    }

                    var abilities = projectile.Target.Type.Abilities;
                    var damage = projectile.Damage;

                    // Stoneskin game mechanic
                    if (abilities?.Stoneskin.HasValue == true)
                    {
                        damage -= abilities.Stoneskin.Value;
                    }

                    // Evasion game mechanic
                    if (abilities?.Evasion.HasValue == true)
                    {
                        var roll = random.Value.Next(100);
                        if(roll < abilities.Evasion.Value)
                        {
                            damage = 0;
                        }
                    }

                    projectile.Target.Health -= Math.Max(damage, 0);
                    round.Projectiles.Remove(projectile);

                    if (projectile.Target.Health <= 0)
                    {
                        // Fracture game mechanic
                        if(abilities?.Fracture != null)
                        {
                            for (var i = 0; i < abilities.Fracture.Count; i++)
                            {
                                round.Mobs.Add(new Mob()
                                {
                                    Type = projectile.Target.Type.Abilities.Fracture.Shard,
                                    CurrentLocation = new Point(projectile.Target.CurrentLocation),
                                    EndingLocation = new Point(projectile.Target.EndingLocation),
                                    Health = projectile.Target.Type.Abilities.Fracture.Shard.StartingHealth,
                                    CurrentSpeed = projectile.Target.Type.Abilities.Fracture.Shard.MoveSpeed

                                });
                            }
                        }

                        // Avenger game mechanic
                        if(abilities?.Avenger != null)
                        {
                            var range = projectile.Target.Type.Abilities.Avenger.Range;
                            foreach(var mob in round.Mobs.Reverse())
                            {
                                if(Point.IsNear(projectile.Target.CurrentLocation, mob.CurrentLocation, range))
                                {
                                    mob.CurrentSpeed *= (1 + projectile.Target.Type.Abilities.Avenger.Bonus);
                                }
                            }
                        }

                        round.Mobs.Remove(projectile.Target);
                    }
                }

                projectile.LastUpdated = DateTime.UtcNow;
            }
        }
Ejemplo n.º 6
0
 public GamePoint(GameRoom gameRoom, Point p) : this(gameRoom, (int)p.X, (int)p.Y)
 {
 }
Ejemplo n.º 7
0
 public GamePoint(GameRoom gameRoom, double x, double y) : base(Math.Max(Math.Min(x, Constants.MapSize), 0), Math.Max(Math.Min(y, Constants.MapSize), 0))
 {
     this.GameRoom = gameRoom;
 }
Ejemplo n.º 8
0
        private GamePoint CalculateMobPath(Mob mob, GameRoom room)
        {
            var path = this.pathingService.FindPath<GamePoint>(new GamePoint(room, mob.CurrentLocation), new GamePoint(room, mob.EndingLocation), (p1, p2) =>
            {
                // Euclidian Squared heuristic
                var dx = p1.X - p2.X;
                var dy = p1.Y - p2.Y;
                if (dx > 0)
                {
                    dx += 1;
                }

                if (dy > 0)
                {
                    dy += 1;
                }
                return Math.Sqrt(dx * dx + dy * dy);
            }, (p) =>
            {
                // Euclidian squared heuristic estimate
                var dx = p.X - mob.EndingLocation.X;
                var dy = p.Y - mob.EndingLocation.Y;
                return dx * dx + dy * dy;
            });
            mob.Path = path?.Reverse().Skip(1);
            return mob.Path?.FirstOrDefault();
        }