예제 #1
0
        public override void act(Collider mover, bool shouting)
        {
            // if (the door is open)
            if (shouting && GameplayManager.Game.Keys.ContainsKey(GameState.GameFlag.REGISTRAR_DOOR_IS_OPEN) && GameplayManager.Game.Keys[GameState.GameFlag.REGISTRAR_DOOR_IS_OPEN])
            {
                // Do nothing. Just let the user pass.
            }
            else if (GameplayManager.Game.Keys.ContainsKey(GameState.GameFlag.REGISTRAR_DOOR_IS_OPEN) && GameplayManager.Game.Keys[GameState.GameFlag.REGISTRAR_DOOR_IS_OPEN])
            {
                GameplayManager.say(getDialogue(shouting));
            }
            // else if (have the graduation form)
            else if (GameplayManager.Game.Keys.ContainsKey(GameState.GameFlag.PLAYER_ACCESSED_PUZZLE) && GameplayManager.Game.Keys[GameState.GameFlag.PLAYER_ACCESSED_PUZZLE])
            {
                // Announce that the door has been opened.
                GameplayManager.say(getDialogue(shouting));
                // Open the door.
                GameplayManager.Game.Keys[GameState.GameFlag.REGISTRAR_DOOR_IS_OPEN] = true;

            }
            // else
            else
            {
                // Announce that you can't do that, homeboy.
                GameplayManager.say(getDialogue(shouting));

                // Send player back.
                if (shouting)
                {
                    ((PlayerController)mover.m_owner).AnimationController.requestAnimation("left", AnimationController.AnimationCommand.Play);
                    mover.handleMovement(new Vector2(-20, 0));
                }
            }
        }
예제 #2
0
파일: Collider.cs 프로젝트: BNHeadrick/Bros
 public Collider(ICollidable owner, Rectangle bounds, ColliderType type)
 {
     this.m_owner = owner;
     this.m_bounds = new DoubleRect(bounds.X, bounds.Y, bounds.Width, bounds.Height);
     this.m_bounds2 = new DoubleRect(bounds.X - 5, bounds.Y - 5, bounds.Width + 10, bounds.Height + 10);
     this.m_type = type;
     this.m_other = null;
 }
예제 #3
0
 public override void handleImpact(Collider mover)
 {
     foreach (Character c in GameplayManager.Game.Characters)
     {
         if (c.ID == characterID)
         {
             c.act(mover, shouting);
         }
     }
 }
        /// <summary>
        /// Scales back an attempted movement so that two colliders don't intersect.
        /// </summary>
        /// <param name="mover">Collider that is moving</param>
        /// <param name="other">Collider that the movement shouldn't be able to move into</param>
        /// <param name="deltaPosition">Amount that mover is trying to move</param>
        /// <returns>How much mover can move so as not to intersect other</returns>
        protected static Vector2 scaleBackVelocity(Collider mover, Collider other, Vector2 deltaPosition)
        {
            // whew! a lot work just to make it so that you can slide along objects when
            //  using multiple directions

            const float EPS = 0.01f;

            DoubleRect dr2 = other.Bounds;

            double reducedX = deltaPosition.X;
            double reducedY = deltaPosition.Y;

            // Project x only movement and fix x velocity
            Vector2 temp = new Vector2(deltaPosition.X, 0);
            DoubleRect dr1 = mover.Bounds + temp;
            if (dr1.IntersectsWith(dr2))
            if (deltaPosition.X > 0 && dr1.X + dr1.Width >= dr2.X) // moving right, rhs collision
            {
                double overlap = dr1.X + dr1.Width - dr2.X + EPS;
                reducedX = Math.Max(0.0f, deltaPosition.X - overlap);
            }
            else if (deltaPosition.X < 0 && dr1.X <= dr2.X + dr2.Width) // moving left, lhs collision
            {
                double overlap = (dr2.X + dr2.Width) - dr1.X + EPS;
                reducedX = Math.Min(0.0f, deltaPosition.X + overlap);
            }

            // Project y only movement and fix y velocity
            temp = new Vector2(0, deltaPosition.Y);
            dr1 = mover.Bounds + temp;
            if (dr1.IntersectsWith(dr2))
            if (deltaPosition.Y > 0 && dr1.Y + dr1.Height >= dr2.Y) // moving down, bottom collision
            {
                double overlap = dr1.Y + dr1.Height - dr2.Y + EPS;
                reducedY = Math.Max(0.0f, deltaPosition.Y - overlap);
            }
            else if (deltaPosition.Y < 0 && dr1.Y <= dr2.Y + dr2.Height) // moving up, top collision
            {
                double overlap = (dr2.Y + dr2.Height) - dr1.Y + EPS;
                reducedY = Math.Min(0.0f, deltaPosition.Y + overlap);
            }

            // if neither X nor Y reduced, must be a corner collision
            // for now, we just won't allow this (if we allow, you can get stuck, but not bad)
            if (reducedX == deltaPosition.X && reducedY == deltaPosition.Y)
            {
                return Vector2.Zero;
            }

            return new Vector2((float)reducedX, (float)reducedY);
        }
예제 #5
0
        private Color m_tint; // a tint to put on the decoration

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Create a new decoration
        /// </summary>
        /// <param name="decorationSetTexture">Texture containing this decoration's graphic</param>
        /// <param name="indexNumber">An index into the texture, which finds this decoration's location in it</param>
        /// <param name="drawPos">Where in the area the decoration should be drawn</param>
        /// <param name="di">XML information about properties of the Decoration (load from Content)</param>
        /// <param name="tint">Color tint to apply to the graphic</param>
        public Decoration(GameTexture decorationSetTexture, int indexNumber, Vector2 drawPos, DecorationInfo di, Color tint)
        {
            this.m_texture = decorationSetTexture;
            this.m_drawIndex = indexNumber;
            this.m_drawPosition = drawPos;

            Rectangle bounds = new Rectangle(
                di.collision.X - di.graphic.X + (int)drawPos.X,
                di.collision.Y - di.graphic.Y + (int)drawPos.Y,
                di.collision.Width,
                di.collision.Height);
            this.m_collider = new Collider(this, bounds, ColliderType.Scenery, -1); // -1 is a flag for non-NPC colliders.

            this.m_tint = tint;
        }
예제 #6
0
        public override void act(Collider mover, bool shouting)
        {
            setFlags();

            if (!f_registrarDoorIsOpen && !f_deanFatigue)
            {
                GameplayManager.Game.Keys[GameState.GameFlag.DEAN_WAITING] = true;
                GameplayManager.Game.Keys[GameState.GameFlag.PLAYER_PARALYZED] = true;
            }
            else if (f_deanFatigue)
            {
                GameplayManager.Game.updateState();
            }

            GameplayManager.say(getDialogue(shouting));
        }
예제 #7
0
 /// <summary>
 /// Determines how to handle various types of collisions.
 /// </summary>
 /// <param name="mover">Collider that is moving</param>
 /// <param name="other">Collider which was moved into</param>
 /// <param name="deltaPosition">Attempted movement by the mover</param>
 /// <param name="allowedMovement">Out param - amount of movement which is allowed</param>
 /// <returns>True if any movement is allowed, false otherwise</returns>
 public static bool handleMovement(Collider mover, Collider other, Vector2 deltaPosition, out Vector2 allowedMovement)
 {
     switch (mover.m_type)
     {
         case ColliderType.PC:
             return handlePCMovement(mover, other, deltaPosition, out allowedMovement);
             //break;
         //case ColliderType.NPC:
         //    break;
         //case ColliderType.Effect:
         //    break;
         //case ColliderType.Movable:
         //    break;
         default:
             throw new Exception("Something's moving that shouldn't be");
     }
     //return false;
 }
예제 #8
0
        /// <summary>
        /// Moves a collider in the direction provided until it hits something
        /// </summary>
        /// <param name="mover">Collider which is moving</param>
        /// <param name="deltaPosition">Change in position the collider is trying to make</param>
        public void handleMovement(Collider mover, Vector2 deltaPosition)
        {
            double areaOfMovementX1 = Math.Min(mover.Bounds.X, mover.Bounds.X + deltaPosition.X);
            double areaOfMovementY1 = Math.Min(mover.Bounds.Y, mover.Bounds.Y + deltaPosition.Y);
            double areaOfMovementX2 = Math.Max(mover.Bounds.X + mover.Bounds.Width, mover.Bounds.X + mover.Bounds.Width + deltaPosition.X);
            double areaOfMovementY2 = Math.Max(mover.Bounds.Y + mover.Bounds.Height, mover.Bounds.Y + mover.Bounds.Height + deltaPosition.Y);

            DoubleRect areaOfMovement = new DoubleRect(
                areaOfMovementX1,
                areaOfMovementY1,
                areaOfMovementX2 - areaOfMovementX1,
                areaOfMovementY2 - areaOfMovementY1);

            //DoubleRect newbounds = mover.Bounds + deltaPosition;

            List<Collider> collisions = m_tree.Query(areaOfMovement);
            List<Collider>.Enumerator i = collisions.GetEnumerator();
            Vector2 allowedMovement = deltaPosition;
            Vector2 temp;
            while (i.MoveNext())
            {
                // we will usually collide with our old position - ignore that case
                if (i.Current != mover)
                {
                    bool canMove = CollisionHandler.handleMovement(mover, i.Current, deltaPosition, out temp);
                    if (!canMove)
                    {
                        return; // don't allow movement
                    }
                    if (allowedMovement.X > 0.0f)
                        allowedMovement.X = Math.Min(allowedMovement.X, temp.X);
                    else if (allowedMovement.X < 0.0f)
                        allowedMovement.X = Math.Max(allowedMovement.X, temp.X);
                    if (allowedMovement.Y > 0.0f)
                        allowedMovement.Y = Math.Min(allowedMovement.Y, temp.Y);
                    else if (allowedMovement.Y < 0.0f)
                        allowedMovement.Y = Math.Max(allowedMovement.Y, temp.Y);
                }
            }

            mover.move(allowedMovement);
        }
예제 #9
0
 /// <summary>
 /// Determines how to handle collisions involving the PC
 /// </summary>
 /// <returns>True if the PC can move, false otherwise</returns>
 protected static bool handlePCMovement(Collider mover, Collider other, Vector2 deltaPosition, out Vector2 allowedMovement)
 {
     switch (other.m_type)
     {
         case ColliderType.Scenery:
             allowedMovement = scaleBackVelocity(mover, other, deltaPosition);
             return true;
         case ColliderType.NPC:
             if (mover.m_type == ColliderType.PC)
             {
                 mover.m_other = other;
             }
             allowedMovement = scaleBackVelocity(mover, other, deltaPosition);
             return true;
         case ColliderType.PC:
             if (mover.m_type == ColliderType.PC)
             {
                 mover.m_other = other;
             }
             if (Quest.currentQuest == Quest.QUEST_TYPE.GET_COMPANION || GameplayManager.ActiveArea.GlobalLocation == Area.PARTY)
             { // if companion isn't in party, treat as NPC collider
                 allowedMovement = scaleBackVelocity(mover, other, deltaPosition);
             }
             else
             { // allow movement through companion
                 allowedMovement = deltaPosition;
             }
             return true;
         //case ColliderType.Effect:
         //    break;
         //case ColliderType.Movable:
         //    break;
         case ColliderType.Trigger:
             allowedMovement = deltaPosition;
             ((ITrigger)other.m_owner).handleImpact(mover);
             return true;
         default:
             allowedMovement = deltaPosition;
             return true;
             //throw new Exception("PC moved into something it shouldn't have");
     }
 }
예제 #10
0
 /// <summary>
 /// Determines how to handle collisions involving the PC
 /// </summary>
 /// <returns>True if the PC can move, false otherwise</returns>
 protected static bool handlePCMovement(Collider mover, Collider other, Vector2 deltaPosition, out Vector2 allowedMovement)
 {
     switch (other.m_type)
     {
         case ColliderType.Scenery:
             allowedMovement = scaleBackVelocity(mover, other, deltaPosition);
             return true;
         case ColliderType.NPC:
             allowedMovement = scaleBackVelocity(mover, other, deltaPosition);
             return true;
         //case ColliderType.Effect:
         //    break;
         //case ColliderType.Movable:
         //    break;
         case ColliderType.Trigger:
             allowedMovement = deltaPosition;
             ((ITrigger)other.m_owner).handleImpact(mover);
             return true;
         default:
             throw new Exception("PC moved into something it shouldn't have");
     }
 }
예제 #11
0
 public abstract void act(Collider mover, bool shouting);
예제 #12
0
        public override void act(Collider mover, bool shouting)
        {
            setFlags();
            if (watching)
            {
                if (example.Count > 0)
                {
                    if (startPoint == null)
                    {
                        Behavior last = null;
                        foreach (Behavior b in example)
                        {
                            if (last == null)
                            {
                                startPoint = b;
                            }
                            else
                            {
                                last.setNext(b);
                            }

                            last = b;
                        }
                    }
                    else
                    {
                        List<LinkedList<Behavior>> paths = getAllPaths(startPoint);
                        int[,] lcsGrid = getLCSGrid(example, paths[0]);
                        int bestPath = 0;
                        int[,] hold;
                        for (int i = 1; i < paths.Count; i++)
                        {
                            hold = getLCSGrid(example, paths[i]);
                            if (hold[hold.GetLength(0) - 1, hold.GetLength(1) - 1] > lcsGrid[lcsGrid.GetLength(0) - 1, lcsGrid.GetLength(1) - 1])
                            {
                                lcsGrid = hold;
                                bestPath = i;
                            }
                        }

                        startPoint = null;
                        LinkedList<Behavior> lcs = getLCS(lcsGrid, example, paths[bestPath], example.Count, paths[bestPath].Count);

                        startPoint = mergePaths(example, paths[bestPath], lcs);
                        paths.RemoveAt(bestPath);

                        foreach (LinkedList<Behavior> llb in paths)
                        {
                            foldIn(llb, lcs);
                        }
                    }
                }
                GameplayManager.Game.Keys[GameState.GameFlag.SIMA_WATCHING] = false;
            }
            else if (openedPuzzle && !completedPuzzle)
            {
                example = new LinkedList<Behavior>();
                GameplayManager.Game.Keys[GameState.GameFlag.SIMA_WAITING] = true;
                GameplayManager.Game.Keys[GameState.GameFlag.PLAYER_PARALYZED] = true;
            }
            GameplayManager.say(getDialogue(shouting));

            //Thread t = new Thread(new ThreadStart(this.actHelper));
            //t.Start();
            //while (!t.IsAlive) ;
        }
예제 #13
0
 /// <summary>
 /// Removes a particular collider from this CollisionDetector
 /// </summary>
 /// <param name="ci">Collider to remove</param>
 public void remove(Collider ci)
 {
     m_tree.Remove(ci);
     ci.forCollisionDetectorUseOnly(null);
 }
예제 #14
0
 /// <summary>
 /// Adds a collider to the detector and marks that collider as being
 /// owned by this detector
 /// </summary>
 /// <param name="ci">Collider to register</param>
 public void register(Collider ci)
 {
     ci.forCollisionDetectorUseOnly(this);
     m_tree.Insert(ci);
 }
        /// <summary>
        /// Code to actually transfer PC to a new Area when touched; called by collision handler
        /// </summary>
        /// <param name="other">Collider which has impacted the trigger</param>
        public override void handleImpact(Collider other)
        {
            if (other.m_owner == GameplayManager.Samus)
            {
                // TODO
                // remove this code once maps are pre-generated and area transition triggers already contain references
                //  to their targets -- or, we might decide its just easier this way
                Point targetGlobalLocation;
                switch (m_side)
                {
                    case AreaSideEnum.Top:
                        targetGlobalLocation = new Point(this.m_owner.GlobalLocation.X, this.m_owner.GlobalLocation.Y - 1);
                        break;
                    case AreaSideEnum.Bottom:
                        targetGlobalLocation = new Point(this.m_owner.GlobalLocation.X, this.m_owner.GlobalLocation.Y + 1);
                        break;
                    case AreaSideEnum.Left:
                        targetGlobalLocation = new Point(this.m_owner.GlobalLocation.X - 1, this.m_owner.GlobalLocation.Y);
                        break;
                    case AreaSideEnum.Right:
                        targetGlobalLocation = new Point(this.m_owner.GlobalLocation.X + 1, this.m_owner.GlobalLocation.Y);
                        break;
                    case AreaSideEnum.Other:
                        throw new Exception("AreaTransitions on non-edges not fully impled");
                        break;
                    default:
                        throw new Exception("Unknown value for AreaSideEnum");
                }
                if (m_target == null)
                {
                    // check if it was created but we just don't have it
                    this.m_target = WorldManager.GetArea(targetGlobalLocation);

                    // still not created, so make it
                    if (m_target == null)
                    {
                        m_target = Area.makeTestArea(targetGlobalLocation);
                    }
                }

                // This code stays
                Point targetTile; // tile on other map on which player should arrive
                switch (m_side)
                {
                    case AreaSideEnum.Top:
                        targetTile = new Point(this.m_tilePos.X, Area.HEIGHT_IN_TILES - 1);
                        break;
                    case AreaSideEnum.Bottom:
                        targetTile = new Point(this.m_tilePos.X, 0);
                        break;
                    case AreaSideEnum.Left:
                        targetTile = new Point(Area.WIDTH_IN_TILES - 1, this.m_tilePos.Y);
                        break;
                    case AreaSideEnum.Right:
                        targetTile = new Point(0, this.m_tilePos.Y);
                        break;
                    case AreaSideEnum.Other:
                        throw new Exception("AreaTransitions on non-edges not fully impled");
                    default:
                        throw new Exception("Unknown value for AreaSideEnum");
                }

                GameplayManager.changeActiveArea(this.m_target, targetTile);

            }
        }
예제 #16
0
 public override void act(Collider mover, bool shouting)
 {
 }
예제 #17
0
 /// <summary>
 /// Certain tile #s in a TileSet may be marked as impassable.  This function looks up those
 /// numbers and makes instances of those tiles in the Area impassable by registering the
 /// appropriate collision box.
 /// </summary>
 public void initializeTileColliders()
 {
     for (int i = 0; i < WIDTH_IN_TILES; ++i)
     {
         for (int j = 0; j < HEIGHT_IN_TILES; ++j)
         {
             if (!TileSet.tileInfos[Tiles[i, j]].passable)
             {
                 Rectangle bounds = getTileRectangle(i, j);
                 Collider ci = new Collider(null, bounds, ColliderType.Scenery);
                 CollisionDetector.register(ci);
             }
         }
     }
 }
예제 #18
0
파일: ATrigger.cs 프로젝트: BNHeadrick/Bros
 public ATrigger(Rectangle bounds)
 {
     m_collider = new Collider(this, bounds, ColliderType.Trigger);
     m_position = new Vector2(m_collider.Bounds.Center().X, m_collider.Bounds.Center().Y);
 }
예제 #19
0
 public ATrigger(Rectangle bounds)
 {
     m_collider = new Collider(this, bounds, ColliderType.Trigger, -1); // -1 is a flag for non-NPC colliders.
     m_position = new Vector2(m_collider.Bounds.Center().X, m_collider.Bounds.Center().Y);
 }
예제 #20
0
        public override void act(Collider mover, bool shouting)
        {
            setFlags();

            if ((f_playerHasSignature && f_playerCompletedPuzzle) || (f_playerHasSignature && !f_playerAccessedPuzzle))
            {
                GameplayManager.Game.Keys[GameState.GameFlag.PLAYER_WON] = true;
            }
            else if ((!f_explained) || (!f_registrarDoorIsOpen && f_explained && !f_riedlFatigue))
            {
                GameplayManager.Game.Keys[GameState.GameFlag.RIEDL_HAS_EXPLAINED] = true;
                GameplayManager.Game.Keys[GameState.GameFlag.RIEDL_WAITING] = true;
                GameplayManager.Game.Keys[GameState.GameFlag.PLAYER_PARALYZED] = true;
            }
            else if (f_riedlFatigue)
            {
                GameplayManager.Game.updateState();
            }
            GameplayManager.say(getDialogue(shouting));
        }
예제 #21
0
 public abstract void handleImpact(Collider mover);