Beispiel #1
0
        public override TagCompound Save()
        {
            IList <TagCompound> villagerData = new List <TagCompound>();

            for (int i = 0; i < Main.maxNPCs; i++)
            {
                NPC npcAtIndex = Main.npc[i];
                if (!LWMUtils.IsTypeOfVillager(npcAtIndex))
                {
                    continue;
                }
                else
                {
                    TagCompound villagerDataTag = new TagCompound
                    {
                        { "type", (int)((Villager)npcAtIndex.modNPC).villagerType },
                        { "spriteVar", ((Villager)npcAtIndex.modNPC).spriteVariation },
                        { "x", npcAtIndex.Center.X },
                        { "y", npcAtIndex.Center.Y },
                        { "name", npcAtIndex.GivenName },
                        { "homePos", ((Villager)npcAtIndex.modNPC).homePosition }
                    };
                    villagerData.Add(villagerDataTag);
                }
            }
            return(new TagCompound {
                { "VillageReputation", villageReputation },
                { "VillagerData", villagerData },
                { "VillageGiftCooldown", villageGiftCooldown }
            });
        }
 private void NPC_VanillaFindFrame(On.Terraria.NPC.orig_VanillaFindFrame orig, NPC self, int frameHeight)
 {
     if (LWMUtils.IsTypeOfVillager(self))
     {
         self.townNPC = true;
     }
     orig(self, frameHeight);
     if (LWMUtils.IsTypeOfVillager(self))
     {
         self.townNPC = false;
     }
 }
 private void NPC_AI_007_TownEntities(On.Terraria.NPC.orig_AI_007_TownEntities orig, NPC self)
 {
     if (LWMUtils.IsTypeOfVillager(self))
     {
         self.townNPC   = true;
         self.homeTileX = (int)((Villager)self.modNPC).homePosition.X;
         self.homeTileY = (int)((Villager)self.modNPC).homePosition.Y;
     }
     orig(self);
     if (LWMUtils.IsTypeOfVillager(self))
     {
         self.townNPC = false;
     }
 }
Beispiel #4
0
 public static void TileRightClicked(int i, int j, VillagerType villageShrineType)
 {
     shrineType = villageShrineType;
     Instance.Toggle();
     itemSlotPos = LWMUtils.FindMultiTileTopLeft(i, j, TileType <HarpyShrineTile>()) + new Vector2(-5, -11);
 }
Beispiel #5
0
        private void SkyVillageGenTask(GenerationProgress progress)
        {
            progress.Message = "Generating Structures...Sky Village";
            progress.Start(0f);


            #region Mapping Floating Islands

            List <FloatingIsland> islands = new List <FloatingIsland>();
            int    islandsZone            = (int)(Main.maxTilesY * 0.18f);
            bool[] visitedCoords          = new bool[Main.maxTilesX * islandsZone];

            bool validCoordinate(Point16 pos)
            {
                //Making sure the coordinate is within the visitedCoords array
                if (pos.Y >= islandsZone)
                {
                    return(false);
                }

                Tile tile = Framing.GetTileSafely(pos);

                if (tile.type != TileID.Cloud && tile.type != TileID.RainCloud)
                {
                    return(false);
                }

                return(true);
            }

            //left top most visible screen coord is (41, 41)?
            for (int i = 41; i < Main.maxTilesX; i++)
            {
                for (int j = 41; j < islandsZone; j++)
                {
                    Point16 currentPos = new Point16(i, j);
                    if (!validCoordinate(currentPos))
                    {
                        continue;
                    }

                    List <Point16> currentIsland = new List <Point16>();

                    //Simple BFS Algorithm implementation
                    Queue <TileNode> queue        = new Queue <TileNode>();
                    TileNode         startingNode = new TileNode(currentPos);
                    queue.Enqueue(startingNode);

                    while (queue.Count != 0)
                    {
                        TileNode activeNode = queue.Dequeue();
                        if (!validCoordinate(activeNode.position))
                        {
                            continue;
                        }

                        //1D array that holds values of 2D coordinates needs a special formula for the index
                        int index = activeNode.position.Y * Main.maxTilesX + activeNode.position.X;
                        //index = row * maxColumns + column

                        if (visitedCoords[index])
                        {
                            continue;
                        }
                        else
                        {
                            visitedCoords[index] = true;
                        }

                        //If current coord wasn't visited yet, add it to the current island list
                        currentIsland.Add(activeNode.position);

                        List <TileNode> childNodes = activeNode.GetChildren();
                        childNodes.ForEach(child => queue.Enqueue(child));
                    }

                    //300 tiles? I should probably make some tests and define an average/2
                    if (currentIsland.Count > 300)
                    {
                        islands.Add(new FloatingIsland(currentIsland));
                    }

                    progress.Set((i * j / visitedCoords.Length) * 0.80f);
                }
            }

            #endregion

            #region Finding Suitable Spot and Generating it

            int structureWidth  = 160;
            int structureHeight = 92;

            //TODO: MAKE IT CHOOSE SPOTS THAT ARE NOT IN BETWEEN ISLANDS IF THEY'RE CLOSER TO THE CENTER (can happen in small worlds)
            //X
            int worldCenter = Main.maxTilesX / 2;
            int biggestDistanceBetweenIslands = 0;
            int smallestDistanceToWorldCenter = Main.maxTilesX;
            int xCoord = 0;

            for (int i = 0; i < islands.Count; i++)
            {
                //Can't do islands[i + 1] on last element
                if (i != islands.Count - 1)
                {
                    //Finding the biggest distance between two islands where the middle spot between the two is the closest to the world center
                    int distanceBetweenIslands =
                        Math.Abs(islands[i + 1].xMin - islands[i].xMax); //Math.Abs not needed since they're ordered?
                    int theoricalXCoord = islands[i].xMax + distanceBetweenIslands / 2 - structureWidth / 2;

                    if (distanceBetweenIslands > biggestDistanceBetweenIslands &&
                        Math.Abs(theoricalXCoord - worldCenter) < smallestDistanceToWorldCenter)
                    {
                        biggestDistanceBetweenIslands = distanceBetweenIslands;
                        smallestDistanceToWorldCenter = Math.Abs(theoricalXCoord - worldCenter);
                        xCoord = theoricalXCoord;
                    }
                }
            }

            progress.Set(0.85f);

            //Y
            int yAverage = 0;
            foreach (FloatingIsland island in islands)
            {
                yAverage += island.GetYAverage();
            }
            yAverage /= islands.Count;

            //Make sure structure y value doesn't go below 41 (world border)
            yAverage = yAverage - structureHeight > 41 ? yAverage - structureHeight : 42;

            progress.Set(0.90f);
            StructureHelper.StructureHelper.GenerateStructure("Structures/SkyVillageStructure",
                                                              new Point16(xCoord, yAverage), mod);

            #endregion

            //Finding shrine top left position
            for (int i = xCoord; i < xCoord + structureWidth; i++)
            {
                for (int j = yAverage; j < yAverage + structureHeight; j++)
                {
                    if (Framing.GetTileSafely(i, j).type == TileType <HarpyShrineTile>())
                    {
                        shrineCoords[(int)VillagerType.Harpy] =
                            LWMUtils.FindMultiTileTopLeft(i, j, TileType <HarpyShrineTile>());
                    }
                }
            }

            //This Gen task is in the Sky Village Gen task since the islands are mapped in this method, and we need those
            SkyBudGenTask(progress, islands);

            progress.End();
        }