public static MudLikeOperationBuilder AddWorldDate(this MudLikeOperationBuilder builder, DateTime dateTime)
 {
     return(builder
            .StartContainer("dateview")
            .AddTextLine(dateTime.ToString("D"), TextColor.Fuschia, TextSize.Small)
            .EndContainer("dateview"));
 }
Ejemplo n.º 2
0
        private async Task HandleMapChanged(Object sender, IMapChangeEvent e)
        {
            if (e.OldMap != null)
            {
                await e.OldMap.RemovePlayerAsync(e.Player);

                await Game.Network.RemovePlayerFromMapGroupAsync(e.Player, e.OldMap);

                e.OldMap.PlayersChanged  -= MapPlayersChanged;
                e.OldMap.ItemsChanged    -= MapItemsChanged;
                e.OldMap.EntitiesChanged -= MapEntitiesChanged;


                var playersLeftBehind = e.OldMap.Players.Except(e.Player);

                var leftBehindNotification = MudLikeOperationBuilder.Start("playerlist")
                                             .AddPlayers(playersLeftBehind)
                                             .Build();
                await Game.Network.SendViewCommandsToMapAsync(e.OldMap, MudLikeViewBuilder.Start().AddOperation(leftBehindNotification).Build());
            }

            var map = (GridMap)e.NewMap;
            await Game.Network.AddPlayerToMapGroupAsync(e.Player, map);

            map.PlayersChanged  += MapPlayersChanged;
            map.ItemsChanged    += MapItemsChanged;;
            map.EntitiesChanged += MapEntitiesChanged;;


            var player   = e.Player;
            var lookView = MudLikeOperationBuilder.Start()
                           .AddWorldDate(Game.World.Time.WorldTime)
                           .AddMap(map)
                           .Build();


            await Game.Network.SendViewCommandsToPlayerAsync(player, MudLikeViewBuilder.Start().AddOperation(lookView).Build());

            // update the map with a new playerslist
            var playersUpdate = MudLikeOperationBuilder.Start("playerlist").AddPlayers(map.Players)
                                .Build();

            var itemsUpdate = MudLikeOperationBuilder.Start("itemlist").AddItems(map.Items)
                              .Build();

            var entitiesUpdate = MudLikeOperationBuilder.Start(MudContainers.EntityList.ToString()).AddEntities(map.Entities)
                                 .Build();

            var update = MudLikeViewBuilder.Start().AddOperation(playersUpdate).AddOperation(itemsUpdate).AddOperation(entitiesUpdate).Build();

            await Game.Network.SendViewCommandsToMapAsync(map, update);
        }
Ejemplo n.º 3
0
 private async Task SpawnerSpawned(ISpawnable spawned, IMap map)
 {
     if (spawned.GetType() == typeof(GridEntity))
     {
         var entity = (GridEntity)spawned;
         entity.Died += EntityDied;
     }
     else
     {
         var itemsUpdate = MudLikeOperationBuilder.Start("itemlist").AddItems(map.Items)
                           .Build();
         await Game.Network.SendViewCommandsToMapAsync(map, MudLikeViewBuilder.Start().AddOperation(itemsUpdate).Build());
     }
 }
Ejemplo n.º 4
0
        private Task ProcessItemPickupAsync(IProcessorData <CommandModel> request, IPlayer player)
        {
            request.Handled = true;

            Parser.Default.ParseArguments <ItemPickupParserOptions>(request.Data.StringFrom(2).Split(' '))
            .WithParsed(async(parsed) =>
            {
                var itemName = string.Join(" ", parsed.Name);

                // take each matching item up to the quantity we requested
                var mapItems = (
                    parsed.PickupAny ?
                    player.Map.Items :
                    player.Map.Items.Where(mi => mi.Name.IndexOf(itemName, StringComparison.OrdinalIgnoreCase) >= 0))
                               .Take(parsed.Quantity)
                               .ToList();

                if (mapItems.Count == 0)
                {
                    await Game.Network.SendMessageToPlayerAsync(player, "Matching item not found");
                    return;
                }

                itemName = mapItems[0].Name;

                await Game.Network.SendMessageToPlayerAsync(player, $"Looting {itemName} | quantity {mapItems.Count}");
                foreach (var i in mapItems)
                {
                    // double check one last time the item wasn't picked up elsewhere in the time we've been picking up others
                    if (player.Map.Items.Contains(i))
                    {
                        await player.PickupItemAsync(Game, i);
                    }
                }

                var itemView = MudLikeViewBuilder.Start()
                               .AddOperation(
                    MudLikeOperationBuilder.Start("itemlist").AddItems(player.Map.Items).Build())
                               .Build();


                await Game.Network.SendViewCommandsToMapAsync(player.Map, itemView);
            })
            .WithNotParsed(async(issues) =>
            {
                await Game.Network.SendMessageToPlayerAsync(player, "invalid command(pickup) - for help type item help");
            });

            return(Task.CompletedTask);
        }
Ejemplo n.º 5
0
        public override async Task IntervalTick(object sender, EventArgs e)
        {
            await base.IntervalTick(sender, e);

            var worldTime = ((GridWorld)Game.World).Time.WorldTime;

            if (lastRunWorldDate.Day != worldTime.Day)
            {
                lastRunWorldDate = worldTime;
                var viewUpdate = MudLikeOperationBuilder.Start("dateview")
                                 .AddWorldDate(worldTime)
                                 .Build();

                await Game.Network.SendViewCommandsToPlayersAsync(Game.Players, MudLikeViewBuilder.Start().AddOperation(viewUpdate).Build());
            }
        }
        public static MudLikeOperationBuilder AddMap(this MudLikeOperationBuilder builder, GridMap map, bool includePlayers = false)
        {
            builder
            .StartContainer("mapdata")
            .AddText($"{map.Id} ", TextColor.Gray, TextSize.Small)
            .AddTextLine(map.Name, color: TextColor.Aqua, size: TextSize.Strong)
            .AddTextLine(map.Description, size: TextSize.Strong)
            .AddText("Exits ")
            .AddTextLine(string.Join(",", map.Exits.Select(o => o.ToString().ToLower())), TextColor.Green)
            .EndContainer("mapdata");
            if (includePlayers)
            {
                builder.AddPlayers(map.Players);
            }

            return(builder);
        }
Ejemplo n.º 7
0
        private async Task HandleNewEncounter(IEncounter encounter)
        {
            encounter.ActionExecuted += Encounter_ActionExecuted;
            encounter.Ended          += Encounter_Ended;

            var map = ((GridPlayer)encounter.Combatants.First().Key).Map;

            await Game.Network.SendViewCommandsToMapAsync(map,
                                                          MudLikeViewBuilder.Start()
                                                          .AddOperation(
                                                              MudLikeOperationBuilder.Start($"enc_{encounter.Id}")
                                                              .StartContainer($"enc_{encounter.Id}")
                                                              .AddTextLine("Combat Starting")
                                                              .EndContainer($"enc_{encounter.Id}")
                                                              .Build()
                                                              )
                                                          .Build());
        }
Ejemplo n.º 8
0
        private async Task ProcessBasicLook(IProcessorData <CommandModel> request, IPlayer player)
        {
            request.Handled = true;
            if (!string.IsNullOrEmpty(request.Data.SecondPart))
            {
                await Game.Network.SendMessageToPlayerAsync(player, "Complex look not yet supported. Processing without arguments.");
            }

            var mapView = MudLikeOperationBuilder.Start()
                          .AddWorldDate(Game.World.Time.WorldTime)
                          .AddMap((GridMap)player.Map, includePlayers: true)
                          .Build();

            var itemsView = MudLikeOperationBuilder.Start("itemlist").AddItems(player.Map.Items)
                            .Build();

            var entitiesUpdate = MudLikeOperationBuilder.Start(MudContainers.EntityList.ToString()).AddEntities(player.Map.Entities)
                                 .Build();

            await Game.Network.SendViewCommandsToPlayerAsync(player, MudLikeViewBuilder.Start().AddOperation(mapView).AddOperation(itemsView).AddOperation(entitiesUpdate).Build());
        }
Ejemplo n.º 9
0
        private Task ProcessListSpawnersAsync(IProcessorData <CommandModel> request, IPlayer player)
        {
            request.Handled = true;

            Parser.Default.ParseArguments <ListSpawnerParserOptions>(request.Data.StringFrom(2).Split(' '))
            .WithParsed(async(parsed) =>
            {
                var validSpawnTypes = new List <string>()
                {
                    "item", "entity"
                };


                var match = validSpawnTypes.FirstOrDefault(s => s == parsed.SpawnType);
                if (match != null)
                {
                    validSpawnTypes.RemoveAll(s => s != match);
                }


                var viewbuilder = MudLikeViewBuilder.Start();

                var partial = Game.Spawners.Cast <GridSpawner>().Where(spawner => spawner.Map == player.Map).ToList();
                foreach (var spawnType in validSpawnTypes)
                {
                    IViewOperation <IViewItem> operation = null;
                    var opBuilder = MudLikeOperationBuilder.Start();
                    opBuilder
                    .AddTextLine(spawnType, TextColor.Olive)
                    .AddTextLine("------------------------------", TextColor.Olive);

                    switch (spawnType)
                    {
                    case "entity":
                        var entityMatches = partial.Where(spawner => spawner.SpawnType == Core.Game.SpawnType.Entity).Select(s => s.EntityId).ToList();
                        var entities      = Game.Entities.Where(e => entityMatches.Contains(e.Id)).ToList();
                        foreach (GridEntity entity in entities)
                        {
                            opBuilder
                            .AddText($"{entity.Id} ", TextColor.Aqua)
                            .AddText($"{entity.Name} ");


                            entity.Stats.ToList().ForEach(stat =>
                            {
                                opBuilder
                                .AddText($"{stat.Name} ", TextColor.Gray)
                                .AddText($"{stat.Value} ")
                                ;
                            });
                            opBuilder.AddLineBreak();
                        }

                        operation = opBuilder.Build();

                        break;

                    case "item":
                        var itemMatches = partial.Where(spawner => spawner.SpawnType == Core.Game.SpawnType.Item);
                        var items       = Game.Items.Where(e => itemMatches.Select(i => i.Id).Contains(e.Id)).ToList();

                        foreach (GridItem item in items)
                        {
                            opBuilder
                            .AddText($"{item.Id} ", TextColor.Aqua)
                            .AddText($"{item.Name} ")
                            ;

                            item.Stats.ToList().ForEach(stat =>
                            {
                                opBuilder
                                .AddText($"{stat.Name} ", TextColor.Gray)
                                .AddText($"{stat.Value} ")
                                ;
                            });
                            opBuilder.AddLineBreak();
                        }

                        operation = opBuilder.Build();
                        break;

                    default:
                        break;
                    }

                    if (operation != null)
                    {
                        viewbuilder.AddOperation(operation);
                    }
                }


                await Game.Network.SendViewCommandsToPlayerAsync(player, viewbuilder.Build());
            })
            .WithNotParsed(async(issues) =>
            {
                await Game.Network.SendMessageToPlayerAsync(player, "invalid command - for help type spawner help");
            });

            return(Task.CompletedTask);
        }
Ejemplo n.º 10
0
        private async Task Encounter_Ended(IEncounter encounter, EncounterEndings ending)
        {
            encounter.ActionExecuted -= Encounter_ActionExecuted;
            encounter.Ended          -= Encounter_Ended;

            if (ending == EncounterEndings.Expired)
            {
                return;
            }

            var gridEncounter = (GridEncounter)encounter;


            // allocate experience to winners

            var factionInfo = gridEncounter.Factions.Select(f => new
            {
                FactionName     = f.Key,
                FactionEntities = f.Value,
                isWinner        = f.Value.Count(e => !gridEncounter.Dead.Contains(e)) > 0,
                AverageLevel    = f.Value.Average(e => e.Stats.FirstOrDefault(s => s.Name == "level")?.Value).GetValueOrDefault(0),
                MinLevel        = f.Value.Min(e => e.Stats.FirstOrDefault(s => s.Name == "level")?.Value).GetValueOrDefault(0),
                MaxLevel        = f.Value.Max(e => e.Stats.FirstOrDefault(s => s.Name == "level")?.Value).GetValueOrDefault(0)
            }).ToList();


            // this would need updated to support more than 2 factions properly
            var winners = factionInfo.FirstOrDefault(f => f.isWinner);
            var losers  = factionInfo.FirstOrDefault(f => !f.isWinner);

            var cancelExperience = false;

            if (winners.MinLevel < winners.MaxLevel - 5)
            {
                cancelExperience = true;
            }


            var experienceScaler = 1 + (losers.AverageLevel - winners.AverageLevel) * 0.2;
            var experience       = (3 * losers.AverageLevel) * experienceScaler;

            if (!cancelExperience)
            {
                foreach (var winner in winners.FactionEntities)
                {
                    // players and monsters both gain experience the same for now
                    var experienceStat = (BasicStat)winner.Stats.FirstOrDefault(s => s.Name == "experience");
                    await experienceStat?.ApplyAsync(Convert.ToInt32(experience));

                    if (experienceStat != null)
                    {
                        // check if leveled
                        if (experienceStat.Value == experienceStat.Base)
                        {
                            var levelStat = winner.Stats.FirstOrDefault(s => s.Name == "level");
                            await levelStat?.ApplyAsync(1);

                            await experienceStat.RebaseAsync(Convert.ToInt32(experienceStat.Base * 1.5), 0);

                            // fill stats
                            var vitalStats = new List <string>()
                            {
                                "health", "mana", "stamina"
                            };
                            foreach (BasicStat stat in winner.Stats.Where(s => vitalStats.Contains(s.Name)).ToList())
                            {
                                await stat.Fill();
                            }
                        }
                    }
                }
            }



            foreach (var faction in factionInfo)
            {
                var players = faction.FactionEntities.Where(e => e.IsPlayer()).Select(e => e).Distinct();

                if (!players.Any())
                {
                    continue;
                }

                var combatView = MudLikeOperationBuilder.Start($"enc_{encounter.Id}")
                                 .StartContainer($"enc_{encounter.Id}").AddLineBreak();

                foreach (var entity in faction.FactionEntities)
                {
                    var experienceStat = entity.Stats.FirstOrDefault(s => s.Name == "experience");

                    combatView
                    .AddText(entity.Name, (entity.IsAlive && !encounter.Dead.Contains(entity) ? TextColor.Normal : TextColor.Red));
                    if (entity.IsAlive && !encounter.Dead.Contains(entity))
                    {
                        combatView
                        .AddText($" {entity.Stats.FirstOrDefault(s => s.Name == "health")?.Value}", TextColor.Green)
                        .AddText($" {entity.Stats.FirstOrDefault(s => s.Name == "mana")?.Value}", TextColor.Blue)
                        .AddText($" {entity.Stats.FirstOrDefault(s => s.Name == "stamina")?.Value}", TextColor.Yellow)
                        .AddText($" Lv {experienceStat.Value}/{experienceStat.Base}", TextColor.Yellow)
                        ;
                    }
                    else
                    {
                        combatView.AddText(" Dead", TextColor.Red, TextSize.Small);
                    }

                    combatView.AddLineBreak();
                }


                if (faction.isWinner)
                {
                    combatView.AddTextLine($"You earned {experience} experience");
                }
                else
                {
                    combatView.AddTextLine($"You lost the encounter.");
                }

                combatView.EndContainer($"enc_{encounter.Id}");


                var view = MudLikeViewBuilder.Start().AddOperation(combatView.Build()).Build();

                await Game.Network.SendViewCommandsToPlayersAsync(players.Cast <IPlayer>(), view);
            }
        }
Ejemplo n.º 11
0
        private async Task Encounter_ActionExecuted(IEncounter encounter, ICombatAction action)
        {
            // this whole thing can be optimized to send way smaller replacement segments later

            var combatView = MudLikeOperationBuilder.Start($"enc_{encounter.Id}")
                             .StartContainer($"enc_{encounter.Id}")
                             .AddTextLine("");

            var gridEncounter = (GridEncounter)encounter;
            var entityAction  = (GridTargetAction)action;

            //var dmgDone = encounter.ActionLog.Select((a) => (ICombatAction<GridEntity>)a)
            //      .GroupBy(a => new { a.SourceEntity })
            //      .Select(a => new { Attacker = a.Key.SourceEntity, Damage = a.Sum(s => s.DamageDone) })
            //  .ToList();

            //var dmgTaken = encounter.ActionLog.Select((a) => (GridSingleTargetAction)a)
            //                            .GroupBy(a => new { a.TargetEntity })
            //                            .Select(a => new { Attacked = a.Key.TargetEntity, Damage = a.Sum(s => s.DamageDone) })
            //                        .ToList();

            foreach (var factionName in gridEncounter.Factions.Keys)
            {
                var factionEntities = gridEncounter.Factions[factionName];


                foreach (var entity in factionEntities)
                {
                    combatView
                    .AddText(entity.Name, (entity.IsAlive && !encounter.Dead.Contains(entity) ? TextColor.Normal : TextColor.Red));
                    if (entity.IsAlive && !encounter.Dead.Contains(entity))
                    {
                        combatView
                        .AddText($" {entity.Stats.FirstOrDefault(s => s.Name == "health")?.Value}", TextColor.Green)
                        .AddText($" {entity.Stats.FirstOrDefault(s => s.Name == "mana")?.Value}", TextColor.Blue)
                        .AddText($" {entity.Stats.FirstOrDefault(s => s.Name == "stamina")?.Value}", TextColor.Yellow)
                        ;
                    }
                    else
                    {
                        combatView.AddText(" Dead", TextColor.Red, TextSize.Small);
                    }

                    //var entityDmgDone = dmgDone.FirstOrDefault(d => d.Attacker == entity);
                    //if (entityDmgDone != null)
                    //{
                    //    combatView
                    //        .AddText($" Dmg {entityDmgDone.Damage}", TextColor.Teal);
                    //    ;
                    //}
                    //var entityDmgTaken = dmgTaken.FirstOrDefault(d => d.Attacked == entity);
                    //if (entityDmgTaken != null)
                    //{
                    //    combatView
                    //        .AddText($" Taken {entityDmgTaken.Damage}", TextColor.Teal);
                    //    ;
                    //}

                    combatView.AddLineBreak();
                }

                combatView.AddTextLine("---------------------------");
            }


            // add last X actions
            var actions = encounter.ActionLog.OrderByDescending(a => a.ExecutedTime).Take(10).OrderBy(a => a.ExecutedTime).ToList();

            actions.ForEach((a) => a.AppendToOperation(combatView));

            combatView.EndContainer($"enc_{encounter.Id}");

            var view = MudLikeViewBuilder.Start()
                       .AddOperation(combatView.Build()
                                     ).Build();


            if (entityAction.TargetEntities.Contains(entityAction.SourceEntity) || entityAction.TargetEntities.Count == 0)
            {
                await Game.Network.SendViewCommandsToMapAsync(entityAction.SourceEntity.Map, view);
            }
            else
            {
                var maps = new List <IMap>()
                {
                    entityAction.SourceEntity.Map
                };
                maps.AddRange(entityAction.TargetEntities.Where(t => t.Map != entityAction.SourceEntity.Map).Select(t => t.Map).Distinct());

                maps.ForEach(async m => await Game.Network.SendViewCommandsToMapAsync(m, view));
            }
        }
Ejemplo n.º 12
0
        private Task ProcessEditAsync(IProcessorData <CommandModel> request, IPlayer player)
        {
            request.Handled = true;

            Parser.Default.ParseArguments <EditMapParserOptions>(request.Data.StringFrom(2).Split(' '))
            .WithParsed(async(parsed) =>
            {
                var mapId     = parsed.Id.HasValue ? parsed.Id.Value : player.Map.Id;
                var map       = Game.World.Maps.FirstOrDefault(m => m.Id == mapId);
                var hasUpdate = false;

                if (parsed.Name.Any())
                {
                    var completeName = string.Join(" ", parsed.Name);
                    if (!string.IsNullOrWhiteSpace(completeName))
                    {
                        map.Name  = completeName;
                        hasUpdate = true;
                    }
                }
                if (parsed.Description.Any())
                {
                    var complete = string.Join(" ", parsed.Description);
                    if (!string.IsNullOrWhiteSpace(complete))
                    {
                        map.Description = complete;
                        hasUpdate       = true;
                    }
                }

                parsed.AddExits.ToList().ForEach((exit) =>
                {
                    try
                    {
                        map.AddExit(Enum.Parse <Exits>(exit, ignoreCase: true));
                    }
                    catch (Exception)
                    {
                        Game.Log(Microsoft.Extensions.Logging.LogLevel.Information, "invalid exit..");
                    }

                    hasUpdate = true;
                });

                parsed.RemoveExits.ToList().ForEach((exit) =>
                {
                    map.RemoveExit(Enum.Parse <Exits>(exit, ignoreCase: true));
                    hasUpdate = true;
                });

                if (hasUpdate)
                {
                    await Game.Store.UpdateMapsAsync(Game, new List <IMap>()
                    {
                        map
                    });

                    var mapView = MudLikeOperationBuilder.Start("mapdata").AddMap(map).Build();

                    await Game.Network.SendViewCommandsToMapAsync(map, MudLikeViewBuilder.Start().AddOperation(mapView).Build());
                }
            })
            .WithNotParsed(async(issues) =>
            {
                await Game.Network.SendMessageToPlayerAsync(player, "invalid command(edit) - for help type map help");
            });

            return(Task.CompletedTask);
        }
Ejemplo n.º 13
0
 private async Task MapEntitiesChanged(IMap map, IReadOnlyList <IEntity> entities)
 {
     var entitiesUpdate = MudLikeOperationBuilder.Start(MudContainers.EntityList.ToString()).AddEntities(entities)
                          .Build();
     await Game.Network.SendViewCommandsToMapAsync(map, MudLikeViewBuilder.Start().AddOperation(entitiesUpdate).Build());
 }
 public static MudLikeOperationBuilder AddEntities(this MudLikeOperationBuilder builder, IEnumerable <IEntity> entities)
 {
     return(builder.StartContainer(MudContainers.EntityList.ToString()).AddText("entities: ")
            .AddText(string.Join(",", entities.Select(p => p.Name)), TextColor.Red)
            .EndContainer(MudContainers.EntityList.ToString()));
 }
 public static MudLikeOperationBuilder AddItems(this MudLikeOperationBuilder builder, IEnumerable <IItem> items)
 {
     return(builder.StartContainer("itemlist").AddText("ground items: ")
            .AddText(string.Join(",", items.Select(p => p.Name)), TextColor.Olive)
            .EndContainer("itemlist"));
 }
 public static MudLikeOperationBuilder AddPlayers(this MudLikeOperationBuilder builder, IEnumerable <IPlayer> players)
 {
     return(builder.StartContainer("playerlist").AddText("players: ")
            .AddText(string.Join(",", players.Select(p => p.Name)), TextColor.Gray)
            .EndContainer("playerlist"));
 }
Ejemplo n.º 17
0
 private async Task MapPlayersChanged(IMap map, IReadOnlyList <IPlayer> arg)
 {
     var playersUpdate = MudLikeOperationBuilder.Start("playerlist").AddPlayers(map.Players)
                         .Build();
     await Game.Network.SendViewCommandsToMapAsync(map, MudLikeViewBuilder.Start().AddOperation(playersUpdate).Build());
 }
Ejemplo n.º 18
0
 private async Task MapItemsChanged(IMap map, IReadOnlyList <IItem> arg)
 {
     var itemsUpdate = MudLikeOperationBuilder.Start("itemlist").AddItems(map.Items)
                       .Build();
     await Game.Network.SendViewCommandsToMapAsync(map, MudLikeViewBuilder.Start().AddOperation(itemsUpdate).Build());
 }