Esempio n. 1
0
    public Inventory GetSecondInventory()
    {
        if (SecondInventory.Inventory == null)
        {
            Vec2i playerPos = Vec2i.FromVector2(Player.Position2);
            //Get current object on player position
            WorldObjectData currentSpace = GameManager.WorldManager.World.GetWorldObject(playerPos);
            if (currentSpace == null)
            {
                //if there is no object here, we create one
                LootSack lootsack = new LootSack(playerPos.AsVector3());
                GameManager.WorldManager.AddNewObject(lootsack);
                SecondInventory.SetInventory(lootsack.GetInventory());

                SecondInventory.gameObject.SetActive(true);

                return(SecondInventory.Inventory);
            }
            //If current tile is taken, we check all the surrounding tiles
            Vec2i[] surrounding = GameManager.WorldManager.World.EmptyTilesAroundPoint(playerPos);
            foreach (Vec2i v in surrounding)
            {
                WorldObjectData surSpace = GameManager.WorldManager.World.GetWorldObject(v);
                if (surSpace == null)
                {
                    //if there is no object here, we create one
                    LootSack lootsack = new LootSack(v.AsVector3());
                    GameManager.WorldManager.AddNewObject(lootsack);
                    SecondInventory.SetInventory(lootsack.GetInventory());

                    SecondInventory.gameObject.SetActive(true);

                    return(SecondInventory.Inventory);
                }
            }
            //If there is no space near, we return null
            return(null);
        }
        else
        {
            //If the inventory is not null, we add to it
            return(SecondInventory.Inventory);
        }
    }
Esempio n. 2
0
    public void AddBuilding(Building b, BuildingVoxels vox, Vec2i pos)
    {
        float minHeight = 0;

        //SetTiles(pos.x, pos.z, b.Width, b.Height, b.BuildingTiles);
        for (int x = 0; x < b.Width; x++)
        {
            for (int z = 0; z < b.Height; z++)
            {
                int cx = WorldToChunk(x);
                int cz = WorldToChunk(z);

                int deltaHeight = ChunkBases != null ? (int)(minHeight - ChunkBases[cx, cz].Height) : 0;

                SetTile(x + pos.x, z + pos.z, b.BuildingTiles[x, z]);
                SetHeight(x + pos.x, z + pos.z, minHeight);



                for (int y = 0; y < vox.Height; y++)
                {
                    VoxelNode voxNode = vox.GetVoxelNode(x, y, z);
                    if (voxNode.IsNode)
                    {
                        //Debug.Log("Adding vox node: " + voxNode);
                        SetVoxelNode(x + pos.x, y, z + pos.z, vox.GetVoxelNode(x, y, z));
                    }
                }
            }
        }
        foreach (WorldObjectData obj in b.GetBuildingExternalObjects())
        {
            obj.SetPosition(obj.Position + pos.AsVector3());
            //We (should) already have checked for object validity when creating the building
            AddObject(obj, true);
        }
    }
Esempio n. 3
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="genRan">The RNG used for this building</param>
    /// <param name="obj">The object to place in the building</param>
    /// <param name="height">The height above the ground the object should sit</param>
    /// <param name="vox">The voxel data of this building. Only required if 'requireWallBacking' is true</param>
    /// <param name="build">The building to place the object in</param>
    /// <param name="distFromWall">The distance from a wall the object should be placed</param>
    /// <param name="wallIndex">Defines the wall we should attempt to place this object on. The 'i'th wall defines the wall
    /// connecting build.BoundingWall[i] -> build.BoundingWall[i+1]. If left as default value (-1), an index will be randomly generated</param>
    /// <param name="requireWallBacking">If true, then we will search for a point on the wall that is backed against a wall.
    /// Used to stop certain objects being placed in front of windows</param>
    /// <param name="forcePlace">If true, then we do not check for intersection with other objects in the building</param>
    /// <param name="attemptsCount">The number of attempts made to place the object on this wall</param>
    /// <returns>True if object is placed sucesfully, false otherwise</returns>
    public static bool PlaceObjectAgainstWall(GenerationRandom genRan, WorldObjectData obj, float height,
                                              BuildingVoxels vox, Building build, float distFromWall = 0, bool requireWallBacking = false, int distToEntr = 2,
                                              bool forcePlace = false, int attemptsCount = 5)
    {
        if (build.InsideWallPoints == null)
        {
            build.InsideWallPoints = FindInsideWallBoundryPoints(vox, build);
        }

        //Check attempts count
        attemptsCount--;
        if (attemptsCount == 0)
        {
            return(false);
        }

        float wallDisp = genRan.Random();
        //Define the position as the start pos + lambda*dir
        //Select a random position from all wall points
        Vec2i pos = genRan.RandomFromArray(build.InsideWallPoints);

        //If too close to entrance, try another placement
        if (build.Entrance != null && pos.QuickDistance(build.Entrance) < distToEntr * distToEntr)
        {
            return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
        }
        //If the object is too close to any of the corners, try again
        foreach (Vec2i v in build.BoundingWall)
        {
            if (v.QuickDistance(pos) < 2)
            {
                return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
            }
        }

        Vec2i faceDirection = GetWallPointDirection(build, pos);

        //If we require a backing wall, we check the position
        if (requireWallBacking)
        {
            Vec2i wPos = pos - faceDirection;
            for (int y = 0; y < 4; y++)
            {
                VoxelNode vn = vox.GetVoxelNode(wPos.x, y, wPos.z);
                //If there is no node (nothing set) then this position is not valid
                if (!vn.IsNode)
                {
                    return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
                }
                if (vn.Voxel == Voxel.glass || vn.Voxel == Voxel.none)
                {
                    return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
                }
            }
        }
        Vector3 finPos   = pos.AsVector3() + faceDirection.AsVector3() * distFromWall + Vector3.up * height;
        float   rotation = Vec2i.Angle(Vec2i.Forward, faceDirection);

        obj.SetPosition(finPos).SetRotation(rotation);
        if (!forcePlace)
        {
            foreach (WorldObjectData obj_ in build.GetBuildingExternalObjects())
            {
                if (obj.Intersects(obj_))
                {
                    return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
                }
            }
        }


        //obj.SetPosition(finPos);
        build.AddInternalObject(obj);
        return(true);
    }
Esempio n. 4
0
    /// <summary>
    /// used to move an entity from one subworld to another
    /// </summary>
    /// <param name="entity"></param>
    /// <param name="newSubworldID"></param>
    /// <param name="newPosition"></param>
    public void MoveEntity(Entity entity, int newSubworldID, Vec2i newPosition)
    {
        Vec2i oldChunk  = World.GetChunkPosition(entity.Position);
        bool  succesful = false;

        if (EntitiesByLocation.TryGetValue(entity.CurrentSubworldID, out Dictionary <Vec2i, List <int> > subworldEnts))
        {
            if (subworldEnts.TryGetValue(oldChunk, out List <int> entIds))
            {
                //if this entity is here, we remove them
                if (entIds.Contains(entity.ID))
                {
                    entIds.Remove(entity.ID);
                    succesful = true;
                }
            }
        }

        if (!succesful)
        {
            Debug.LogError("Could not find old location of entity: " + entity);
            throw new System.Exception("loool");
        }

        int id = entity.ID;
        //get world ID and chunk position
        Vec2i cPos = World.GetChunkPosition(newPosition);

        if (!EntitiesByLocation.ContainsKey(newSubworldID))
        {
            EntitiesByLocation.Add(newSubworldID, new Dictionary <Vec2i, List <int> >());
        }

        if (!EntitiesByLocation[newSubworldID].ContainsKey(cPos))
        {
            EntitiesByLocation[newSubworldID].Add(cPos, new List <int>());
        }

        EntitiesByLocation[newSubworldID][cPos].Add(id);


        Subworld sw = World.Instance.GetSubworld(newSubworldID);


        if (sw != null)
        {
            sw.AddEntity(entity);
        }
        entity.SetSubworld(newSubworldID);
        entity.SetPosition(newPosition.AsVector3());
        entity.SetLastChunk(cPos);
        int loadedSubworldID = Subworld == null ? -1 : Subworld.SubworldID;

        //If the current entity is loaded...
        if (IsEntityLoaded(entity.ID))
        {
            Debug.Log("1");
            //Check if the new position is loaded, if not then we unload the entity
            if (!LoadedChunks.Contains(cPos) || (entity.CurrentSubworldID != loadedSubworldID))
            {
                Debug.Log("2");
                //If the new position isn't loaded, then we must unload the entity
                //If correct chunk position is loaded, but wrong world, we also unload
                UnloadEntity(entity.GetLoadedEntity(), false);
                //If the entity is now in a subworld after being unloaded,
                //we must check if they are close enough to the player to have a slow update.
                if (entity.CurrentSubworldID != -1)
                {
                    if (sw != null)
                    {
                        //We get the entrance, and check if the relvent chunk is loaded
                        Vec2i entranceChunk = World.GetChunkPosition(sw.ExternalEntrancePos);
                        //If it is, then we make sure we continue to run slow ticks on the unloaded entity
                        if (LoadedChunks.Contains(entranceChunk))
                        {
                            UnloadedUpdatableEntities.Add(entity.ID);
                        }
                    }
                }
            }
        }
        else
        {
            if (LoadedChunks.Contains(cPos) && (entity.CurrentSubworldID == loadedSubworldID))
            {
                LoadEntity(entity);
            }
        }
    }
 public WorldObjectData SetPosition(Vec2i nPos)
 {
     this.Position = nPos.AsVector3();
     return(this);
 }
 public bool IntersectsPoint(Vec2i point)
 {
     return(Vector3.Distance(point.AsVector3(), Position) <= Mathf.Max(Size.x, Size.y, Size.z));
 }
Esempio n. 7
0
    /// <summary>
    /// Adds the building to the settlement
    /// </summary>
    /// <param name="b"></param>
    /// <param name="vox"></param>
    /// <param name="pos"></param>
    /// <returns></returns>
    public Recti AddBuilding(Building b, BuildingVoxels vox, Vec2i pos)
    {
        if (!IsAreaFree(pos.x, pos.z, b.Width, b.Height))
        {
            return(null);
        }


        int nodeX      = Mathf.FloorToInt(((float)pos.x) / NodeSize);
        int nodeZ      = Mathf.FloorToInt(((float)pos.z) / NodeSize);
        int nodeWidth  = Mathf.CeilToInt(((float)b.Width) / NodeSize);
        int nodeHeight = Mathf.CeilToInt(((float)b.Height) / NodeSize);

        for (int x = nodeX; x < nodeX + nodeWidth; x++)
        {
            for (int z = nodeZ; z < nodeZ + nodeHeight; z++)
            {
                BuildingMap[x, z] = true;
            }
        }

        Recti bo = new Recti(pos.x - 1, pos.z - 1, b.Width + 2, b.Height + 2);

        foreach (Recti bound in BuildingPlots)
        {
            if (bo.Intersects(bound))
            {
                return(null);
            }
        }
        int height = (int)Mathf.FloorToInt(FlattenArea(pos.x - 1, pos.z - 1, b.Width + 2, b.Height + 2));

        BuildingPlots.Add(bo);

        //Debug.Log("Adding building " + b);
        //SetTiles(pos.x, pos.z, b.Width, b.Height, b.BuildingTiles);
        for (int x = 0; x < b.Width; x++)
        {
            for (int z = 0; z < b.Height; z++)
            {
                SetTile(x + pos.x, z + pos.z, b.BuildingTiles[x, z]);


                //SetHeight(x + pos.x, z + pos.z, maxHeight);
                for (int y = 0; y < vox.Height; y++)
                {
                    SetVoxelNode(x + pos.x, height + y, z + pos.z, vox.GetVoxelNode(x, y, z));
                }
            }
        }
        foreach (WorldObjectData obj in b.GetBuildingExternalObjects())
        {
            //We must set the object to have coordinates based on the settlement,
            //such that the object is added to the correct chunk.
            obj.SetPosition(obj.Position + pos.AsVector3());
            //We (should) already have checked for object validity when creating the building
            AddObject(obj, true);
        }


        Vec2i wPos = pos + BaseTile;
        Vec2i cPos = World.GetChunkPosition(wPos);

        //Debug.Log("Calculating tiles!!!");
        b.SetPositions(BaseTile, pos);

        //if (b.BuildingSubworld != null)
        //    AddObject(b.ExternalEntranceObject as WorldObjectData, true);
        //    World.Instance.AddSubworld(b.BuildingSubworld);

        b.CalculateSpawnableTiles(vox);
        Buildings.Add(b);
        //PathNodes.Add(b.Entrance);
        return(bo);
    }