Пример #1
0
        /// <summary>
        /// Looks at a particular tile, detecting if NPCs are present as well
        /// Provides string output or special instructions if it is "special"B
        /// </summary>
        /// <param name="xy">position of tile to look at</param>
        /// <param name="specialLookCommand">Special command such as look at gem or sign</param>
        /// <returns>String to output to user</returns>
        public string Look(Point2D xy, out SpecialLookCommand specialLookCommand)
        {
            specialLookCommand = SpecialLookCommand.None;
            string retStr;

            TileReference tileReference = State.TheVirtualMap.GetTileReference(xy);

            // if there is an NPC on the tile, then we assume they want to look at the NPC, not whatever else may be on the tiles
            if (State.TheVirtualMap.IsNPCTile(xy))
            {
                MapCharacter mapCharacter = State.TheVirtualMap.GetNPCOnTile(xy);
                if (mapCharacter == null)
                {
                    throw new Ultima5ReduxException("Tried to look up NPC, but couldn't find the map character");
                }
                retStr = DataOvlRef.StringReferences.GetString(DataOvlReference.Vision2Strings.THOU_DOST_SEE).Trim()
                         + " " + (LookRef.GetLookDescription(mapCharacter.NPCRef.NPCKeySprite).Trim());
            }
            // if we are any one of these signs then we superimpose it on the screen
            else if (SpriteTileReferences.IsSign(tileReference.Index))
            {
                specialLookCommand = SpecialLookCommand.Sign;
                retStr             = string.Empty;
            }
            else if (SpriteTileReferences.GetTileNumberByName("Clock1") == tileReference.Index)
            {
                retStr = (DataOvlRef.StringReferences.GetString(DataOvlReference.Vision2Strings.THOU_DOST_SEE).Trim()
                          + " " + (LookRef.GetLookDescription(tileReference.Index).TrimStart()
                                   + State.TheTimeOfDay.FormattedTime));
            }
            else // lets see what we've got here!
            {
                retStr = (DataOvlRef.StringReferences.GetString(DataOvlReference.Vision2Strings.THOU_DOST_SEE).Trim()
                          + " " + (LookRef.GetLookDescription(tileReference.Index).TrimStart()));
            }

            // pass time at the end to make sure moving characters are accounted for
            PassTime();
            return(retStr);
        }
Пример #2
0
        /// <summary>
        /// Tries to move the avatar in a given direction - if succesful it will move him
        /// </summary>
        /// <param name="direction">the direction you want to move</param>
        /// <param name="bKlimb">is the avatar K-limbing?</param>
        /// <param name="bFreeMove">is "free move" on?</param>
        /// <param name="tryToMoveResult">outputs the result of the attempt</param>
        /// <returns>output string (may be empty)</returns>
        public string TryToMove(VirtualMap.Direction direction, bool bKlimb, bool bFreeMove, out TryToMoveResult tryToMoveResult)
        {
            int nTilesPerMapRow = State.TheVirtualMap.NumberOfRowTiles;
            int nTilesPerMapCol = State.TheVirtualMap.NumberOfColumnTiles;

            // if we were to move, which direction would we move
            GetAdjustments(direction, out int xAdjust, out int yAdjust);

            // would we be leaving a small map if we went forward?
            if (!State.TheVirtualMap.IsLargeMap && (
                    (State.TheVirtualMap.CurrentPosition.Y == (nTilesPerMapRow - 1) && direction == VirtualMap.Direction.Down) ||
                    (State.TheVirtualMap.CurrentPosition.Y == (0) && direction == VirtualMap.Direction.Up) ||
                    (State.TheVirtualMap.CurrentPosition.X == (nTilesPerMapCol - 1) && direction == VirtualMap.Direction.Right) ||
                    (State.TheVirtualMap.CurrentPosition.X == (0) && direction == VirtualMap.Direction.Left)))
            {
                tryToMoveResult = TryToMoveResult.OfferToExitScreen;
                // it is expected that the called will offer an exit option, but we won't move the avatar because the space
                // is empty
                return(string.Empty);
            }

            // calculate our new x and y values based on the adjustments
            int     newX   = (State.TheVirtualMap.CurrentPosition.X + xAdjust) % nTilesPerMapCol;
            int     newY   = (State.TheVirtualMap.CurrentPosition.Y + yAdjust) % nTilesPerMapRow;
            Point2D newPos = new Point2D(newX, newY);

            // if we have reached 0, and we are adjusting -1 then we should assume it's a round world and we are going to the opposite side
            // this should only be true if it is a RepeatMap
            if (newX < 0)
            {
                Debug.Assert(State.TheVirtualMap.IsLargeMap, "You should not reach the very end of a map +/- 1 if you are not on a repeating map"); newX = nTilesPerMapCol + newX;
            }
            if (newY < 0)
            {
                Debug.Assert(State.TheVirtualMap.IsLargeMap, "You should not reach the very end of a map +/- 1 if you are not on a repeating map"); newY = nTilesPerMapRow + newY;
            }

            // we get the newTile so that we can determine if it's passable
            //int newTile = GetTileNumber(newX, newY);
            TileReference newTileReference = State.TheVirtualMap.GetTileReference(newX, newY);

            if (newTileReference.Index == SpriteTileReferences.GetTileNumberByName("BrickFloorHole"))
            {
                State.TheVirtualMap.UseStairs(newPos, true);
                tryToMoveResult = TryToMoveResult.Fell;
                // we need to evaluate in the game and let the game know that they should continue to fall
                TileReference newTileRef = State.TheVirtualMap.GetTileReference(State.TheVirtualMap.CurrentPosition);
                if (newTileRef.Index == SpriteTileReferences.GetTileNumberByName("BrickFloorHole"))
                {
                    IsPendingFall = true;
                }

                // todo: get string from data file
                return("A TRAPDOOR!");
            }

            // we have evaluated and now know there is not a further fall (think Blackthorne's palace)
            IsPendingFall = false;

            // it's passable if it's marked as passable,
            // but we double check if the portcullis is down
            bool bPassable = newTileReference.IsWalking_Passable &&
                             !(SpriteTileReferences.GetTileNumberByName("BrickWallArchway") == newTileReference.Index && !State.TheTimeOfDay.IsDayLight) &&
                             !State.TheVirtualMap.IsNPCTile(newPos);


            // this is insufficient in case I am in a boat
            if (bPassable || bFreeMove || (bKlimb && newTileReference.IsKlimable))
            {
                State.TheVirtualMap.CurrentPosition.X = newX;
                State.TheVirtualMap.CurrentPosition.Y = newY;
            }
            else
            {
                tryToMoveResult = TryToMoveResult.Blocked;
                // if it's not passable then we have no more business here
                AdvanceTime(2);
                return(DataOvlRef.StringReferences.GetString(DataOvlReference.TravelStrings.BLOCKED));
            }

            // the world is a circular - so when you get to the end, start over again
            // this will prevent a never ending growth or shrinking of character position in case the travel the world only moving right a bagillion times
            State.TheVirtualMap.CurrentPosition.X %= nTilesPerMapCol;
            State.TheVirtualMap.CurrentPosition.Y %= nTilesPerMapRow;

            // if you walk on top of a staircase then we will immediately jump to the next floor
            if (SpriteTileReferences.IsStaircase(newTileReference.Index))
            {
                tryToMoveResult = TryToMoveResult.UsedStairs;
                State.TheVirtualMap.UseStairs(State.TheVirtualMap.CurrentPosition);
                return(string.Empty);
            }

            // if we are on a big map then we may issue extra information about slow moving terrain
            if (State.TheVirtualMap.IsLargeMap)
            {
                AdvanceTime(SpriteTileReferences.GetMinuteIncrement(newTileReference.Index));
                tryToMoveResult = TryToMoveResult.Moved;
                return(SpriteTileReferences.GetSlowMovementString(newTileReference.Index));;
            }
            else
            {
                tryToMoveResult = TryToMoveResult.Moved;

                // if we are indoors then all walking takes 2 minutes
                AdvanceTime(2);

                return(string.Empty);
            }
        }
Пример #3
0
        /// <summary>
        /// Try to jimmy the door with a given character
        /// </summary>
        /// <param name="xy">position of the door</param>
        /// <param name="record">character who will attempt to open it</param>
        /// <param name="bWasSuccessful">was it a successful jimmy?</param>
        /// <returns>the output string to write to console</returns>
        public string TryToJimmyDoor(Point2D xy, PlayerCharacterRecord record, out bool bWasSuccessful)
        {
            bWasSuccessful = false;
            TileReference tileReference = State.TheVirtualMap.GetTileReference(xy);
            string        retStr;

            bool isDoorInDirection = tileReference.IsOpenable;

            if (!isDoorInDirection)
            {
                retStr = (DataOvlRef.StringReferences.GetString(DataOvlReference.OpeningThingsStrings.NO_LOCK));
            }
            else
            {
                bool bIsDoorMagical = SpriteTileReferences.IsDoorMagical(tileReference.Index);
                bool bIsDoorLocked  = SpriteTileReferences.IsDoorLocked(tileReference.Index);

                if (bIsDoorMagical)
                {
                    // we use up a key
                    State.Keys--;

                    // for now we will also just open the door so we can get around - will address when we have spells
                    if (SpriteTileReferences.IsDoorWithView(tileReference.Index))
                    {
                        State.TheVirtualMap.SetOverridingTileReferece(
                            SpriteTileReferences.GetTileReferenceByName("RegularDoorView"), xy);
                    }
                    else
                    {
                        State.TheVirtualMap.SetOverridingTileReferece(
                            SpriteTileReferences.GetTileReferenceByName("RegularDoor"), xy);
                    }

                    bWasSuccessful = true;

                    retStr = (DataOvlRef.StringReferences.GetString(DataOvlReference.OpeningThingsStrings.KEY_BROKE));
                }
                else if (bIsDoorLocked)
                {
                    // we use up a key
                    State.Keys--;

                    // todo: bh: we will need to determine the likelihood of lock picking success, for now, we always succeed

                    // bh: open player selection dialog here
                    //record.

                    // bh: assume it's me for now

                    if (SpriteTileReferences.IsDoorWithView(tileReference.Index))
                    {
                        State.TheVirtualMap.SetOverridingTileReferece(
                            SpriteTileReferences.GetTileReferenceByName("RegularDoorView"), xy);
                    }
                    else
                    {
                        State.TheVirtualMap.SetOverridingTileReferece(
                            SpriteTileReferences.GetTileReferenceByName("RegularDoor"), xy);
                    }

                    bWasSuccessful = true;
                    retStr         = (DataOvlRef.StringReferences.GetString(DataOvlReference.OpeningThingsStrings.UNLOCKED));
                }
                else
                {
                    retStr = (DataOvlRef.StringReferences.GetString(DataOvlReference.OpeningThingsStrings.NO_LOCK));
                }
            }

            PassTime();
            return(retStr);
        }
Пример #4
0
        /// <summary>
        /// Climbs the ladder on the current tile that the Avatar occupies
        /// </summary>
        public string TryToKlimb(out KlimbResult klimbResult)
        {
            string getKlimbOutput(string output = "")
            {
                if (output == "")
                {
                    return(DataOvlRef.StringReferences.GetString(DataOvlReference.TravelStrings.KLIMB));
                }
                return(DataOvlRef.StringReferences.GetString(DataOvlReference.TravelStrings.KLIMB) + output);
            }

            TileReference curTileRef = State.TheVirtualMap.GetTileReferenceOnCurrentTile();

            // if it's a large map, we either klimb with the grapple or don't klimb at all
            if (State.TheVirtualMap.IsLargeMap)
            {
                if (State.HasGrapple) // we don't have a grapple, so we can't klimb
                {
                    klimbResult = KlimbResult.RequiresDirection;
                    return(getKlimbOutput());
                }
                klimbResult = KlimbResult.CantKlimb;
                return(getKlimbOutput(DataOvlRef.StringReferences.GetString(DataOvlReference.KlimbingStrings.WITH_WHAT)));
            }

            // we can't klimb on the current tile, so we need to pick a direction
            if (!SpriteTileReferences.IsLadder(curTileRef.Index) && !SpriteTileReferences.IsGrate(curTileRef.Index))
            {
                klimbResult = KlimbResult.RequiresDirection;
                return(getKlimbOutput());
            }

            SmallMapReferences.SingleMapReference.Location location = State.TheVirtualMap.CurrentSingleMapReference.MapLocation;
            int  nCurrentFloor = State.TheVirtualMap.CurrentSingleMapReference.Floor;
            bool hasBasement   = State.TheVirtualMap.SmallMapRefs.HasBasement(location);
            int  nTotalFloors  = State.TheVirtualMap.SmallMapRefs.GetNumberOfFloors(location);
            int  nTopFloor     = hasBasement ? nTotalFloors - 1 : nTotalFloors;

            TileReference tileReference = State.TheVirtualMap.GetTileReference(State.TheVirtualMap.CurrentPosition);

            if (SpriteTileReferences.IsLadderDown(tileReference.Index) || SpriteTileReferences.IsGrate(tileReference.Index))
            {
                if ((hasBasement && nCurrentFloor >= 0) || nCurrentFloor > 0)
                {
                    State.TheVirtualMap.LoadSmallMap(SmallMapRef.GetSingleMapByLocation(location, nCurrentFloor - 1), State.CharacterRecords, false);
                    klimbResult = KlimbResult.Success;
                    return(getKlimbOutput(DataOvlRef.StringReferences.GetString(DataOvlReference.TravelStrings.DOWN)));
                }
            }
            else if (SpriteTileReferences.IsLadderUp(tileReference.Index))
            {
                if (nCurrentFloor + 1 < nTopFloor)
                {
                    State.TheVirtualMap.LoadSmallMap(SmallMapRef.GetSingleMapByLocation(location, nCurrentFloor + 1), State.CharacterRecords, false);
                    klimbResult = KlimbResult.Success;
                    return(getKlimbOutput(DataOvlRef.StringReferences.GetString(DataOvlReference.TravelStrings.UP)));
                }
            }

            klimbResult = KlimbResult.RequiresDirection;
            return(getKlimbOutput());
        }
Пример #5
0
        /// <summary>
        /// Try to jimmy the door with a given character
        /// </summary>
        /// <param name="xy">position of the door</param>
        /// <param name="record">character who will attempt to open it</param>
        /// <param name="bWasSuccesful">was it a successful jimmy?</param>
        /// <returns></returns>
        public string TryToJimmyDoor(Point2D xy, PlayerCharacterRecord record, out bool bWasSuccesful)
        {
            bWasSuccesful = false;
            //Point2D doorPos = GetAdustedPos(CurrentVirtualMap.CurrentPosition, keyCode);
            //int doorTileSprite = GetTileNumber(doorPos.X, doorPos.Y);
            TileReference tileReference     = State.TheVirtualMap.GetTileReference(xy);
            bool          isDoorInDirection = tileReference.IsOpenable;

            if (!isDoorInDirection)
            {
                return(DataOvlRef.StringReferences.GetString(DataOvlReference.OPENING_THINGS_STRINGS.NO_LOCK));
            }

            bool bIsDoorMagical = SpriteTileReferences.IsDoorMagical(tileReference.Index);
            bool bIsDoorLocked  = SpriteTileReferences.IsDoorLocked(tileReference.Index);

            if (bIsDoorMagical)
            {
                // we use up a key
                State.Keys--;

                // for now we will also just open the door so we can get around - will address when we have spells
                if (SpriteTileReferences.IsDoorWithView(tileReference.Index))
                {
                    State.TheVirtualMap.SetOverridingTileReferece(SpriteTileReferences.GetTileReferenceByName("RegularDoorView"), xy);
                }
                else
                {
                    State.TheVirtualMap.SetOverridingTileReferece(SpriteTileReferences.GetTileReferenceByName("RegularDoor"), xy);
                }
                //ReassignSprites();
                bWasSuccesful = true;

                return(DataOvlRef.StringReferences.GetString(DataOvlReference.OPENING_THINGS_STRINGS.KEY_BROKE));
            }
            if (bIsDoorLocked)
            {
                // we use up a key
                State.Keys--;

                // todo: bh: we will need to determine the likelihood of lock picking success, for now, we always succeed

                // bh: open player selection dialog here
                //record.

                // bh: assume it's me for now

                if (SpriteTileReferences.IsDoorWithView(tileReference.Index))
                {
                    State.TheVirtualMap.SetOverridingTileReferece(SpriteTileReferences.GetTileReferenceByName("RegularDoorView"), xy);
                }
                else
                {
                    State.TheVirtualMap.SetOverridingTileReferece(SpriteTileReferences.GetTileReferenceByName("RegularDoor"), xy);
                }
                //ReassignSprites();
                bWasSuccesful = true;
                return(DataOvlRef.StringReferences.GetString(DataOvlReference.OPENING_THINGS_STRINGS.UNLOCKED));
            }
            else
            {
                return(DataOvlRef.StringReferences.GetString(DataOvlReference.OPENING_THINGS_STRINGS.NO_LOCK));
            }
        }