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); } }
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); } }
/// <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); }
/// <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)); }
/// <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); }