예제 #1
0
        protected override ActionResult OnProcess()
        {
            Vec      newPos   = Entity.Position + mDirection;
            TileType tileType = Dungeon.Tiles[newPos].Type;

            // if walking into a closed door, open it
            if (tileType == TileType.DoorClosed)
            {
                return(new OpenDoorAction(Entity, newPos));
            }

            // if there is something in the tile we are moving to, attack it
            Entity occupier = Dungeon.Entities.GetAt(newPos);

            if ((occupier != null) && (occupier != Entity))
            {
                return(new AttackAction(Entity, occupier));
            }

            // fail if the tile is not occupiable
            if (!Entity.CanMove(mDirection))
            {
                // not occupyable tile
                if (Entity is Hero)
                {
                    // you know it's a wall now
                    Dungeon.SetTileExplored(newPos);
                }

                return(Fail("{subject} can't walk there."));
            }

            // move the entity
            Entity.Position = newPos;

            // enter a store
            switch (tileType)
            {
            case TileType.DoorStore1:
            case TileType.DoorStore2:
            case TileType.DoorStore3:
            case TileType.DoorStore4:
            case TileType.DoorStore5:
            case TileType.DoorStore6:
                Hero hero = Entity as Hero;
                if (hero != null)
                {
                    AddAction(new EnterStoreAction(hero, tileType));
                }
                break;
            }

            if (mCheckForCancel)
            {
                return(ActionResult.CheckForCancel);
            }
            else
            {
                return(ActionResult.Done);
            }
        }
예제 #2
0
 public ItemCollection(Dungeon dungeon)
 {
     mDungeon = dungeon;
 }
예제 #3
0
        public override Action NextAction()
        {
            Dungeon dungeon = Hero.Dungeon;

            // get the current step
            Action action = new WalkAction(Hero, mDirection, true);

            // process the next step
            Vec pos = Hero.Position + mDirection.Offset;

            // try to turn to follow corridors
            if (!dungeon.Tiles[pos + mDirection.RotateLeft90].IsPassable &&  // wall on the left
                !dungeon.Tiles[pos + mDirection.RotateRight90].IsPassable && // wall on the right
                !(dungeon.Tiles[pos + mDirection].IsPassable &&              // blocked directly ahead
                  dungeon.Tiles[pos + mDirection + mDirection].IsPassable))  // or one step past that
            {
                // we're in a corridor that's about to either turn or dead end

                // first step before the turn
                // ###.#
                // ###.# dir = e
                // .@pn# p = pos
                // ##### n = pos + dir

                // second step halfway through the turn
                // ###.n
                // ###p# dir = ne
                // ..@.# p = pos
                // ##### n = pos + dir

                bool leftTurnOpen  = dungeon.Tiles[pos + mDirection.Previous].IsPassable;
                bool rightTurnOpen = dungeon.Tiles[pos + mDirection.Next].IsPassable;

                if (leftTurnOpen && rightTurnOpen)
                {
                    // tees off, so don't decide
                }
                else if (leftTurnOpen)
                {
                    mDirection = mDirection.Previous;
                }
                else if (rightTurnOpen)
                {
                    mDirection = mDirection.Next;
                }
            }

            Vec nextPos = pos + mDirection.Offset;

            bool disturb = false;

            // stop if we're going to hit a wall
            if (!Hero.CanOccupy(nextPos))
            {
                disturb = true;
            }

            // some things disturb when directly next to the hero,
            // others when they are one step away
            // .....
            // ..12.
            // o@12.
            // ..12.
            // .....
            // o: where hero is
            // @: where hero will be after step
            // 1: disturb if item, stairs, etc.
            // 2: disturb if monster

            // stop next to some things
            foreach (Vec testPos in GetLeadingTiles(pos, mDirection))
            {
                // items
                if (dungeon.Items.GetAt(testPos) != null)
                {
                    // found an item
                    disturb = true;
                    break;
                }

                // interesting floor features
                TileType tileType = dungeon.Tiles[testPos].Type;
                if ((tileType != TileType.Floor) &&
                    (tileType != TileType.Wall) &&
                    (tileType != TileType.LowWall) &&
                    (tileType != TileType.RoofDark) &&
                    (tileType != TileType.RoofLight))
                {
                    // found something other than wall or floor
                    disturb = true;
                    break;
                }
            }

            // stop one tile away from monsters
            foreach (Vec testPos in GetLeadingTiles(nextPos, mDirection))
            {
                //### bob: need to take into account visibility
                if (dungeon.Entities.GetAt(testPos) != null)
                {
                    // found a monster
                    disturb = true;
                    break;
                }
            }

            // stop if the wall on either side changed
            bool isLeftOpen  = dungeon.Tiles[pos + mDirection.RotateLeft90].IsPassable;
            bool isRightOpen = dungeon.Tiles[pos + mDirection.RotateRight90].IsPassable;

            if ((isLeftOpen != mIsLeftOpen) || (isRightOpen != mIsRightOpen))
            {
                disturb = true;
            }

            // stop running if we found something interesting
            if (disturb)
            {
                mDirection = Direction.None;
            }

            return(action);
        }
예제 #4
0
 public EntityCollection(Dungeon dungeon)
 {
     mDungeon  = dungeon;
     mEntities = new List <Entity>();
 }
예제 #5
0
        protected override bool OnEffect(Vec pos, Direction direction)
        {
            AddEffect(new Effect(pos, direction, mAttack.EffectType, mAttack.Element));

            return(Dungeon.HitAt(pos, this, new Hit(mNoun, mAttack, direction)));
        }
예제 #6
0
        protected override void OnSetPosition(Vec pos)
        {
            base.OnSetPosition(pos);

            Dungeon.DirtyVisibility();
        }