Пример #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;
 }
Пример #2
0
        /// <summary>
        /// Construct an NPC
        /// </summary>
        /// <param name="mapRef">Which map are they on?</param>
        /// <param name="sched">daily schedule</param>
        /// <param name="npcType">type of NPC they are</param>
        /// <param name="dialogNumber">dialog number referencing data OVL</param>
        /// <param name="dialogIndex">0-31 index of it's position in the NPC arrays (used for saved.gam references)</param>
        /// <param name="talkScript">their conversation script</param>
        public NonPlayerCharacterReference(SmallMapReferences.SingleMapReference.Location location, GameState gameStateRef, NPC_Schedule sched,
                                           byte npcType, byte dialogNumber, int dialogIndex, TalkScript talkScript, int nKeySprite)
        {
            Schedule = new NonPlayerCharacterSchedule(sched);

            MapLocation  = location;
            NPCKeySprite = nKeySprite;

            CharacterType     = npcType;
            DialogNumber      = dialogNumber;
            Script            = talkScript;
            DialogIndex       = dialogIndex;
            this.gameStateRef = gameStateRef;


            // no schedule? I guess you're not real
            if (!IsEmptySched(sched))
            {
                System.Console.WriteLine(location.ToString() + "     NPC Number: " + this.DialogNumber + " in " + location.ToString());
            }
        }
Пример #3
0
        /// <summary>
        /// Intializes an individual TalkingScript using the raw data created from InitalizeTalkScriptsRaw
        /// <remark>May God have mercy on my soul if I ever need to debug or troubleshoot this again.</remark>
        /// </summary>
        /// <param name="smallMapRef">the small map reference</param>
        /// <param name="index">NPC Index</param>
        private TalkScript InitializeTalkScriptFromRaw(SmallMapReferences.SingleMapReference.SmallMapMasterFiles smallMapRef, int index)
        {
            TalkScript talkScript = new TalkScript();                                   // the script we are building and will return

            List <bool> labelsSeenList = new List <bool>(TalkScript.TOTAL_LABELS);      // keeps track of the labels we have already seen

            labelsSeenList.AddRange(Enumerable.Repeat(false, TalkScript.TOTAL_LABELS)); // creates a list of "false" bools to set the default labelsSeenList

            bool   writingSingleCharacters = false;                                     // are we currently writing a single character at a time?
            string buildAWord = string.Empty;                                           // the word we are currently building if we are writingSingleCharacters=true

            foreach (byte byteWord in talkRefs[smallMapRef][index])
            {
                // if a NULL byte is provided then you need to go the next line, resetting the writingSingleCharacters so that a space is not inserted next line
                // bh: Sept 21, 2019 - had to add a disgusting hack to account for what appears to be broken
                //   data or a misunderstood algorithm - they seem to have an end of script line in the middle of a response
                //   there could be a rule I simply don't undertstand, but for now - i hack
                if (byteWord == END_OF_SCRIPTLINE_BYTE && !buildAWord.EndsWith("to give unto charity!"))
                {
                    buildAWord += "\n";
                    // we are done with the entire line, so lets add it the script
                    talkScript.AddTalkCommand(TalkScript.TalkCommand.PlainString, buildAWord);
                    // tells the script to move onto the next command
                    talkScript.NextLine();
                    // reset some vars
                    buildAWord = string.Empty;
                    writingSingleCharacters = false;
                    continue;
                }

                byte tempByte          = (byte)((int)byteWord); // this is the byte that we will manipulate, leaving the byteWord in tact
                bool usePhraseLookup   = false;                 // did we do a phrase lookup (else we are typing single letters)
                bool useCompressedWord = false;                 // did we succesfully use a compressed word?

                // if it's one of the bytes that requires a subraction of 0x80 (128)
                if (byteWord >= 165 && byteWord <= 218)
                {
                    tempByte -= TALK_OFFSET_ADJUST;
                }
                else if (byteWord >= 225 && byteWord <= 250)
                {
                    tempByte -= TALK_OFFSET_ADJUST;
                }
                else if (byteWord >= 160 && byteWord <= 161)
                {
                    tempByte -= TALK_OFFSET_ADJUST;
                }
                else
                {
                    // it didn't match which means that it's one the special phrases and we will perform a lookup
                    usePhraseLookup = true;
                }

                // Debug code to help track down particular codes being written
                // if (tempByte == 119) { Console.Write("");  }
                // it wasn't a special phrase which means that the words are being typed one word at a time
                if (!usePhraseLookup)
                {
                    // I'm writing single characters, we will keep track so that when we hit the end we can insert a space
                    writingSingleCharacters = true;
                    // this signifies the end of the printing (sample code enters a newline)
                    if ((char)tempByte == '@')
                    {
                        //Console.WriteLine("");
                        continue;
                    }
                    //Console.Write((char)tempByte);
                    buildAWord += (char)tempByte;
                    // Debug code to help track down an NPCs question or response
                    //if (buildAWord.Contains("to give unto charity")) { Console.Write(""); }
                }
                else // usePhraseLookup = true
                {
                    // We were instructed to perform a lookup, either a compressed word lookup, or a special character

                    // if we were previously writing single characters, but have moved onto lookups, then we add a space, and reset it
                    if (writingSingleCharacters)
                    {
                        writingSingleCharacters = false;
                        buildAWord += " ";
                    }

                    // we are going to lookup the word in the compressed word list, if we throw an exception then we know it wasn't in the list
                    if (compressedWordRef.IsTalkingWord((int)tempByte))
                    {
                        string talkingWord = compressedWordRef.GetTalkingWord((int)tempByte);
                        useCompressedWord = true;
                        buildAWord       += talkingWord;
                    }
                    // this is a bit lazy, but if I ask for a string that is not captured in the lookup map, then we know it's a special case
                    else
                    {
                        // oddly enough - we add an existing plain string that we have been building
                        // at the very last second
                        if (buildAWord != string.Empty)
                        {
                            talkScript.AddTalkCommand(TalkScript.TalkCommand.PlainString, buildAWord);
                            buildAWord = string.Empty;
                        }

                        // if the tempByte is within these boundaries then it is a label
                        // it is up to us to determine if it a Label or a GotoLabel
                        if (tempByte >= TalkScript.MIN_LABEL && tempByte <= TalkScript.MAX_LABEL)
                        {
                            // create an offset starting at 0 for label numbering
                            int offset = tempByte - TalkScript.MIN_LABEL;
                            // have I already seen a label once? Then the next label is a definition
                            if (labelsSeenList[offset] == true)
                            {
                                talkScript.AddTalkLabel(TalkScript.TalkCommand.DefineLabel, offset);
                            }
                            else
                            {
                                // the first time you see the label is a goto statement
                                talkScript.AddTalkLabel(TalkScript.TalkCommand.DefineLabel, offset);
                                //talkScript.AddTalkLabel(TalkScript.TalkCommand.GotoLabel, offset);
                                labelsSeenList[offset] = true;
                            }
                        }
                        else
                        {
                            // this is just a standard special command, so let's add it
                            talkScript.AddTalkCommand((TalkScript.TalkCommand)tempByte, string.Empty);
                        }
                    }
                    // we just used a compressed word which means we need to insert a space afterwards
                    if (useCompressedWord)
                    {
                        buildAWord += " ";
                    }
                }
            }
            talkScript.InitScript();
            return(talkScript);
        }