Exemple #1
0
 /// <summary>
 /// Construction a conversation
 /// </summary>
 /// <param name="npc">NPC you will have a conversation with</param>
 /// <param name="state">The games current State</param>
 /// <param name="dataOvlRef">Data.OVL for reference</param>
 public Conversation(NonPlayerCharacterReference npc, GameState state, DataOvlReference dataOvlRef)
 {
     this.Npc          = npc;
     script            = npc.Script;
     this.gameStateRef = state;
     this.dataOvlRef   = dataOvlRef;
 }
Exemple #2
0
 public TalkScript GetTalkScript(SmallMapReferences.SingleMapReference.SmallMapMasterFiles smallMapRef, int nNPC)
 {
     if (NonPlayerCharacterReference.IsSpecialDialogType((NonPlayerCharacterReference.NPCDialogTypeEnum)nNPC))
     {
         return(null);
     }
     return(talkScriptRefs[smallMapRef][nNPC]);
 }
Exemple #3
0
        /// <summary>
        /// Begins the conversation with a particular NPC
        /// </summary>
        /// <param name="npc">the NPC to have a conversation with</param>
        /// <param name="enqueuedScriptItem">a handler to be called when script items are enqueued</param>
        /// <returns>A conversation object to be used to follow along with the conversation</returns>
        public Conversation CreateConversationAndBegin(NonPlayerCharacterReference npc, Conversation.EnqueuedScriptItem enqueuedScriptItem)
        {
            CurrentConversation = new Conversation(npc, State, DataOvlRef);

            CurrentConversation.EnqueuedScriptItemCallback += enqueuedScriptItem;

            PassTime();
            return(CurrentConversation);
        }
Exemple #4
0
        public MapCharacterState(TileReferences tileReferences, NonPlayerCharacterReference npcRef, int nCharacterAnimationStateIndex, TimeOfDay timeOfDay)
        {
            NPCIndex = npcRef.DialogIndex;
            TileRef  = tileReferences.GetTileReference(npcRef.NPCKeySprite);
            CharacterAnimationStateIndex = nCharacterAnimationStateIndex;
            // if you are adding by hand then we can assume that the character is active
            TheCharacterPosition = npcRef.Schedule.GetCharacterDefaultPositionByTime(timeOfDay);

            Active = true;
        }
Exemple #5
0
 public PlayerCharacterRecord GetCharacterRecordByNPC(NonPlayerCharacterReference npc)
 {
     foreach (PlayerCharacterRecord record in Records)
     {
         if (record.Name == npc.Name)
         {
             return(record);
         }
     }
     throw new Exception("Was unable to match CharacterRecord with NPC: " + npc.Name);
 }
Exemple #6
0
        /// <summary>
        /// Resets the current map to a default state - typically no monsters and NPCs in there default positions
        /// </summary>
        private List <NonPlayerCharacterReference> LoadSmallMap(SmallMapReferences.SingleMapReference singleMapReference, TimeOfDay timeOfDay, bool bLoadFromDisk)
        {
            List <NonPlayerCharacterReference> npcCurrentMapRefs = null;

            npcCurrentMapRefs = npcRefs.GetNonPlayerCharactersByLocation(singleMapReference.MapLocation);
            if (bLoadFromDisk)
            {
                smallMapAnimationStates.Load(MapCharacterAnimationStates.MapCharacterAnimationStatesFiles.SAVED_GAM, bLoadFromDisk);
            }
            else
            {
            }

            for (int i = 0; i < MAX_MAP_CHARACTERS; i++)
            {
                if (i == 0)
                {
                    Characters.Add(new MapCharacter());
                    continue;
                }


                NonPlayerCharacterReference npcRef = npcCurrentMapRefs[i];
                MapCharacterState           mapCharState;
                MapCharacterAnimationState  charAnimState = null;
                NonPlayerCharacterMovement  charMovement;

                charMovement = movements.GetMovement(i);

                if (!bLoadFromDisk)
                {
                    // we keep the object because we may be required to save this to disk - but since we are leaving the map there is no need to save their movements
                    charMovement.ClearMovements();
                    mapCharState = new MapCharacterState(tileRefs, npcRef, i, timeOfDay);
                }
                else
                {
                    // character states are only loaded when forced from disk and only on small maps
                    mapCharState = charStates.GetCharacterState(i);

                    if (CurrentAnimationState.HasAnyAnimationStates())
                    {
                        charAnimState = CurrentAnimationState.GetCharacterState(mapCharState.CharacterAnimationStateIndex);
                    }
                }

                Characters.Add(new MapCharacter(npcRef, charAnimState, mapCharState, charMovement, timeOfDay));
            }
            return(npcCurrentMapRefs);
        }
Exemple #7
0
        public void SetCurrentMapType(SmallMapReferences.SingleMapReference singleMapReference, LargeMap.Maps largeMap, TimeOfDay timeOfDay, bool bLoadFromDisk)
        {
            List <NonPlayerCharacterReference> npcCurrentMapRefs = null;

            currentMapType = largeMap;

            // I may need make an additional save of state before wiping these mapcharacters out
            Characters.Clear();

            switch (largeMap)
            {
            case LargeMap.Maps.Small:
                LoadSmallMap(singleMapReference, timeOfDay, bLoadFromDisk);
                return;

            case LargeMap.Maps.Overworld:
                // we don't reload them because the over and underworld are only loaded at boot time
                break;

            case LargeMap.Maps.Underworld:
                break;
            }
            bool bIsLargeMap = largeMap != LargeMap.Maps.Small;

            if (bIsLargeMap)
            {
                for (int i = 0; i < MAX_MAP_CHARACTERS; i++)
                {
                    // the animations are out of order - so we use this reference to track it down
                    NonPlayerCharacterReference npcRef = bIsLargeMap ? null : npcCurrentMapRefs[i];
                    MapCharacterState           mapCharState;

                    MapCharacterAnimationState charAnimState = null;

                    NonPlayerCharacterMovement charMovement;

                    mapCharState  = null;
                    charMovement  = null;
                    charAnimState = CurrentAnimationState.GetCharacterState(i);

                    Characters.Add(new MapCharacter(npcRef, charAnimState, mapCharState, charMovement, timeOfDay));
                }
                //Debug.Assert(charAnimState.X == mapCharState.X);
                //Debug.Assert(charAnimState.Y == mapCharState.Y);
                //Debug.Assert(charAnimState.Floor == mapCharState.Floor);
            }
        }
Exemple #8
0
        public MapCharacter(NonPlayerCharacterReference npcRef, MapCharacterAnimationState mapCharacterAnimationState, MapCharacterState mapCharacterState,
                            NonPlayerCharacterMovement nonPlayerCharacterMovement, TimeOfDay timeOfDay)
        {
            NPCRef         = npcRef;
            AnimationState = mapCharacterAnimationState;
            CharacterState = mapCharacterState;
            Movement       = nonPlayerCharacterMovement;

            CurrentCharacterPosition.Floor = CharacterState == null? 0: CharacterState.TheCharacterPosition.Floor;

            if (CharacterState == null)
            {
                if (npcRef != null)
                {
                    MoveNPCToDefaultScheduledPosition(timeOfDay);
                }
            }
            else
            {
                CurrentCharacterPosition.XY = new Point2D(CharacterState.TheCharacterPosition.X, CharacterState.TheCharacterPosition.Y);
            }
        }
Exemple #9
0
        // left over structure

        /* [StructLayout(LayoutKind.Sequential, Pack = 1)]
         *      private unsafe struct NPC_Info
         *      {
         *          NPC_Schedule schedule[32];
         *          fixed byte type[32]; // merchant, guard, etc.
         *          fixed byte dialog_number[32];
         *      };*/
        #endregion

        #region Initialization and Constructor routines
        /// <summary>
        /// Initialize NPCs from a particular small map master file set
        /// </summary>
        /// <param name="u5Directory">Directory with Ultima 5</param>
        /// <param name="mapMaster">The master map from which to load</param>
        /// <param name="smallMapRef">Small map reference to help link NPCs to a map</param>
        private void InitializeNPCs(string u5Directory, SmallMapReferences.SingleMapReference.SmallMapMasterFiles mapMaster, SmallMapReferences smallMapRef,
                                    TalkScripts talkScriptsRef, GameState gameStateRef)
        {
            // open the appropriate NPC data file
            string dataFilenameAndPath = Path.Combine(u5Directory, SmallMapReferences.SingleMapReference.GetNPCFilenameFromMasterFile(mapMaster));

            // load the file into memory
            List <byte> npcData = Utils.GetFileAsByteList(dataFilenameAndPath);

            for (int nTown = 0; nTown < TOWNS_PER_NPCFILE; nTown++)
            {
                // fresh collections for each major loop to guarantee they are clean
                List <NonPlayerCharacterReference.NPC_Schedule> schedules = new List <NonPlayerCharacterReference.NPC_Schedule>(NPCS_PER_TOWN);
                List <byte> npcTypes        = new List <byte>(NPCS_PER_TOWN);
                List <byte> npcDialogNumber = new List <byte>(NPCS_PER_TOWN);

                SmallMapReferences.SingleMapReference.Location location     = smallMapRef.GetLocationByIndex(mapMaster, nTown);
                SmallMapReferences.SingleMapReference          singleMapRef = smallMapRef.GetSingleMapByLocation(location, 0);

                //sing = SmallMapRef.GetSingleMapByLocation(SmallMapRef.GetLocationByIndex(mapMaster, nTown);

                int townOffset = (TOWN_OFFSET_SIZE * nTown);

                // bajh: I know this could be done in a single loop, but it would be so damn ugly that I honestly don't even want to both
                // read through the schedules first
                int count = 0;
                // start at the town offset, incremenet by an NPC record each time, for 32 loops
                for (int offset = townOffset; count < NPCS_PER_TOWN; offset += SCHEDULE_OFFSET_SIZE, count++)
                {
                    NonPlayerCharacterReference.NPC_Schedule sched = (NonPlayerCharacterReference.NPC_Schedule)Utils.ReadStruct(npcData, offset, typeof(NonPlayerCharacterReference.NPC_Schedule));
                    schedules.Add(sched);
                }
                // bajh: just shoot me if I ever have to write this again - why on earth did LB write all of his data in different formats!
                // these are single byte, so we can capture them just by jumping to their offsets
                count = 0;
                for (int offset = townOffset; count < NPCS_PER_TOWN; offset++, count++)
                {
                    // add NPC type
                    npcTypes.Add(npcData[offset + STARTING_NPC_TYPE_TOWN_OFFSET]);

                    // add NPC dialog #
                    npcDialogNumber.Add(npcData[offset + STARTING_NPC_DIALOG_TOWN_OFFSET]);
                }

                List <byte> keySpriteList = gameStateRef.NonPlayerCharacterKeySprites.GetAsByteList();

                // go over all of the NPCs, create them and add them to the collection
                for (int nNpc = 0; nNpc < NPCS_PER_TOWN; nNpc++)
                {
                    NonPlayerCharacterReference npc = new NonPlayerCharacterReference(location, gameStateRef, schedules[nNpc], npcTypes[nNpc],
                                                                                      npcDialogNumber[nNpc], nNpc, talkScriptsRef.GetTalkScript(mapMaster, npcDialogNumber[nNpc]), (int)(keySpriteList[nNpc] + 100));
                    npcs.Add(npc);
                    // we also create a quick lookup table by location but first need to check that there is an initialized list inside
                    if (!locationToNPCsDictionary.ContainsKey(singleMapRef.MapLocation))
                    {
                        locationToNPCsDictionary.Add(singleMapRef.MapLocation, new List <NonPlayerCharacterReference>());
                    }
                    locationToNPCsDictionary[singleMapRef.MapLocation].Add(npc);
                }
            }
        }
Exemple #10
0
 /// <summary>
 /// DEBUG FUNCTION
 /// </summary>
 /// <param name="npc"></param>
 public void SetNpcHasMetAvatar(NonPlayerCharacterReference npc, bool hasMet)
 {
     npcIsMetArray[npc.MapLocationID][npc.DialogIndex] = hasMet;
 }
Exemple #11
0
 /// <summary>
 /// Has the NPC met the avatar yet?
 /// </summary>
 /// <param name="npc"></param>
 /// <returns></returns>
 public bool NpcHasMetAvatar(NonPlayerCharacterReference npc)
 {
     return(npcIsMetArray[npc.MapLocationID][npc.DialogIndex]);
 }
Exemple #12
0
        /// <summary>
        /// Adds an NPC character to the party, and maps their CharacterRecord
        /// </summary>
        /// <param name="npc">the NPC to add</param>
        public void AddMemberToParty(NonPlayerCharacterReference npc)
        {
            PlayerCharacterRecord record = CharacterRecords.GetCharacterRecordByNPC(npc);

            record.PartyStatus = PlayerCharacterRecord.CharacterPartyStatus.InParty;
        }
Exemple #13
0
 /// <summary>
 /// Sets the flag to indicate the NPC is met
 /// </summary>
 /// <param name="npc"></param>
 public void SetMetNPC(NonPlayerCharacterReference npc)
 {
     npcIsMetArray[npc.MapLocationID][npc.DialogIndex] = true;
 }
Exemple #14
0
 /// <summary>
 /// Is NPC alive?
 /// </summary>
 /// <param name="npc">NPC object</param>
 /// <returns>true if NPC is alive</returns>
 public bool NpcIsAlive(NonPlayerCharacterReference npc)
 {
     // the array isDead becasue LB stores 0=alive, 1=dead
     // I think it's easier to evaluate if they are alive
     return(npcIsDeadArray[npc.MapLocationID][npc.DialogIndex] == false);
 }