예제 #1
0
        public int GetMaxY(int x, int z)
        {
            Vector3i chunkPos = OCChunk.ToChunkPosition(x, 0, z);

            chunkPos.y = _chunks.GetMax().y;
            Vector3i localPos = OCChunk.ToLocalPosition(x, 0, z);

            for (; chunkPos.y >= 0; chunkPos.y--)
            {
                localPos.y = OCChunk.SIZE_Y - 1;
                for (; localPos.y >= 0; localPos.y--)
                {
                    OCChunk chunk = _chunks.SafeGet(chunkPos);
                    if (chunk == null)
                    {
                        break;
                    }
                    OCBlockData block = chunk.GetBlock(localPos);
                    if (block != null && !block.IsEmpty())
                    {
                        return(OCChunk.ToWorldPosition(chunkPos, localPos).y);
                    }
                }
            }

            return(0);
        }
예제 #2
0
        public OCBlockData GetBlock(int x, int y, int z)
        {
            OCChunk chunk = null;

            if (_lastRequestedChunk != null)
            {
                Vector3i requestedChunkPosition = OCChunk.ToChunkPosition(x, y, z);
                if (requestedChunkPosition.x == _lastRequestedChunk.GetPosition().x)
                {
                    if (requestedChunkPosition.y == _lastRequestedChunk.GetPosition().y)
                    {
                        if (requestedChunkPosition.z == _lastRequestedChunk.GetPosition().z)
                        {
                            chunk = _lastRequestedChunk;
                        }
                    }
                }
            }

            if (chunk == null)
            {
                chunk = GetChunk(OCChunk.ToChunkPosition(x, y, z));
                _lastRequestedChunk = chunk;
            }

            if (chunk == null)
            {
                return(OCBlockData.CreateInstance <OCBlockData>());
            }
            return(chunk.GetBlock(OCChunk.ToLocalPosition(x, y, z)));
        }
예제 #3
0
        public void SetBlock(OCBlockData block, int x, int y, int z)
        {
            OCChunk chunk = GetChunkInstance(OCChunk.ToChunkPosition(x, y, z));

            if (chunk != null)
            {
                chunk.SetBlock(block, OCChunk.ToLocalPosition(x, y, z));
            }
        }
예제 #4
0
        //---------------------------------------------------------------------------

        #endregion

        //---------------------------------------------------------------------------

        #region Public Member Functions

        //---------------------------------------------------------------------------



        public void SetBlockAndRecompute(OCBlockData block, Vector3i pos)
        {
            //MethodInfo info = this.GetType().GetMember("SetBlockAndRecompute")[0] as MethodInfo;

// TODO [BLOCKED]: uncomment when aspect stuff is in place?
//		object[] attributes = info.GetCustomAttributes(typeof(OCLogAspect), true);
//		OCLogAspect asp = null;
//
//		if(attributes != null)
//			asp = attributes[0] as OCLogAspect;
//
//		if(asp == null)
//			Debug.Log("No OCLog Aspect...");
//
//		asp.OnEntry(null);

            OCBlockData oldBlock = GetBlock(pos);

            SetBlock(block, pos);

            // Convert the global coordinate of the block to the chunk coordinates.
            Vector3i chunkPos = OCChunk.ToChunkPosition(pos);

            UpdateChunkLimits(chunkPos);

            // Convert the global coordinate of the block to the coordinate within the chunk.
            Vector3i localPos = OCChunk.ToLocalPosition(pos);

            SetDirty(chunkPos);

            // If on the lower boundary of a chunk...set the neighbouring chunk to dirty too.
            if (localPos.x == 0)
            {
                SetDirty(chunkPos - Vector3i.right);
            }
            if (localPos.y == 0)
            {
                SetDirty(chunkPos - Vector3i.up);
            }
            if (localPos.z == 0)
            {
                SetDirty(chunkPos - Vector3i.forward);
            }

            // If on the upper boundary of a chunk...set the neighbouring chunk to dirty too.
            if (localPos.x == OCChunk.SIZE_X - 1)
            {
                SetDirty(chunkPos + Vector3i.right);
            }
            if (localPos.y == OCChunk.SIZE_Y - 1)
            {
                SetDirty(chunkPos + Vector3i.up);
            }
            if (localPos.z == OCChunk.SIZE_Z - 1)
            {
                SetDirty(chunkPos + Vector3i.forward);
            }

            OpenCog.Map.Lighting.OCSunLightComputer.RecomputeLightAtPosition(this, pos);
            OpenCog.Map.Lighting.OCLightComputer.RecomputeLightAtPosition(this, pos);

            UpdateMeshColliderAfterBlockChange();
            // TODO [BLOCKED]: uncomment when aspect stuff is in place?
            //		asp.OnExit(null);

            OpenCog.Embodiment.OCPerceptionCollector perceptionCollector = OpenCog.Embodiment.OCPerceptionCollector.Instance;

            List <GameObject> batteries = GameObject.FindGameObjectsWithTag("OCBattery").ToList();
            GameObject        battery   = batteries.Where(b => VectorUtil.AreVectorsEqual(b.transform.position, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))).FirstOrDefault();

            List <GameObject> hearths = GameObject.FindGameObjectsWithTag("OCHearth").ToList();
            GameObject        hearth  = hearths.Where(h => VectorUtil.AreVectorsEqual(h.transform.position, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))).FirstOrDefault();

            if (block.IsEmpty() && !oldBlock.IsEmpty())
            {
                UnityEngine.Debug.Log(OCLogSymbol.RUNNING + "OCMap.SetBlockAndRecompute(): Null block type sent; destroying block.");

                if (perceptionCollector != null && oldBlock.block.GetName() != "Battery")
                {
                    perceptionCollector.NotifyBlockRemoved(pos);
                }

                // I'm going to take a gamble here...since NotifyBatteryRemoved only does its work when it finds a battery at this location...it should be ok...

                if (perceptionCollector != null && oldBlock.block.GetName() == "Battery")
                {
                    perceptionCollector.NotifyBatteryRemoved(pos);
                }

                if (battery != default(GameObject) && battery != null)
                {
                    GameObject.DestroyImmediate(battery);
                }
                if (hearth != default(GameObject) && hearth != null)
                {
                    GameObject.DestroyImmediate(hearth);
                }
            }
            else
            {
                UnityEngine.Debug.Log(OCLogSymbol.RUNNING + "OCMap.SetBlockAndRecompute(): Block type sent; creating block.");

                // Moved notify down...to AFTER the point where it is actually created...
            }

            if (block.block != null && block.block.GetName() == "Battery" && (battery == default(GameObject) || battery == null))
            {
                GameObject batteryPrefab = OCMap.Instance.BatteryPrefab;
                if (batteryPrefab == null)
                {
                    UnityEngine.Debug.LogWarning(OCLogSymbol.WARN + "OCBuilder.Update(), batteryPrefab == null");
                }
                else
                {
                    GameObject newBattery = (GameObject)GameObject.Instantiate(batteryPrefab);
                    newBattery.transform.position = pos;
                    newBattery.name             = "Battery";
                    newBattery.transform.parent = OCMap.Instance.BatteriesSceneObject.transform;

                    if (perceptionCollector != null)
                    {
                        perceptionCollector.NotifyBatteryAdded(pos);
                    }
                }
            }

            if (block.block != null && block.block.GetName() == "Hearth" && (hearth == default(GameObject) || hearth == null))
            {
                GameObject hearthPrefab = OCMap.Instance.HearthPrefab;
                if (hearthPrefab == null)
                {
                    UnityEngine.Debug.LogWarning(OCLogSymbol.WARN + "OCBuilder::Update, hearthPrefab == null");
                }
                else
                {
                    GameObject newHearth = (GameObject)GameObject.Instantiate(hearthPrefab);
                    newHearth.transform.position = pos;
                    newHearth.name             = "Hearth";
                    newHearth.transform.parent = OCMap.Instance.HearthsSceneObject.transform;

                    if (perceptionCollector != null)
                    {
                        perceptionCollector.NotifyBlockAdded(pos);
                    }
                }
            }
        }