예제 #1
0
 void _initialize()
 {
     OfficersPresent      = BriefingOfficers.FlightOfficer;
     _invalidError        = _invalidError.Replace("{0}", "TIE");
     _iffHostile[0]       = true;
     _iffNameIndexer      = new IffNameIndexer(this);
     _iffHostileIndexer   = new Indexer <bool>(_iffHostile, new bool[] { true, true, false, false, false, false });
     _endOfMissionIndexer = new Indexer <string>(_endOfMissionMessages, 63);
     FlightGroups         = new FlightGroupCollection();
     Messages             = new MessageCollection();
     GlobalGoals          = new Globals();
     Briefing             = new Briefing();
     BriefingQuestions    = new Questions();
 }
예제 #2
0
        /// <summary>Loads a mission from an open FileStream</summary>
        /// <param name="stream">Opened FileStream to mission file</param>
        /// <exception cref="System.IO.InvalidDataException"><i>stream</i> is not a valid TIE mission file</exception>
        public void LoadFromStream(FileStream stream)
        {
            if (MissionFile.GetPlatform(stream) != MissionFile.Platform.TIE)
            {
                throw new InvalidDataException(_invalidError);
            }
            BinaryReader br = new BinaryReader(stream, System.Text.Encoding.Default);               //[JB] Added encoding
            int          i;

            stream.Position = 2;
            short numFlightGroups = br.ReadInt16();
            short numMessages     = br.ReadInt16();

            stream.Position = 0xA;
            try { OfficersPresent = (Mission.BriefingOfficers)br.ReadByte(); }
            catch { OfficersPresent = Mission.BriefingOfficers.Both; }
            stream.Position    = 0xD;
            CapturedOnEjection = br.ReadBoolean();
            stream.Position    = 0x18;
            for (i = 0; i < 6; i++)
            {
                EndOfMissionMessages[i] = new string(br.ReadChars(64));
            }
            stream.Position += 2;
            byte[] buffer = new byte[64];
            for (i = 2; i < 6; i++)
            {
                IFFs[i] = new string(br.ReadChars(12));
            }
            #region FlightGroups
            FlightGroups = new FlightGroupCollection(numFlightGroups);
            for (i = 0; i < FlightGroups.Count; i++)
            {
                #region Craft
                int j;
                FlightGroups[i].Name         = new string(br.ReadChars(12));
                FlightGroups[i].Pilot        = new string(br.ReadChars(12));            //not used by TIE
                FlightGroups[i].Cargo        = new string(br.ReadChars(12));
                FlightGroups[i].SpecialCargo = new string(br.ReadChars(12));
                stream.Read(buffer, 0, 0x38);
                FlightGroups[i].SpecialCargoCraft = buffer[0];
                FlightGroups[i].RandSpecCargo     = Convert.ToBoolean(buffer[1]);
                FlightGroups[i].CraftType         = buffer[2];
                FlightGroups[i].NumberOfCraft     = buffer[3];
                // the Rand part of the check below is because if true, don't need to mess with it
                if (!FlightGroups[i].RandSpecCargo)
                {
                    if (FlightGroups[i].SpecialCargoCraft >= FlightGroups[i].NumberOfCraft)
                    {
                        FlightGroups[i].SpecialCargoCraft = 0;
                    }
                    else
                    {
                        FlightGroups[i].SpecialCargoCraft++;
                    }
                }
                FlightGroups[i].Status1            = buffer[4];
                FlightGroups[i].Missile            = buffer[5];
                FlightGroups[i].Beam               = buffer[6];
                FlightGroups[i].IFF                = buffer[7];
                FlightGroups[i].AI                 = buffer[8];
                FlightGroups[i].Markings           = buffer[9];
                FlightGroups[i].FollowsOrders      = Convert.ToBoolean(buffer[0xA]);
                FlightGroups[i].Unknowns.Unknown1  = buffer[0xB];
                FlightGroups[i].Formation          = buffer[0xC];
                FlightGroups[i].FormDistance       = buffer[0xD];
                FlightGroups[i].GlobalGroup        = buffer[0xE];
                FlightGroups[i].FormLeaderDist     = buffer[0xF];
                FlightGroups[i].NumberOfWaves      = (byte)(buffer[0x10] + 1);
                FlightGroups[i].Unknowns.Unknown5  = buffer[0x11];
                FlightGroups[i].PlayerCraft        = buffer[0x12];
                FlightGroups[i].Yaw                = (short)Math.Round((double)(sbyte)buffer[0x13] * 360 / 0x100);
                FlightGroups[i].Pitch              = (short)Math.Round((double)(sbyte)buffer[0x14] * 360 / 0x100);
                FlightGroups[i].Pitch             += (short)(FlightGroups[i].Pitch < -90 ? 270 : -90);
                FlightGroups[i].Roll               = (short)Math.Round((double)(sbyte)buffer[0x15] * 360 / 0x100);
                FlightGroups[i].Unknowns.Unknown9  = Convert.ToBoolean(buffer[0x16]);
                FlightGroups[i].Unknowns.Unknown10 = buffer[0x17];
                FlightGroups[i].Unknowns.Unknown11 = buffer[0x18];
                #endregion
                #region Arr/Dep
                FlightGroups[i].Difficulty            = buffer[0x19];
                FlightGroups[i].ArrDepTriggers[0]     = new Trigger(buffer, 0x1A);
                FlightGroups[i].ArrDepTriggers[1]     = new Trigger(buffer, 0x1E);
                FlightGroups[i].AT1AndOrAT2           = Convert.ToBoolean(buffer[0x22]);
                FlightGroups[i].Unknowns.Unknown12    = buffer[0x23];
                FlightGroups[i].ArrivalDelayMinutes   = buffer[0x24];
                FlightGroups[i].ArrivalDelaySeconds   = buffer[0x25];
                FlightGroups[i].ArrDepTriggers[2]     = new Trigger(buffer, 0x26);
                FlightGroups[i].DepartureTimerMinutes = buffer[0x2A];
                FlightGroups[i].DepartureTimerSeconds = buffer[0x2B];
                FlightGroups[i].AbortTrigger          = buffer[0x2C];
                FlightGroups[i].Unknowns.Unknown15    = buffer[0x2D];
                FlightGroups[i].Unknowns.Unknown16    = buffer[0x2E];
                FlightGroups[i].Unknowns.Unknown17    = buffer[0x2F];
                FlightGroups[i].ArrivalCraft1         = buffer[0x30];
                FlightGroups[i].ArrivalMethod1        = Convert.ToBoolean(buffer[0x31]);
                FlightGroups[i].DepartureCraft1       = buffer[0x32];
                FlightGroups[i].DepartureMethod1      = Convert.ToBoolean(buffer[0x33]);
                FlightGroups[i].ArrivalCraft2         = buffer[0x34];
                FlightGroups[i].ArrivalMethod2        = Convert.ToBoolean(buffer[0x35]);
                FlightGroups[i].DepartureCraft2       = buffer[0x36];
                FlightGroups[i].DepartureMethod2      = Convert.ToBoolean(buffer[0x37]);
                #endregion
                stream.Read(buffer, 0, 0x36);
                for (j = 0; j < 3; j++)
                {
                    FlightGroups[i].Orders[j] = new FlightGroup.Order(buffer, j * 18);
                }
                stream.Read(buffer, 0, 0xA);
                FlightGroups[i].Goals = new FlightGroup.FGGoals(buffer, 0);
                for (j = 0; j < 4; j++)
                {
                    for (int k = 0; k < 15; k++)
                    {
                        FlightGroups[i].Waypoints[k][j] = (short)(br.ReadInt16() * (j == 1 ? -1 : 1));
                    }
                }
                FlightGroups[i].Unknowns.Unknown19 = br.ReadBoolean();
                stream.Position++;
                FlightGroups[i].Unknowns.Unknown20 = br.ReadByte();
                FlightGroups[i].Unknowns.Unknown21 = br.ReadBoolean();
            }
            #endregion
            #region Messages
            if (numMessages != 0)
            {
                Messages = new MessageCollection(numMessages);
                for (i = 0; i < Messages.Count; i++)
                {
                    Messages[i].MessageString = new string(br.ReadChars(64)).Trim('\0');
                    if (Messages[i].MessageString.IndexOf('\0') != -1)
                    {
                        Messages[i].MessageString = Messages[i].MessageString.Substring(0, Messages[i].MessageString.IndexOf('\0'));
                    }
                    Messages[i].Color = 0;
                    if (Messages[i].MessageString.Length > 0)                      //[JB] Added length check, otherwise empty strings would crash the load process and make the mission unrecoverable to anything but hex editing.
                    {
                        char c = Messages[i].MessageString[0];
                        if (c >= '1' && c <= '3')
                        {
                            Messages[i].Color         = (byte)(c - '0');
                            Messages[i].MessageString = Messages[i].MessageString.Substring(1);
                        }
                    }
                    stream.Read(buffer, 0, 8);
                    Messages[i].Triggers[0]     = new Trigger(buffer, 0);
                    Messages[i].Triggers[1]     = new Trigger(buffer, 4);
                    Messages[i].Short           = new string(br.ReadChars(12));
                    stream.Position            += 4;
                    Messages[i].Delay           = br.ReadByte();
                    Messages[i].Trig1AndOrTrig2 = br.ReadBoolean();
                }
            }
            else
            {
                Messages.Clear();
            }
            #endregion
            #region Globals
            for (i = 0; i < 3; i++)
            {
                stream.Read(buffer, 0, 8);
                GlobalGoals.Goals[i].Triggers[0] = new Trigger(buffer, 0);
                GlobalGoals.Goals[i].Triggers[1] = new Trigger(buffer, 4);
                stream.Position += 0x11;
                //for some reason, there's triggers with Var set with no Type
                if (GlobalGoals.Goals[i].Triggers[0].VariableType == 0)
                {
                    GlobalGoals.Goals[i].Triggers[0].Variable = 0;
                }
                if (GlobalGoals.Goals[i].Triggers[1].VariableType == 0)
                {
                    GlobalGoals.Goals[i].Triggers[1].Variable = 0;
                }
                GlobalGoals.Goals[i].T1AndOrT2 = br.ReadBoolean();
                stream.Position += 2;
            }
            #endregion
            #region Briefing
            Briefing.Length   = br.ReadInt16();
            Briefing.Unknown1 = br.ReadInt16();
            stream.Position  += 6;              // StartLength, EventsLength, Res(0)
            for (i = 0; i < 12; i++)
            {
                stream.Read(buffer, 0, 0x40);
                Buffer.BlockCopy(buffer, 0, Briefing.Events, 0x40 * i, 0x40);
            }
            stream.Read(buffer, 0, 0x20);
            Buffer.BlockCopy(buffer, 0, Briefing.Events, 0x300, 0x20);
            for (i = 0; i < 32; i++)
            {
                int j = br.ReadInt16();
                if (j > 0)
                {
                    Briefing.BriefingTag[i] = new string(br.ReadChars(j));
                }
            }
            for (i = 0; i < 32; i++)
            {
                int j = br.ReadInt16();
                if (j > 0)
                {
                    Briefing.BriefingString[i] = new string(br.ReadChars(j));
                }
            }
            #endregion
            #region Questions
            for (i = 0; i < 10; i++)
            {
                int j, k, l = 0;
                j = br.ReadInt16();                     //read the question length, we're just not going to save it
                if (j == 1)
                {
                    stream.Position++;                          //if it's just the return, get rid of it
                    continue;
                }
                if (j == 0)
                {
                    continue;
                }
                for (k = 0; k < j; k++)
                {
                    BriefingQuestions.PreMissQuestions[i] += br.ReadChar().ToString();
                    l++;
                    if (stream.ReadByte() == 10)
                    {
                        break;
                    }
                    else
                    {
                        stream.Position--;
                    }
                }
                l++;
                for (k = l; k < j; k++)
                {
                    int b = stream.ReadByte();
                    switch (b)                          //TIE uses char(2) and char(1) for bolding in this section
                    {
                    case 1:
                        BriefingQuestions.PreMissAnswers[i] += "]";
                        break;

                    case 2:
                        BriefingQuestions.PreMissAnswers[i] += "[";
                        break;

                    case 10:
                        BriefingQuestions.PreMissAnswers[i] += "\r\n";                                  //because txt doesn't like \n by itself
                        break;

                    default:
                        BriefingQuestions.PreMissAnswers[i] += Convert.ToChar(b).ToString();
                        break;
                    }
                }
            }
            for (i = 0; i < 10; i++)
            {
                int j, k, l = 2;
                j = br.ReadInt16();                     //also got rid of saving here, calc'ing on the fly
                if (j == 3)
                {
                    stream.Position += 3;                       // goddamn TFW-isms
                    continue;
                }
                if (j == 0)
                {
                    continue;
                }
                BriefingQuestions.PostTrigger[i]  = br.ReadByte();
                BriefingQuestions.PostTrigType[i] = br.ReadByte();
                for (k = 0; k < j; k++)
                {
                    BriefingQuestions.PostMissQuestions[i] += br.ReadChar().ToString();
                    l++;
                    if (stream.ReadByte() == 10)
                    {
                        break;
                    }
                    else
                    {
                        stream.Position--;
                    }
                }
                l++;
                for (k = l; k < j; k++)
                {
                    int b = stream.ReadByte();
                    switch (b)
                    {
                    case 0:
                        k = j;
                        break;

                    case 1:
                        BriefingQuestions.PostMissAnswers[i] += "]";
                        break;

                    case 2:
                        BriefingQuestions.PostMissAnswers[i] += "[";
                        break;

                    case 10:
                        BriefingQuestions.PostMissAnswers[i] += "\r\n";
                        break;

                    case 255:
                        k = j;
                        break;

                    default:
                        BriefingQuestions.PostMissAnswers[i] += Convert.ToChar(b).ToString();
                        break;
                    }
                }
            }
            #endregion
            MissionPath = stream.Name;
        }