예제 #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;
 }