示例#1
0
        public void AddLiquid(int amount, Vector2 pos)
        {
            if (amount <= 0)
                return;

            if (pos.X < 0)
                pos.X = 0;
            if (pos.Y < 0)
                pos.Y = 0;
            if (pos.X >= W)
                pos.X = W - 1;
            if (pos.Y >= H)
                pos.Y = H - 1;

            fixed (TileMapElement* tptr = tileMap)
                for (int i = 0; i < W * H; i++)
                    (*(tptr + i)).updated = false;

            List<long> open = new List<long>();
            int curind = 0;
            fixed (TileMapElement* ptrmap = tileMap)
            {
                open.Add((long)(ptrmap + (int)pos.X * H + (int)pos.Y));
                while (open.Count > curind && amount > 0)
                {
                    a = (TileMapElement*)((long)open[curind]);
                    curind++;
                    //(*a).updated = true;

                    if ((*a).Free && (*a).level < MaxLevel)
                    {
                        if ((*a).level + amount >= MaxLevel)
                        {
                            wasChanged = true;
                            amount -= (MaxLevel - (*a).level);
                            (*a).level = MaxLevel;
                        }
                        else
                        {
                            wasChanged = true;
                            (*a).level += amount;
                            amount = 0;
                        }
                    }

                    if ((*a).x > 0 && !(*(l = a - H)).updated)//left
                    {
                        open.Add((long)l);
                        (*l).updated = true;
                    }
                    if ((*a).x < W - 1 && !(*(l = a + H)).updated)//right
                    {
                        open.Add((long)l);
                        (*l).updated = true;
                    }
                    if ((*a).y > 0 && !(*(l = a - 1)).updated)//up
                    {
                        open.Add((long)l);
                        (*l).updated = true;
                    }
                    if ((*a).y < H - 1 && !(*(l = a + 1)).updated)//down
                    {
                        open.Add((long)l);
                        (*l).updated = true;
                    }
                }
            }
        }
示例#2
0
        //TODO optimize
        private unsafe void _updatePass()
        {
            if (!wasChanged)
            {
                return;
            }
            wasChanged = false;

            int x, y;

            updateSideSwapper++;
            if (updateSideSwapper >= 3)
            {
                updateSideSwapper = 0;
            }
            bool ussb  = updateSideSwapper > 0;
            int  inc   = ussb ? 1 : -1;
            int  start = ussb ? 0 : W - 1;

            fixed(TileMapElement *ptrmap = tileMap)
            {
                for (y = H - 1; y >= 0; y--)
                {
                    //swapps between starting from left and starting from right
                    for (x = start; (ussb && x < W) || (!ussb && x >= 0); x += inc)
                    {
                        a = ptrmap + y + x * H;
                        if ((*a).level != 0)
                        {
                            l = x > 0 ? ptrmap + y + (x - 1) * H : null;
                            r = x < W - 1 ? ptrmap + y + (x + 1) * H : null;
                            d = y < H - 1 ? ptrmap + (y + 1) + x * H : null;

                            l = (l != null && (*l).Free) ? l : null;
                            r = (r != null && (*r).Free) ? r : null;
                            d = (d != null && (*d).Free) ? d : null;

                            if (d != null && (*d).level != MaxLevel)//drop down
                            {
                                wasChanged = true;
                                if ((*d).level + (*a).level <= MaxLevel)
                                {
                                    (*d).level += (*a).level;
                                    (*a).level  = 0;
                                    continue;
                                }
                                else
                                {
                                    (*a).level -= MaxLevel - (*d).level;
                                    (*d).level  = MaxLevel;
                                }
                            }

                            //split left and right

                            if (r != null)
                            {
                                if (l == null)
                                {
                                    if ((*a).level < 2 && (*r).level < 2)
                                    {
                                        continue;
                                    }
                                    int lev = (*r).level + (*a).level;
                                    if ((*a).level != lev / 2)
                                    {
                                        wasChanged = true;
                                    }
                                    (*r).level = lev / 2;
                                    (*a).level = (*r).level;
                                    if (lev % 2 == 1)
                                    {
                                        (*r).level++;
                                    }
                                    continue;
                                }
                                else
                                {
                                    if ((*a).level < 2 && (*r).level < 2 && (*l).level < 2)
                                    {
                                        continue;
                                    }
                                    int lev = (*l).level + (*a).level + (*r).level;
                                    if ((*a).level != lev / 3)
                                    {
                                        wasChanged = true;
                                    }
                                    (*l).level = lev / 3;
                                    (*r).level = (*l).level;
                                    (*a).level = (*l).level;
                                    if (lev % 3 >= 1)
                                    {
                                        (*r).level++;
                                    }
                                    if (lev % 3 == 2)
                                    {
                                        (*l).level++;
                                    }
                                    continue;
                                }
                            }

                            if (l != null)
                            {
                                if ((*a).level < 2 && (*l).level < 2)
                                {
                                    continue;
                                }
                                int lev = (*l).level + (*a).level;
                                if ((*a).level != lev / 2)
                                {
                                    wasChanged = true;
                                }
                                (*l).level = lev / 2;
                                (*a).level = (*l).level;
                                if (lev % 2 == 1)
                                {
                                    (*l).level++;
                                }
                                continue;
                            }
                        }
                    }
                }
            }
        }
示例#3
0
        //TODO optimize
        private unsafe void _updatePass()
        {
            if (!wasChanged)
                return;
            wasChanged = false;

            int x, y;
            updateSideSwapper++;
            if (updateSideSwapper >= 3)
                updateSideSwapper = 0;
            bool ussb = updateSideSwapper > 0;
            int inc = ussb ? 1 : -1;
            int start = ussb ? 0 : W - 1;
            fixed (TileMapElement* ptrmap = tileMap)
            {
                for (y = H - 1; y >= 0; y--)
                {
                    //swapps between starting from left and starting from right
                    for (x = start; (ussb && x < W) || (!ussb && x >= 0); x += inc)
                    {
                        a = ptrmap + y + x * H;
                        if ((*a).level != 0)
                        {
                            l = x > 0 ? ptrmap + y + (x - 1) * H : null;
                            r = x < W - 1 ? ptrmap + y + (x + 1) * H : null;
                            d = y < H - 1 ? ptrmap + (y + 1) + x * H : null;

                            l = (l != null && (*l).Free) ? l : null;
                            r = (r != null && (*r).Free) ? r : null;
                            d = (d != null && (*d).Free) ? d : null;

                            if (d != null && (*d).level != MaxLevel)//drop down
                            {
                                wasChanged = true;
                                if ((*d).level + (*a).level <= MaxLevel)
                                {
                                    (*d).level += (*a).level;
                                    (*a).level = 0;
                                    continue;
                                }
                                else
                                {
                                    (*a).level -= MaxLevel - (*d).level;
                                    (*d).level = MaxLevel;
                                }
                            }

                            //split left and right

                            if (r != null)
                            {
                                if (l == null)
                                {
                                    if ((*a).level < 2 && (*r).level < 2)
                                        continue;
                                    int lev = (*r).level + (*a).level;
                                    if ((*a).level != lev / 2)
                                        wasChanged = true;
                                    (*r).level = lev / 2;
                                    (*a).level = (*r).level;
                                    if (lev % 2 == 1)
                                        (*r).level++;
                                    continue;
                                }
                                else
                                {
                                    if ((*a).level < 2 && (*r).level < 2 && (*l).level < 2)
                                        continue;
                                    int lev = (*l).level + (*a).level + (*r).level;
                                    if ((*a).level != lev / 3)
                                        wasChanged = true;
                                    (*l).level = lev / 3;
                                    (*r).level = (*l).level;
                                    (*a).level = (*l).level;
                                    if (lev % 3 >= 1)
                                        (*r).level++;
                                    if (lev % 3 == 2)
                                        (*l).level++;
                                    continue;
                                }
                            }

                            if (l != null)
                            {
                                if ((*a).level < 2 && (*l).level < 2)
                                    continue;
                                int lev = (*l).level + (*a).level;
                                if ((*a).level != lev / 2)
                                    wasChanged = true;
                                (*l).level = lev / 2;
                                (*a).level = (*l).level;
                                if (lev % 2 == 1)
                                    (*l).level++;
                                continue;
                            }
                        }
                    }
                }
            }
        }
示例#4
0
        public void SetAmount(int amount)
        {
            if (amount < 0)
                return;

            if (amount == 0)
            {
                fixed (TileMapElement* ptrmap = tileMap)
                {
                    for (int i = 0; i < W*H; i++)
                    {
                        (*(ptrmap + i)).level = 0;
                    }
                    return;
                }
            }

            wasChanged = true;

            fixed (TileMapElement* ptrmap = tileMap)
            {
                for (int y = H - 1; y >= 0 && amount > 0; y--)
                    for (int x = 0; x < W && amount > 0; x++)
                    {
                        if ((*(a = ptrmap + y + x * H)).Free)
                        {
                            if (amount > MaxLevel)
                            {
                                (*a).level = MaxLevel;
                                amount -= MaxLevel;
                            }
                            else
                            {
                                (*a).level = amount;
                                amount = 0;
                            }
                        }
                    }
            }
        }
示例#5
0
        public void RemoveFromTop(int amount)
        {
            if (amount <= 0)
                return;
            wasChanged = true;

            fixed (TileMapElement* ptrmap = tileMap)
            {
                for (int y = 0; y < H; y++)
                    for (int x = 0; x < W; x++)
                    {
                        if ((*(a = ptrmap + y + x * H)).Free && (*a).level > 0)
                        {
                            if ((*a).level > amount)
                            {
                                (*a).level -= amount;
                                return;
                            }
                            else
                            {
                                amount -= (*a).level;
                                (*a).level = 0;
                            }
                        }
                    }
            }
        }
示例#6
0
        public void RemoveFromBottom(int amount)
        {
            if (amount <= 0)
                return;
            wasChanged = true;

            int t = amount > W * 4 ? 4 : amount / 4 / W + 1;

            fixed (TileMapElement* ptrmap = tileMap)
            {
                while (true)//for if t < 4 and not enough after all passes
                {
                    for (int y = H - 1; y >= 0; y--)
                        for (int x = 0; x < W; x++)
                        {
                            if ((*(a = ptrmap + y + x * H)).Free && (*a).level > 0)
                            {
                                if (t >= amount && (*a).level >= amount)
                                {
                                    (*a).level -= amount;
                                    return;
                                }
                                else
                                {
                                    amount -= t;
                                    (*a).level -= t;
                                }
                            }
                        }
                }
            }
        }
示例#7
0
        public int GetHeightAt(int x)
        {
            if (x < 0)
                x = 0;
            if (x >= W)
                x = W - 1;

            fixed (TileMapElement* ptrmap = tileMap)
            {
                int h = 0;
                for (int y = H - 1; y >= 0; y--)
                {
                    if ((*(a = ptrmap + y + x * H)).Free && (*a).level == 4)
                        h++;
                    else
                        return h;
                }
                return h;
            }
        }