Exemplo n.º 1
0
 public WorldBlock GetBlock(HexXY blockp)
 {
     return(wbCache.GetNoCache(blockp));
 }
Exemplo n.º 2
0
 public void RemoveTriggerZoneFrom(HexXY p, uint zone)
 {
     triggerZones[p].Remove(zone);
 }
Exemplo n.º 3
0
        public HashSet <WorldBlock> RecalcPassabilityOnEdges()
        {
            var changedBlocks = new HashSet <WorldBlock>();

            foreach (var wb in GetAllBlocks())
            {
                for (int x = 0; x < WorldBlock.sz; x++)
                {
                    for (int y = 0; y < WorldBlock.sz; y++)
                    {
                        var p      = new HexXY(x, y) + wb.Offset;
                        var type   = GetCellType(p);
                        var blType = GetPFBlockedMap(p);
                        if (type != TerrainCellType.Empty)
                        {
                            bool isNearEmpty = false;
                            for (int n = 0; n < 6; n++)
                            {
                                if (GetCellType(p + HexXY.neighbours[n]) == TerrainCellType.Empty)
                                {
                                    isNearEmpty = true;
                                    break;
                                }
                            }

                            if (isNearEmpty)
                            {
                                if (GetPFBlockedMap(p) != WorldBlock.PFBlockType.EdgeBlocked)
                                {
                                    if (!changedBlocks.Contains(wb))
                                    {
                                        changedBlocks.Add(wb);
                                    }
                                    SetPFBlockedMap(p, WorldBlock.PFBlockType.EdgeBlocked);
                                }
                            }
                            else if (!isNearEmpty && blType == WorldBlock.PFBlockType.EdgeBlocked)
                            {
                                if (!changedBlocks.Contains(wb))
                                {
                                    changedBlocks.Add(wb);
                                }
                                SetPFBlockedMap(p, WorldBlock.PFBlockType.Unblocked);
                            }
                        }
                        else
                        {
                            if (GetPFBlockedMap(p) != WorldBlock.PFBlockType.EdgeBlocked)
                            {
                                if (!changedBlocks.Contains(wb))
                                {
                                    changedBlocks.Add(wb);
                                }
                                SetPFBlockedMap(p, WorldBlock.PFBlockType.EdgeBlocked);
                            }
                        }
                    }
                }
            }

            return(changedBlocks);
        }
Exemplo n.º 4
0
 public void Add(HexXY p, WorldBlock block)
 {
     all.Add(p, block);
 }
Exemplo n.º 5
0
        bool InterpretPredicate(Spell.CompiledRune predRune)
        {
            //Compute connected component and find avatar ref position
            Spell.CompiledRune avatarRefRune = null;

            blobFront.Enqueue(predRune);
            blobAll.Add(predRune);

            do
            {
                var c = blobFront.Dequeue();
                additionalInterpretedRunes.Add(c);
                if (c.type == RuneType.PredicateAvatarRef)
                {
                    if (avatarRefRune != null)
                    {
                        //Double avatar ref error
                        finishState = FinishedState.PredicateParseError;
                        return(false);
                    }
                    else
                    {
                        avatarRefRune = c;
                    }
                }

                foreach (var n in c.neighs)
                {
                    if (n == null || !IsPredicateRune(n.type) || blobAll.Contains(n))
                    {
                        continue;
                    }
                    blobFront.Enqueue(n);
                    blobAll.Add(n);
                }
            } while (blobFront.Count > 0);

            HexXY predRefPos;

            if (avatarRefRune != null)
            {
                predRefPos = avatarRefRune.relPos;
            }
            else
            {
                if (blobAll.Count > 1)
                {
                    //No avatar reference in predicate with more than one rune
                    finishState = FinishedState.PredicateParseError;
                    return(false);
                }
                else
                {
                    predRefPos = blobAll.First().relPos;
                }
            }

            //Check predicate
            bool isMatch = true;

            foreach (var prune in blobAll)
            {
                HexXY checkPos = prune.relPos - predRefPos;
                for (int i = 0; i < dir; i++)
                {
                    checkPos = checkPos.RotateRight(new HexXY(0, 0));
                }
                checkPos += this.pos;

                switch (prune.type)
                {
                case RuneType.PredicateTileEmpty:
                {
                    var blType = Level.S.GetPFBlockedMap(checkPos);
                    if (blType != WorldBlock.PFBlockType.Unblocked &&
                        blType != WorldBlock.PFBlockType.DynamicBlocked)
                    {
                        isMatch = false;
                    }
                    break;
                }

                case RuneType.PredicateTileWall:
                    if (Level.S.GetPFBlockedMap(checkPos) != WorldBlock.PFBlockType.EdgeBlocked &&
                        Level.S.GetPFBlockedMap(checkPos) != WorldBlock.PFBlockType.StaticBlocked &&
                        Level.S.GetPFBlockedMap(checkPos) != WorldBlock.PFBlockType.DoorBlocked)
                    {
                        isMatch = false;
                    }
                    break;

                case RuneType.PredicateTileMonster:
                    if (!Level.S.GetEntities(checkPos).Any(e => e is Mob))
                    {
                        isMatch = false;
                    }
                    break;
                }
                if (!isMatch)
                {
                    break;
                }
            }

            blobAll.Clear();

            if (SpellExecuting.isLogging)
            {
                Logger.Log("predicate at " + predRune.relPos + " is " + isMatch);
            }

            return(isMatch);
        }
Exemplo n.º 6
0
 public static HexXY GetBlockCoords(Vector2 coord)
 {
     return(GetBlockCoords(HexXY.FromPlaneCoordinates(coord)));
 }
Exemplo n.º 7
0
        //Trace first straight line dest and move there
        void MovePart()
        {
            //Debug.Log("MOVEPART " + p);
            uint?pathLen = Pathfinder.FindPath(pos, dest.Value, pathStorage, distToStop, 10);

            if (pathLen.HasValue && pathLen.Value > 0)
            {
                HexXY firstPathCell = pathStorage[0];
                if (!blockedCells.Contains(firstPathCell) && Level.S.GetPFBlockedMap(firstPathCell) != WorldBlock.PFBlockType.Unblocked)
                {
                    //Even first cell is blocked, just rotate there
                    dest      = null;
                    isWalking = false;
                    Interfacing.PerformInterfaceStop(graphicsHandle, pos);
                    Interfacing.PerformInterfaceUpdateRotation(graphicsHandle, (uint)HexXY.neighbours.IndexOf(pathStorage[0] - pos));
                }
                else
                {
                    //Try to trace a line to these
                    //First line that will be blocked will determine max straight-line destination
                    //Path to first cell should not be blocked so start with second
                    if (pathLen.Value == 1)
                    {
                        interDest     = pathStorage[0];
                        interFracDest = interDest.ToPlaneCoordinates();
                    }
                    else
                    {
                        for (int i = 1; i < pathLen.Value; i++)
                        {
                            HexXY inter = pathStorage[i];

                            //Check if straight line backwards is blocked
                            Vector2 linePos       = inter.ToPlaneCoordinates();
                            Vector2 lineDir       = (fracPos - linePos).normalized;
                            bool    isLineBlocked = false;
                            HexXY   traced        = inter;

                            do
                            {
                                float minDist    = float.MaxValue;
                                float lineShift  = 0;
                                HexXY nextTraced = new HexXY(0, 0);
                                for (int n = 0; n < 6; n++)
                                {
                                    HexXY   np      = traced + HexXY.neighbours[n];
                                    Vector2 v       = np.ToPlaneCoordinates() - linePos;
                                    float   lineLen = Vector2.Dot(v, lineDir);
                                    if (lineLen < 0)
                                    {
                                        continue;
                                    }
                                    float dist = (lineDir * lineLen - v).magnitude;
                                    if (dist < 0.8f) //Line intersects cell np (circle approximated, not hexagon though, and larger (should be less than cos(60)) so it will not cut walls)
                                    {
                                        if (!blockedCells.Contains(np) && Level.S.GetPFBlockedMap(np) != WorldBlock.PFBlockType.Unblocked)
                                        {
                                            isLineBlocked = true;
                                            break;
                                        }

                                        if (dist < minDist)
                                        {
                                            minDist    = dist;
                                            nextTraced = np;
                                            lineShift  = lineLen;
                                        }
                                    }
                                }

                                traced   = nextTraced;
                                linePos += lineShift * lineDir;
                            } while (!isLineBlocked && traced != pos);

                            if (isLineBlocked) //Choose the previous cell
                            {
                                interDest     = pathStorage[i - 1];
                                interFracDest = interDest.ToPlaneCoordinates();
                                break;
                            }

                            //Got to the last cell - use it
                            if (i == pathLen.Value - 1)
                            {
                                interDest     = inter;
                                interFracDest = interDest.ToPlaneCoordinates();
                            }
                        }
                    }

                    float timeToGetThere = (fracPos - interFracDest).magnitude / speed;
                    Interfacing.PerformInterfaceMovePrecise(graphicsHandle, interFracDest, timeToGetThere);
                    isWalking = true;
                }
            }
            else
            {
                dest      = null;
                isWalking = false;
                Interfacing.PerformInterfaceStop(graphicsHandle, pos);
            }
        }
Exemplo n.º 8
0
 public static bool IsInRange(HexXY pos)
 {
     return(pos.x >= 0 && pos.x < sz && pos.y >= 0 && pos.y < sz);
 }
Exemplo n.º 9
0
        void Walking(float dt)
        {
            HexXY prevPos = pos;

            float distToTargetSqr = (interFracDest - fracPos).sqrMagnitude;

            Vector2 dir = (interFracDest - fracPos).normalized;

            //Calculate blocking
            //Debug.Log(distToTargetSqr + " " + (blockForwardDist * blockForwardDist));
            if (distToTargetSqr >= blockForwardDist * blockForwardDist)
            {
                Vector2 nextBlockPos = fracPos + dir * blockForwardDist;
                HexXY   nextPosCell  = HexXY.FromPlaneCoordinates(nextBlockPos);
                if (!blockedCells.Contains(nextPosCell))
                {
                    if (Level.S.GetPFBlockedMap(nextPosCell) != WorldBlock.PFBlockType.Unblocked)
                    {
                        //Blocked by something - stop and move to nearest cell center
                        dest = interDest = pos;
                        //Debug.Log("Blocked dest " + pos);
                        interFracDest = pos.ToPlaneCoordinates();
                        float timeToGetThere = (fracPos - interFracDest).magnitude / (speed * 0.5f); //at half speed
                        Interfacing.PerformInterfaceMovePrecise(graphicsHandle, interFracDest, timeToGetThere);
                        return;
                    }
                    else
                    {
                        Level.S.SetPFBlockedMap(nextPosCell, WorldBlock.PFBlockType.DynamicBlocked);
                        //G.S.DebugShowCell(nextPosCell);
                        blockedCells.Add(nextPosCell);
                    }
                }
            }

            //Calculate movement
            Vector2 step = dir * speed * dt;

            if (step.sqrMagnitude == 0 || step.sqrMagnitude > distToTargetSqr)
            {
                fracPos = interFracDest;
                if (HexXY.Dist(interDest, dest.Value) <= distToStop)
                {
                    dest      = null;
                    isWalking = false;
                    Interfacing.PerformInterfaceStop(graphicsHandle, pos);
                }
                else
                {
                    MovePart();
                }
            }
            else
            {
                fracPos += step;
            }

            pos = HexXY.FromPlaneCoordinates(fracPos);

            if (pos != prevPos)
            {
                Level.S.RemoveEntity(prevPos, this);
                Level.S.AddEntity(pos, this);

                //Remove blocked cells that are behind us
                blockedCellsToDelete.Clear();

                foreach (var bc in blockedCells)
                {
                    Vector2 bcFrac = bc.ToPlaneCoordinates();
                    if (bc != pos && Vector2.Dot(fracPos - bcFrac, dir) > blockBackDist)
                    {
                        blockedCellsToDelete.Add(bc);
                    }
                }

                foreach (var dbc in blockedCellsToDelete)
                {
                    blockedCells.Remove(dbc);
                    Level.S.SetPFBlockedMap(dbc, WorldBlock.PFBlockType.Unblocked);
                    //G.S.DebugHideCell(dbc);
                }
            }

            this.dir = HexXY.GetApproximateDir(dir);
        }
Exemplo n.º 10
0
 public Player() : base(EntityClass.Character, (uint)CharacterType.Player)
 {
     pathStorage   = new HexXY[64];
     speed         = 3;
     abilitySpells = new Spell[3];
 }
Exemplo n.º 11
0
 public void OnMove(HexXY from, HexXY to, bool isDrawing)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 12
0
 public abstract void StackOn(HexXY pos);
Exemplo n.º 13
0
 public static int PFGetPassCost(HexXY pos)
 {
     return(1);
 }
Exemplo n.º 14
0
        public bool OnUpdate(float dt)
        {
            if (onTileCenter && shouldRecalcPath)
            {
                var pathLen = Pathfinder.FindPath(entity.pos, dest.Value, pathStorage, distToStop, blockedCost);
                //Logger.Log(pathLen.ToString());
                pathStart        = 0;
                shouldRecalcPath = false;
                isWalkBlocked    = false;

                if (!pathLen.HasValue || pathLen.Value == 0)
                {
                    pathEnd = 0;
                    if (isWalking)
                    {
                        Interfacing.PerformInterfaceStop(entity.graphicsHandle, entity.pos);
                        isWalking = false;
                    }
                    return(true);
                }


                pathEnd = pathLen.Value;
            }

            if (pathStart == pathEnd)
            {
                return(true);
            }
            var nextTile = pathStorage[pathStart];

            if (distToNextTile > 0.5)
            {
                entity.pos = prevTile;
            }
            else
            {
                entity.pos = nextTile;
            }

            if (onTileCenter)
            {
                if (Level.S.GetPFBlockedMap(nextTile) == WorldBlock.PFBlockType.DynamicBlocked)
                {
                    if (!isWalkBlocked)
                    {
                        isWalkBlocked   = true;
                        walkBlockedTime = 0;
                        isWalking       = false;
                        Interfacing.PerformInterfaceStop(entity.graphicsHandle, entity.pos);
                    }
                    walkBlockedTime += dt;
                    return(true);
                }
                isWalkBlocked = false;
                Level.S.SetPFBlockedMap(nextTile, WorldBlock.PFBlockType.DynamicBlocked);
                Level.S.SetPFBlockedMap(prevTile, WorldBlock.PFBlockType.Unblocked);
                pfBlockedTile = nextTile;

                Interfacing.PerformInterfaceMove(entity.graphicsHandle, nextTile, distToNextTile * invSpeed);
                isWalking = true;
            }

            float timeLeft = distToNextTile * invSpeed;

            if (timeLeft > dt)
            {
                distToNextTile -= dt * speed;
                onTileCenter    = false;
            }
            else
            {
                prevTile       = nextTile;
                distToNextTile = 1;
                onTileCenter   = true;
                ++pathStart;

                if (pathEnd - pathStart > 0)
                {
                    OnUpdate(dt - timeLeft);
                }
                else
                {
                    Interfacing.PerformInterfaceStop(entity.graphicsHandle, prevTile);
                    isWalking = false;
                }
            }

            return(true);
        }
Exemplo n.º 15
0
 public void OnSpawn(HexXY pos)
 {
 }
Exemplo n.º 16
0
 public override void LoadDerived(BinaryReader reader)
 {
     dir            = reader.ReadByte();
     sourceSpellPos = new HexXY(reader.ReadInt32(), reader.ReadInt32());
 }
Exemplo n.º 17
0
 public TerrainCellType GetCellType(HexXY pos)
 {
     return(cellTypes[pos.x, pos.y]);
 }