Ejemplo n.º 1
0
        /// <summary>
        /// Regenerates a site's actors based on the sitedata. If it is not marked as needing regeneration , will do nothing
        /// </summary>
        /// <param name="sitedata"></param>
        /// <param name="currentMap"></param>
        /// <param name="actors"></param>
        /// <returns></returns>
        public static MapBlock[,] RegenerateSite(SiteData sitedata, MapBlock[,] currentMap, Actor[] currentActors, out Actor[] newActors)
        {
            if (!sitedata.MapRegenerationRequired)
            {
                //Do nothing
                newActors = currentActors;
                return currentMap;
            }

            //So, first go through the actors and remove any of them which shouldn't be there. That is to say all of them which are site members (I realise it's a big ugly but it's a clean check)
            List<Actor> actors = currentActors.ToList();

            var actorsToRemove = currentActors.Where(ca => ca.SiteMember);

            //Remove the map items for these actors
            foreach(var a in actorsToRemove)
            {
                a.IsAlive = false;
            }

            //We'll handle actors soon, first we need to go through all the items and set the ones with the wrong owner to inactive
            foreach (var mapBlock in currentMap)
            {
                foreach (var item in mapBlock.GetItems())
                {
                    if (!item.OwnedBy.HasFlag(sitedata.Owners))
                    {
                        item.IsActive = false;
                    }
                    else
                    {
                        item.IsActive = true;
                    }
                }
            }

            //Now go through the site's actors and create the new ones as required
            foreach (ActorProfession profession in Enum.GetValues(typeof(ActorProfession)))
            {
                //So do we have any wander areas for them ?
                var possibleAreas = sitedata.WanderAreas.Where(wa => wa.Factions.HasFlag(sitedata.Owners) && wa.Profession.Equals(profession));
                var possibleRoutes = sitedata.PatrolRoutes.Where(pr => pr.Owners.HasFlag(sitedata.Owners) && pr.Profession.Equals(profession));

                //Any actors?
                if (sitedata.ActorCounts.ContainsKey(profession))
                {
                    //Yes, how many
                    int total = sitedata.ActorCounts[profession];

                    var a = ActorGeneration.CreateActors(sitedata.Owners, profession, total);

                    foreach (var ac in a)
                    {
                        ac.SiteMember = true;
                    }

                    actors.AddRange(a);

                    foreach (var actor in a)
                    {
                        //So, where we going to drop them off ? Randomly
                        int tries = 0;

                        for (; ; )
                        {
                            int randomX = GameState.Random.Next(currentMap.GetLength(0));
                            int randomY = GameState.Random.Next(currentMap.GetLength(1));

                            if (currentMap[randomX, randomY].MayContainItems)
                            {
                                //Plop it on there
                                actor.MapCharacter.Coordinate = new MapCoordinate(randomX, randomY, 0, MapType.LOCAL);
                                currentMap[randomX, randomY].ForcePutItemOnBlock(actor.MapCharacter);
                                tries = 0;
                                break;
                            }
                            else
                            {
                                tries++;
                            }

                            if (tries >= 150)
                            {
                                //give up
                                break;
                            }
                        }

                        //Go through each actor, and either tell them to wander in the whole map, or within any possible area which matches
                        //Any possible area avaialble?
                        List<object> possibleMissions = new List<object>(); //I know :( But Using an interface or trying to mangle together an inheritance was worse

                        possibleMissions.AddRange(possibleAreas.Where(pa => pa.MaxAmount > pa.CurrentAmount));
                        possibleMissions.AddRange(possibleRoutes);

                        var chosenArea = possibleMissions.OrderBy(pa => GameState.Random.Next(100)).FirstOrDefault();

                        if (chosenArea == null)
                        {
                            //Wander around the whole map
                            actor.CurrentMission = new WanderMission() { LoiterPercentage = 25, WanderPoint = new MapCoordinate(currentMap.GetLength(0) / 2, currentMap.GetLength(1) / 2, 0, MapType.LOCAL), WanderRectangle = new Rectangle(0, 0, currentMap.GetLength(0), currentMap.GetLength(1)) };
                        }
                        else
                        {
                            //Is this a patrol or a wander ?
                            if (chosenArea.GetType().Equals(typeof(PatrolRoute)))
                            {
                                var patrolDetails = chosenArea as PatrolRoute;

                                PatrolRouteMission pm = new PatrolRouteMission();
                                pm.PatrolRoute.AddRange(patrolDetails.Route);

                                actor.CurrentMission = pm;
                            }
                            else if (chosenArea.GetType().Equals(typeof(MapletActorWanderArea)))
                            {
                                var wanderDetails = chosenArea as MapletActorWanderArea;

                                //Wander around in that area
                                actor.CurrentMission = new WanderMission() { LoiterPercentage = 25, WanderPoint = new MapCoordinate(wanderDetails.WanderPoint), WanderRectangle = wanderDetails.WanderRect };
                                wanderDetails.CurrentAmount++;
                            }
                        }

                    }

                }

            }

            newActors = actors.ToArray();
            sitedata.MapRegenerationRequired = false; //We're done

            return currentMap;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Generates a site
        /// </summary>
        /// <param name="siteType"></param>
        /// <param name="biomeType"></param>
        /// <param name="owner"></param>
        /// <param name="startPoint"></param>
        /// <param name="actors"></param>
        /// <returns></returns>
        public static MapBlock[,] GenerateSite(SiteData siteData, out Actor[] actors)
        {
            MapCoordinate startPoint = null;

            //First we generate some empty wilderness of the right type
            MapBlock[,] map = WildernessGenerator.GenerateMap(siteData.Biome, 0, 0, out actors, out startPoint);

            //Now, clear the tiles from between 5,5 till 25,25
            for (int x = 5; x < 26; x++)
            {
                for (int y = 5; y < 26; y++)
                {
                    MapBlock block = map[x, y];
                    block.RemoveAllItems();
                }
            }

            ItemFactory.ItemFactory itemFactory = new ItemFactory.ItemFactory();

            int waterID = 0;

            MapItem waterTile = itemFactory.CreateItem(Archetype.TILES, "water", out waterID);

            //If it's a fishing village, put some water in
            if (siteData.SiteTypeData.SiteType == SiteType.FISHING_VILLAGE)
            {
                for (int x = 0; x < map.GetLength(0); x++)
                {
                    for (int y = map.GetLength(1) - 10; y < map.GetLength(1); y++)
                    {
                        MapBlock block = map[x, y];
                        block.RemoveAllItems();

                        //Set the tile to water
                        block.Tile = itemFactory.CreateItem("tiles", waterID);
                        block.Tile.Coordinate = new MapCoordinate(x, y, 0, MapType.LOCAL);
                    }
                }
            }

            LocalMapGenerator lmg = new LocalMapGenerator();

            LocalMapXMLParser parser = new LocalMapXMLParser();

            Maplet maplet = parser.ParseMapletFromTag(siteData.SiteTypeData.SiteType.ToString().Replace("_", " ").ToLower(),siteData.Biome);

            var tileID = DatabaseHandling.GetItemIdFromTag(Archetype.TILES, WildernessGenerator.details[siteData.Biome].BaseTileTag);

            MapletActorWanderArea[] wanderAreas = null;
            MapletPatrolPoint[] patrolPoints = null;
            MapletFootpathNode[] footPath = null;

            //Now generate the actual map
            MapBlock[,] siteMap = lmg.GenerateMap(tileID, null, maplet, false, "", siteData.Owners, out actors, out wanderAreas, out patrolPoints, out footPath);

            //Now lets fuse the maps
            map = lmg.JoinMaps(map, siteMap, 5, 5);

            foreach (var actor in actors)
            {
                if (actor.CurrentMission == null)
                {
                    actor.CurrentMission = actor.MissionStack.Count > 0 ? actor.MissionStack.Pop() : null;
                }

                if (actor.CurrentMission != null && actor.CurrentMission.GetType() == typeof(WanderMission))
                {
                    WanderMission wMiss = actor.CurrentMission as WanderMission;

                    wMiss.WanderPoint.X += 5;
                    wMiss.WanderPoint.Y += 5;

                    wMiss.WanderRectangle = new Rectangle(wMiss.WanderRectangle.X + 5, wMiss.WanderRectangle.Y + 5, wMiss.WanderRectangle.Width, wMiss.WanderRectangle.Height);
                }
            }

            //Fix the patrol points

            foreach (var point in patrolPoints)
            {
                point.Point.X += 5;
                point.Point.Y += 5;
            }

            //Let's fix the patrol points, we need to merge them into PatrolRoutes
            var patrolRoutes = PatrolRoute.GetPatrolRoutes(patrolPoints);

            foreach (var area in wanderAreas)
            {
                area.WanderRect = new Rectangle(area.WanderRect.X + 5, area.WanderRect.Y + 5, area.WanderRect.Width, area.WanderRect.Height);
            }

            //And fix the path nodes
            foreach (var pn in footPath)
            {
                pn.Point.X += 5;
                pn.Point.Y += 5;
            }

            //If the map already has any actors in it, make the characters prone
            foreach (var actor in actors)
            {
                actor.IsProne = true;
            }

            //Now generate the pathfinding map
            PathfinderInterface.Nodes = GeneratePathfindingMap(map);

            int pathTileID = -1;

            var dummy = itemFactory.CreateItem(Archetype.TILES, "stone", out pathTileID);

            //Go through each footpath node. Attempt to connect the node with the other primary nodes
            foreach (var fp in footPath)
            {
                foreach (var primary in footPath.Where(p => p.IsPrimary))
                {
                    //Join them up
                    var path = PathfinderInterface.GetPath(fp.Point, primary.Point);
                    if (path != null)
                    {
                        foreach (var coord in path)
                        {
                            MapBlock block = map[coord.X, coord.Y];

                            //Only do this if the tile isn't wood, or stone
                            if (!block.Tile.InternalName.ToUpper().Contains("STONE") && !block.Tile.InternalName.ToUpper().Contains("WOOD"))
                            {
                                block.Tile = itemFactory.CreateItem("tiles", pathTileID);
                                block.Tile.Coordinate = new MapCoordinate(coord);
                            }

                        }
                    }
                }
            }

            List<Actor> actorList = new List<Actor>();

            actorList.AddRange(actors); //And add the actors

            //Let's generate a number of actors then
            foreach (ActorProfession profession in Enum.GetValues(typeof(ActorProfession)))
            {
                //So do we have any wander areas for them ?
                var possibleAreas = wanderAreas.Where(wa => wa.Factions.HasFlag(siteData.Owners) && wa.Profession.Equals(profession));
                var possibleRoutes = patrolRoutes.Where(pr => pr.Owners.HasFlag(siteData.Owners) && pr.Profession.Equals(profession));

                //Any actors?
                if (siteData.ActorCounts.ContainsKey(profession))
                {
                    //Yes, how many
                    int total = siteData.ActorCounts[profession];

                    var a = ActorGeneration.CreateActors(siteData.Owners, profession, total);

                    foreach(var ac in a)
                    {
                        ac.SiteMember = true;
                    }

                    actorList.AddRange(a);

                    foreach (var actor in a)
                    {
                        //So, where we going to drop them off ? Randomly
                        int tries = 0;

                        for (; ; )
                        {
                            int randomX = GameState.Random.Next(map.GetLength(0));
                            int randomY = GameState.Random.Next(map.GetLength(1));

                            if (map[randomX, randomY].MayContainItems)
                            {
                                //Plop it on there
                                actor.MapCharacter.Coordinate = new MapCoordinate(randomX, randomY, 0, MapType.LOCAL);
                                map[randomX, randomY].ForcePutItemOnBlock(actor.MapCharacter);
                                tries = 0;
                                break;
                            }
                            else
                            {
                                tries++;
                            }

                            if (tries >= 150)
                            {
                                //give up
                                break;
                            }
                        }

                        //Go through each actor, and either tell them to wander in the whole map, or within any possible area which matches
                        //Any possible area avaialble?
                        List<object> possibleMissions = new List<object>(); //I know :( But Using an interface or trying to mangle together an inheritance was worse

                        possibleMissions.AddRange(possibleAreas.Where(pa => pa.MaxAmount > pa.CurrentAmount));
                        possibleMissions.AddRange(possibleRoutes);

                        var chosenArea = possibleMissions.OrderBy(pa => GameState.Random.Next(100)).FirstOrDefault();

                        if (chosenArea == null)
                        {
                            //Wander around the whole map
                            actor.CurrentMission = new WanderMission() { LoiterPercentage = 25, WanderPoint = new MapCoordinate(map.GetLength(0) / 2, map.GetLength(1) / 2, 0, MapType.LOCAL), WanderRectangle = new Rectangle(0, 0, map.GetLength(0), map.GetLength(1)) };
                        }
                        else
                        {
                            //Is this a patrol or a wander ?
                            if (chosenArea.GetType().Equals(typeof(PatrolRoute)))
                            {
                                var patrolDetails = chosenArea as PatrolRoute;

                                PatrolRouteMission pm = new PatrolRouteMission();
                                pm.PatrolRoute.AddRange(patrolDetails.Route);

                                actor.CurrentMission = pm;
                            }
                            else if (chosenArea.GetType().Equals(typeof(MapletActorWanderArea)))
                            {
                                var wanderDetails = chosenArea as MapletActorWanderArea;

                                //Wander around in that area
                                actor.CurrentMission = new WanderMission() { LoiterPercentage = 25, WanderPoint = new MapCoordinate(wanderDetails.WanderPoint), WanderRectangle = wanderDetails.WanderRect };
                                wanderDetails.CurrentAmount++;
                            }
                        }

                    }

                }

            }

            actors = actorList.ToArray();

            siteData.PatrolRoutes = patrolRoutes.ToList();
            siteData.WanderAreas = wanderAreas.ToList();

            return map;
        }
Ejemplo n.º 3
0
        public static ActionFeedback[] PatrolRouteMission(PatrolRouteMission mission, Actor actor)
        {
            //Push it back on the stack
            actor.MissionStack.Push(mission);

            var nextPoint = mission.GetNextPoint();

            //Create a move to mission which moves the actor to the next point
            WalkToMission wTM = new WalkToMission()
            {
                TargetCoordinate = nextPoint.Coordinate,
                AcceptableRadius = nextPoint.AcceptableRadius
            };

            actor.CurrentMission = wTM;

            //Log it
            Console.WriteLine("Actor " + actor.ToString() + " is going to" + wTM.TargetCoordinate.ToString() + " as part of his patrol route");

            return new ActionFeedback[] { };
        }