/* ** Copyright (C) 1999 Microsoft Corporation. All Rights Reserved. ** ** File: Mission3.cpp ** ** Author: ** ** Description: ** Implementation of the first training mission ** ** History: */ #include "pch.h" #include "Mission3.h" #include "Training.h" #include "GoalList.h" #include "Predicate.h" #include "TrueCondition.h" #include "FalseCondition.h" #include "AndCondition.h" #include "OrCondition.h" #include "NotCondition.h" #include "PeriodicCondition.h" #include "ElapsedTimeCondition.h" #include "ObjectMovingTowardsCondition.h" #include "ObjectWithinRadiusCondition.h" #include "ObjectPointingAtCondition.h" #include "ConditionalAction.h" #include "ConditionList.h" #include "ActionList.h" #include "MessageAction.h" #include "PlaySoundAction.h" #include "SetCommandAction.h" #include "NoAction.h" #include "NTimesCondition.h" #include "EndMissionAction.h" #include "ResetAction.h" #include "ResetShipAction.h" #include "SoundFinishedCondition.h" #include "SetDisplayModeAction.h" #include "TurnShipAboutCondition.h" #include "GetRadarLODCondition.h" #include "SetRadarLODAction.h" #include "GetControlActiveCondition.h" #include "GetStateBitsCondition.h" #include "GetShipIsStoppedCondition.h" #include "GetShipIsDestroyedCondition.h" #include "SetControlConstraintsAction.h" #include "SetControlsAction.h" #include "GetAutopilotCondition.h" #include "SetAutopilotAction.h" #include "SetSignatureAction.h" #include "GetTargetCondition.h" #include "CommandAcknowledgedCondition.h" #include "GetCommandCondition.h" #include "ReleaseConsumerAction.h" #include "CreateProbeAction.h" #include "CreateWaypointAction.h" #include "SetHUDOverlayAction.h" #include "GetKeyCondition.h" #include "ProxyCondition.h" #include "TurnToAction.h" #include "ToggleWeaponAction.h" #include "SwapWeaponAction.h" #include "DoDamageAction.h" #include "CurrentTarget.h" #include "PlayerShipTarget.h" #include "RepairRearmAction.h" #include "ShowPaneAction.h" namespace Training { //------------------------------------------------------------------------------ // class methods //------------------------------------------------------------------------------ /* void */ Mission3::~Mission3 (void) { } //------------------------------------------------------------------------------ int Mission3::GetMissionID (void) { return c_TM_3_Basic_Weaponry; } //------------------------------------------------------------------------------ SectorID Mission3::GetStartSectorID (void) { return 1010; } //------------------------------------------------------------------------------ bool Mission3::RecordKeyPress (TrekKey key) { switch (key) { case TK_TargetCenter: if (trekClient.flyingF()) { IshipIGC* pShip = trekClient.GetShip (); const Orientation* pOrientation = &(pShip->GetOrientation()); ImodelIGC* pTarget = FindTarget ( pShip, c_ttFront | c_ttShip | c_ttEnemy, pShip->GetCommandTarget (c_cmdCurrent), NULL, NULL, pOrientation); GetWindow ()->SetTarget(pTarget, c_cidNone); } return false; case TK_SwapWeapon1: case TK_SwapWeapon2: case TK_SwapWeapon3: case TK_SwapWeapon4: case TK_SwapTurret1: case TK_SwapTurret2: case TK_SwapTurret3: case TK_SwapTurret4: case TK_SwapMissile: case TK_SwapChaff: case TK_SwapShield: case TK_SwapCloak: case TK_SwapAfterburner: case TK_SwapMine: case TK_NextCargo: case TK_ToggleWeapon1: case TK_ToggleWeapon2: case TK_ToggleWeapon3: case TK_ToggleWeapon4: case TK_DropCargo: case TK_Reload: case TK_ToggleGroupFire: case TK_PrevWeapon: case TK_NextWeapon: case TK_PrevPart: case TK_NextPart: case TK_MountPart: case TK_ReplacePart: case TK_UnmountPart: case TK_DropPart: { // only allow if the inventory pane is up TrekWindow* pWindow = GetWindow (); if (pWindow->GetOverlayFlags () bit_and ofInventory) return true; return false; } } return TrainingMission::RecordKeyPress (key); } //------------------------------------------------------------------------------ bool Mission3::ShipLanded (void) { Terminate (); return false; } //------------------------------------------------------------------------------ void Mission3::CreateUniverse (void) { LoadUniverse ("training_1", 414, 1010); // a fighter 3 // stuff for setup ImissionIGC* pCore = trekClient.GetCore(); Time now = pCore->GetLastUpdate(); IshipIGC* pShip = trekClient.GetShip(); ImodelIGC* pStation = pCore->GetModel (OT_station, 1010); // take one of the guns off the ship IpartIGC* pPart = pShip->GetMountedPart (ET_Weapon, 0); if (pPart) pPart->Terminate (); // put an anti-shield weapon on the ship AddPartToShip (92, 0, 0); // take the missiles off the ship pPart = pShip->GetMountedPart (ET_Magazine, 0); if (pPart) pPart->Terminate (); // activate only the starting weapon trekClient.SetSelectedWeapon (0); trekClient.fGroupFire = false; // set a global attribute to reduce overall energy of ship IsideIGC* pSide = pShip->GetSide (); GlobalAttributeSet gas = pSide->GetGlobalAttributeSet (); gas.SetAttribute (c_gaMaxEnergy, 0.25f); pSide->SetGlobalAttributeSet (gas); // put the commander ship in the station IshipIGC* pCommander = pCore->GetShip (m_commanderID); pCommander->SetStation (static_cast (pStation)); pCommander->SetCommand (c_cmdAccepted, NULL, c_cidDoNothing); pCommander->SetCommand (c_cmdCurrent, NULL, c_cidDoNothing); pCommander->SetAutopilot (false); // create a bunch of derelict hulls in a sphere around the ship // at about 200m to 450m distance Vector direction (1.0f, 0.0f, 0.0f); for (int i = 0; i < TM_NUMBER_OF_DERELICTS; i++) { float fRadius = 200.0f + (static_cast (i) * 25.0f); Vector newPosition = direction * fRadius; HullID hullID; switch (randomInt (0, 2)) { case 0: hullID = 800; break; case 1: case 2: hullID = 801; break; } char name[32]; sprintf (name, "Derelict %02d", i + 1); m_derelict_hulls[i] = pCore->GenerateNewShipID (); IshipIGC* pShip = CreateDrone (name, m_derelict_hulls[i], hullID, 1, c_ptPlayer); pShip->SetAutopilot (false); pShip->SetPosition (newPosition); // XXX I hope this works out - if a random vector is generated that is the same as direction, we're in trouble pShip->SetOrientation (Orientation (pShip->GetOrientation ().GetForward (), direction * -1.0f)); pShip->SetCluster (pCore->GetCluster(1010)); direction = Vector::RandomDirection (); } } //------------------------------------------------------------------------------ Condition* Mission3::CreateMission (void) { // create the goal and the goal list GoalList* pGoalList = new GoalList; Goal* pGoal = new Goal (pGoalList); // put a constraint that will point the back in if it's more than 7500m from the base ImodelIGC* pShip = static_cast (trekClient.GetShip ()); TurnToAction* pTurnToAction = new TurnToAction (pShip, OT_station, 1010); ObjectWithinRadiusCondition* pObjectWithinRadiusCondition = new ObjectWithinRadiusCondition (pShip, OT_station, 1010, 7500.0f); ObjectWithinRadiusCondition* pObjectWithinRadiusCondition2 = new ObjectWithinRadiusCondition (pShip, OT_station, 1010, 7000.0f); ConditionalAction* pConditionalAction = new ConditionalAction (new NotCondition (pObjectWithinRadiusCondition), pTurnToAction); ConditionalAction* pConditionalAction2 = new ConditionalAction (new AndCondition (new NotCondition (pObjectWithinRadiusCondition2), new ProxyCondition (pObjectWithinRadiusCondition)), new SetControlsAction); pGoal->AddConstraintCondition (pConditionalAction); pGoal->AddConstraintCondition (pConditionalAction2); // add the subgoals pGoalList->AddGoal (CreateGoal01 ()); pGoalList->AddGoal (CreateGoal02 ()); pGoalList->AddGoal (CreateGoal03 ()); pGoalList->AddGoal (CreateGoal04 ()); pGoalList->AddGoal (CreateGoal05 ()); pGoalList->AddGoal (CreateGoal06 ()); pGoalList->AddGoal (CreateGoal07 ()); pGoalList->AddGoal (CreateGoal08 ()); pGoalList->AddGoal (CreateGoal09 ()); pGoalList->AddGoal (CreateGoal10 ()); pGoalList->AddGoal (CreateGoal11 ()); pGoalList->AddGoal (CreateGoal12 ()); pGoalList->AddGoal (CreateGoal13 ()); // return the goal return pGoal; } //------------------------------------------------------------------------------ Condition* Mission3::CreateGotTargetCondition (void) { // generate the array of leaf conditions and fill it in Condition* pTargetCondition[TM_NUMBER_OF_DERELICTS]; for (int i = 0; i < TM_NUMBER_OF_DERELICTS; i++) pTargetCondition[i] = new GetTargetCondition (trekClient.GetShip(), OT_ship, m_derelict_hulls[i]); // walk the array of leaf conditions pairing them using Or conditions Condition* pTmpCondition = pTargetCondition[0]; for (i = 1; i < TM_NUMBER_OF_DERELICTS; i++) pTmpCondition = new OrCondition (pTmpCondition, pTargetCondition[i]); // return the last Or condition generated return pTmpCondition; } //------------------------------------------------------------------------------ Goal* Mission3::CreateGoal01 (void) { GoalList* pGoalList = new GoalList; // play the introductory audio { Goal* pGoal = CreatePlaySoundGoal (salCommenceScanSound); SetControlConstraintsAction* pSetControlConstraintsAction = new SetControlConstraintsAction; pSetControlConstraintsAction->DisableInputAction (0xffffffff ^ selectedWeaponMaskIGC); pSetControlConstraintsAction->ScaleInputControl (c_axisYaw, 0.0f); pSetControlConstraintsAction->ScaleInputControl (c_axisPitch, 0.0f); pSetControlConstraintsAction->ScaleInputControl (c_axisRoll, 0.0f); pSetControlConstraintsAction->ScaleInputControl (c_axisThrottle, 0.0f); pGoal->AddStartAction (pSetControlConstraintsAction); pGoalList->AddGoal (pGoal); } // wait two seconds pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (2.0f))); // tm_3_01 // This ship is a fighter. It is well armed and has a moderate // scan range. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_01Sound)); // wait one second, zoom into ship { Goal* pGoal = new Goal (new ElapsedTimeCondition (1.0f)); pGoal->AddStartAction (new SetDisplayModeAction (TrekWindow::cmCockpit)); pGoalList->AddGoal (pGoal); } // tm_3_02 // In this mission, we're going to go over targeting with the // peripheral radar and the weapon systems carried by your // ships. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_02Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_03 // As before, your controls will be disabled until I ask you // to do something, so listen carefully. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_03Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); return new Goal (pGoalList); } //------------------------------------------------------------------------------ Goal* Mission3::CreateGoal02 (void) { GoalList* pGoalList = new GoalList; // tm_3_04 // First, notice the two gauges in the center of your heads-up // display: the shield and armor gauges. These gauges indicate // the relative health of your craft. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_04Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_05 // The shield gauge shows how much damage the shields can // absorb before you will start taking armor damage. Shields // can regenerate, so it's not a disaster if this gauge shows // that your shields are offline. When you take shield damage, // it will look like this. { Goal* pGoal = CreatePlaySoundGoal (tm_3_05Sound); pGoal->AddStartAction (new SetHUDOverlayAction (ShieldTrainingOverlay)); pGoalList->AddGoal (pGoal); } // wait one second and show shield damage { Goal* pGoal = new Goal (new ElapsedTimeCondition (1.0f)); pGoal->AddConstraintCondition (new ConditionalAction (new TrueCondition, new DoDamageAction (false))); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_06 // Now notice that the shield regenerates. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_06Sound)); // wait four seconds pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (4.0f))); // tm_3_07 // The armor gauge shows how much more damage your ship hull // can withstand before breaking apart. If this gauge drops to // 0, you will explode˙. This is what it will look like when // you take armor damage. { Goal* pGoal = CreatePlaySoundGoal (tm_3_07Sound); pGoal->AddStartAction (new SetHUDOverlayAction (HullTrainingOverlay)); pGoalList->AddGoal (pGoal); } // wait one second and show hull damage { Goal* pGoal = new Goal (new ElapsedTimeCondition (1.0f)); pGoal->AddConstraintCondition (new ConditionalAction (new TrueCondition, new DoDamageAction (true))); pGoalList->AddGoal (pGoal); } // wait one and a half seconds pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (1.5f))); // tm_3_08 // Notice that the armor does not regenerate. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_08Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_09 // If you're in a battle and you get damaged, try to return to // the nearest friendly station for repairs or search for a // shield and armor power-up. { Goal* pGoal = CreatePlaySoundGoal (tm_3_09Sound); pGoal->AddStartAction (new SetHUDOverlayAction (NoTrainingOverlay)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); return new Goal (pGoalList); } //------------------------------------------------------------------------------ Goal* Mission3::CreateGoal03 (void) { GoalList* pGoalList = new GoalList; // tm_3_10 // There are a number of derelict hulls in this sector of // space. We'll use these for target practice. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_10Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_11 // As your first introduction to targeting, you're going to // learn to target objects in front of the craft. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_11Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_11r // Press the C key to target objects nearest to the center of // your display. { Goal *pGoal = new Goal (CreateGotTargetCondition ()); pGoal->AddStartAction (new MessageAction ("Press the C key to target the derelict hull nearest the center of your display.")); pGoal->AddStartAction (new PlaySoundAction (tm_3_11rSound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_11Sound)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_12 // Good! I'm enabling your flight controls now. Practice // turning and targeting the derelict hulls with the C key. { Goal* pGoal = CreatePlaySoundGoal (tm_3_12Sound); SetControlConstraintsAction* pSetControlConstraintsAction = new SetControlConstraintsAction; pSetControlConstraintsAction->ScaleInputControl (c_axisYaw, 1.0f); pSetControlConstraintsAction->ScaleInputControl (c_axisPitch, 1.0f); pSetControlConstraintsAction->ScaleInputControl (c_axisRoll, 1.0f); pGoal->AddStartAction (pSetControlConstraintsAction); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_12r // When you are comfortable with targeting, press the SPACEBAR // to proceed. { Goal* pGoal = new Goal (new GetKeyCondition (TK_FireWeapon)); pGoal->AddStartAction (new MessageAction ("Press the SPACEBAR when you are ready to proceed.")); pGoal->AddStartAction (new PlaySoundAction (tm_3_12rSound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_12rSound)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); return new Goal (pGoalList); } //------------------------------------------------------------------------------ Goal* Mission3::CreateGoal04 (void) { GoalList* pGoalList = new GoalList; // tm_3_13 // All ships have a scan range, within which you can detect // the presence of other objects. Some ships, like the // interceptor we flew in the first mission, have a very poor // range. These ships are not very good in unexplored space // because an enemy can sneak up on them quite easily. // However, if a friendly ship can see something in its scan // range, you can too. It's always handy to have a scout or // two around when you're in uncharted regions, because they // have a very large scan range. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_13Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // XXX target something if there isn't a target? // tm_3_14 // Now examine the portion of your heads-up display that shows // a detail of the target. Notice that this area displays the // shield and armor strength of your target, as well as its // velocity and range. { Goal* pGoal = CreatePlaySoundGoal (tm_3_14Sound); pGoal->AddStartAction (new SetHUDOverlayAction (TargetTrainingOverlay)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_15 // Press the SPACEBAR when you are ready to proceed. { Goal* pGoal = new Goal (new GetKeyCondition (TK_FireWeapon)); pGoal->AddStartAction (new MessageAction ("Press the SPACEBAR when you are ready to proceed.")); pGoal->AddStartAction (new PlaySoundAction (tm_3_15Sound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_15Sound)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); return new Goal (pGoalList); } //------------------------------------------------------------------------------ Goal* Mission3::CreateGoal05 (void) { GoalList* pGoalList = new GoalList; // tm_3_16 // When you target an enemy craft, you will see an aiming // reticule in the center of your display. This reticule will // be green when you are in range and aiming at the target. If // you are not aiming correctly, or you are not in range, the // reticule will be gray. Your ship will now turn to show you // this effect. { Goal* pGoal = CreatePlaySoundGoal (tm_3_16Sound); pGoal->AddStartAction (new SetHUDOverlayAction (ReticuleTrainingOverlay)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // turn the craft until it lines up { ObjectPointingAtCondition* pObjectPointingAtCondition = new ObjectPointingAtCondition (static_cast (trekClient.GetShip ()), new CurrentTarget (new PlayerShipTarget)); Goal* pGoal = new Goal (pObjectPointingAtCondition); pObjectPointingAtCondition->SetMinimumAngle (1.0f); TurnToAction* pTurnToAction = new TurnToAction (trekClient.GetShip (), new CurrentTarget (new PlayerShipTarget)); ConditionalAction* pConditionalAction = new ConditionalAction (new TrueCondition, pTurnToAction); pGoal->AddConstraintCondition (pConditionalAction); pGoalList->AddGoal (pGoal); } // wait half second, and turn to the right { Goal* pGoal = new Goal (new ElapsedTimeCondition (0.5f)); SetControlsAction* pSetControlsAction = new SetControlsAction; pSetControlsAction->SetInputControl (c_axisYaw, -0.5f); pGoal->AddStartAction (pSetControlsAction); pGoalList->AddGoal (pGoal); } // turn the craft until it lines up { ObjectPointingAtCondition* pObjectPointingAtCondition = new ObjectPointingAtCondition (static_cast (trekClient.GetShip ()), new CurrentTarget (new PlayerShipTarget)); Goal* pGoal = new Goal (pObjectPointingAtCondition); pObjectPointingAtCondition->SetMinimumAngle (1.0f); TurnToAction* pTurnToAction = new TurnToAction (trekClient.GetShip (), new CurrentTarget (new PlayerShipTarget)); ConditionalAction* pConditionalAction = new ConditionalAction (new TrueCondition, pTurnToAction); pGoal->AddConstraintCondition (pConditionalAction); pGoalList->AddGoal (pGoal); } // wait half second, and reset the controls { Goal* pGoal = new Goal (new ElapsedTimeCondition (0.5f)); SetControlsAction* pSetControlsAction = new SetControlsAction; pGoal->AddStartAction (pSetControlsAction); pGoalList->AddGoal (pGoal); } // tm_3_17 // Okay. There are basically three weapon types: weapons that // use energy, weapons that use ammunition, and missiles. Your // craft is currently armed with all three. To start with, // only the energy-based weapon is activated. { Goal* pGoal = CreatePlaySoundGoal (tm_3_17Sound); pGoal->AddStartAction (new SetHUDOverlayAction (NoTrainingOverlay)); pGoalList->AddGoal (pGoal); } // wait half second { Goal* pGoal = new Goal (new ElapsedTimeCondition (0.5f)); SetControlConstraintsAction* pSetControlConstraintsAction = new SetControlConstraintsAction; pSetControlConstraintsAction->EnableInputAction (weaponsMaskIGC); pGoal->AddStartAction (pSetControlConstraintsAction); pGoalList->AddGoal (pGoal); } // wait for weapons to fire { Goal* pGoal = new Goal (new GetStateBitsCondition (trekClient.GetShip(), weaponsMaskIGC)); if (GetWindow ()->GetInputEngine ()->GetJoystickCount () > 0) { // tm_3_18 // Press the trigger button on your joystick to fire your main // weapon. pGoal->AddStartAction (new PlaySoundAction (tm_3_18Sound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_18Sound)); pGoal->AddStartAction (new MessageAction ("Fire the main weapon by pressing the trigger button on your joystick.")); } else { // tm_3_19 // Press the SPACEBAR on the keyboard to fire your main weapon. pGoal->AddStartAction (new PlaySoundAction (tm_3_19Sound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_19Sound)); pGoal->AddStartAction (new MessageAction ("Fire the main weapon by pressing the SPACEBAR.")); } pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_20 // Good! pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_20Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); return new Goal (pGoalList); } //------------------------------------------------------------------------------ Goal* Mission3::CreateGoal06 (void) { GoalList* pGoalList = new GoalList; // tm_3_21 // Notice the energy gauge on your heads-up display. This // gauge shows how much energy is available to power your gun. // As you fire, energy is used up. This gauge shows you how // much energy remains. { Goal* pGoal = CreatePlaySoundGoal (tm_3_21Sound); pGoal->AddStartAction (new SetHUDOverlayAction (EnergyTrainingOverlay)); /* SetControlsAction* pSetControlsAction = new SetControlsAction; pSetControlsAction->SetInputAction (oneWeaponIGC); pGoal->AddStartAction (pSetControlsAction); */ pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_22 // One benefit of using energy-based weapons is that the // energy available to your ship will recharge. In effect, you // never run out. { Goal* pGoal = CreatePlaySoundGoal (tm_3_22Sound); /* SetControlsAction* pSetControlsAction = new SetControlsAction; pGoal->AddStartAction (pSetControlsAction); */ pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_23 // Notice how the shield and armor strength of your target are // affected. { Goal* pGoal = CreatePlaySoundGoal (tm_3_23Sound); pGoal->AddStartAction (new SetHUDOverlayAction (TargetTrainingOverlay)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_23r // Keep firing until your target is destroyed. { Goal* pGoal = new Goal (new GetShipIsDestroyedCondition (new CurrentTarget (new PlayerShipTarget, true))); pGoal->AddStartAction (new MessageAction ("Destroy current target.")); pGoal->AddStartAction (new PlaySoundAction (tm_3_23rSound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_23rSound)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_24 // Great. As you can see, stationary objects are easy // pickings. { Goal* pGoal = CreatePlaySoundGoal (tm_3_24Sound); pGoal->AddStartAction (new SetHUDOverlayAction (NoTrainingOverlay)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); return new Goal (pGoalList); } //------------------------------------------------------------------------------ Goal* Mission3::CreateGoal07 (void) { GoalList* pGoalList = new GoalList; // tm_3_25 // Notice that your radar has targeted another derelict hull. // Whenever an item that you have targeted goes away, the // radar will automatically target the next item of the same // type. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_25Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_26 // You can selectively target the nearest friendly craft and // the nearest enemy craft. To target the nearest enemy, press // the E key. To target the nearest friendly object, press the // F key. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_26Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_27 // Select a new target now using the E key. { Goal* pGoal = new Goal (new GetKeyCondition (TK_TargetEnemy)); pGoal->AddStartAction (new MessageAction ("Target an enemy using the E key.")); pGoal->AddStartAction (new PlaySoundAction (tm_3_27Sound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_27Sound)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_28 // Notice your radar. The targeted object has a set of square // brackets around it, and there is a red arrow near the // center of your display that points at the target. You can // use this information to help you locate your target in // space. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_28Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_29 // Turn to face your new target. { ObjectPointingAtCondition* pObjectPointingAtCondition = new ObjectPointingAtCondition (static_cast (trekClient.GetShip ()), new CurrentTarget (new PlayerShipTarget)); Goal* pGoal = new Goal (pObjectPointingAtCondition); pGoal->AddStartAction (new PlaySoundAction (tm_3_29Sound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_29Sound)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_30 // Excellent! You're getting the hang of this! pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_30Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); return new Goal (pGoalList); } //------------------------------------------------------------------------------ Goal* Mission3::CreateGoal08 (void) { GoalList* pGoalList = new GoalList; // tm_3_31 // I am activating your machine gun now. { Goal* pGoal = CreatePlaySoundGoal (tm_3_31Sound); pGoal->AddStartAction (new ToggleWeaponAction (1)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_31r // Go ahead and fire. { Goal* pGoal = new Goal (new GetStateBitsCondition (trekClient.GetShip(), weaponsMaskIGC)); if (GetWindow ()->GetInputEngine ()->GetJoystickCount () > 0) pGoal->AddStartAction (new MessageAction ("Fire the main weapon by pressing the trigger button on your joystick.")); else pGoal->AddStartAction (new MessageAction ("Fire the main weapon by pressing the SPACEBAR.")); pGoal->AddStartAction (new PlaySoundAction (tm_3_31rSound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_31rSound)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_32 // Good! pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_32Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_33 // The machine gun uses ammunition. This gauge shows how much // ammunition remains. Note that the ammunition is not // recharged until you land again, so watch your supply. { Goal* pGoal = CreatePlaySoundGoal (tm_3_33Sound); pGoal->AddStartAction (new SetHUDOverlayAction (AmmoTrainingOverlay)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_34 // Blow up your target with the machine guns.˙ { Goal* pGoal = new Goal (new GetShipIsDestroyedCondition (new CurrentTarget (new PlayerShipTarget, true))); pGoal->AddStartAction (new MessageAction ("Destroy current target.")); pGoal->AddStartAction (new PlaySoundAction (tm_3_34Sound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_34Sound)); pGoal->AddStartAction (new SetHUDOverlayAction (NoTrainingOverlay)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_35 // Now turn to face the next targeted derelict hull. { ObjectPointingAtCondition* pObjectPointingAtCondition = new ObjectPointingAtCondition (static_cast (trekClient.GetShip ()), new CurrentTarget (new PlayerShipTarget)); Goal* pGoal = new Goal (pObjectPointingAtCondition); pGoal->AddStartAction (new PlaySoundAction (tm_3_35Sound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_35Sound)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); return new Goal (pGoalList); } //------------------------------------------------------------------------------ Goal* Mission3::CreateGoal09 (void) { GoalList* pGoalList = new GoalList; // tm_3_36 // Perfect! I'm going to load a missile launcher from cargo. // When the load is complete, you will see a new set of // brackets around this target. These brackets indicate the // quality of the lock you have on your target. When the lock // is perfect, you will hear a special sound. Missiles will // turn to follow targets when they have a lock, so you don't // need to shoot quite as straight. { Goal* pGoal = CreatePlaySoundGoal (tm_3_36Sound); pGoal->AddStartAction (new SwapWeaponAction (ET_Magazine, 0)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // wait for missilies to fire { Goal* pGoal = new Goal (new GetStateBitsCondition (trekClient.GetShip(), missileFireIGC)); if (GetWindow ()->GetInputEngine ()->GetJoystickCount () > 0) { // tm_3_37 // Fire your missiles by pressing button 2 on your joystick. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_37Sound)); pGoal->AddStartAction (new MessageAction ("Fire missiles by pressing the #2 button on your joystick.")); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_37Sound)); } else { // tm_3_38 // Fire your missiles by pressing CONTROL plus SPACEBAR on the // keyboard. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_38Sound)); pGoal->AddStartAction (new MessageAction ("Fire missiles by pressing CTRL+SPACEBAR.")); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_38Sound)); } SetControlConstraintsAction* pSetControlConstraintsAction = new SetControlConstraintsAction; pSetControlConstraintsAction->EnableInputAction (missileFireIGC); pGoal->AddStartAction (pSetControlConstraintsAction); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_39 // Watch how these affect the target! pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_39Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_23r // Keep firing until your target is destroyed. { Goal* pGoal = new Goal (new GetShipIsDestroyedCondition (new CurrentTarget (new PlayerShipTarget, true))); pGoal->AddStartAction (new MessageAction ("Destroy current target.")); pGoal->AddStartAction (new PlaySoundAction (tm_3_23rSound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_23rSound)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_40 // Good job. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_40Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); return new Goal (pGoalList); } //------------------------------------------------------------------------------ Goal* Mission3::CreateGoal10 (void) { GoalList* pGoalList = new GoalList; // tm_3_41 // This is the Inventory display. I?ve been using your // inventory controls to enable and disable weapons and to // load missiles from cargo. You can do this yourself by // pressing the corresponding number keys to enable or disable // the items and CONTROL plus the number keys to shift items // to and from cargo. { Goal* pGoal = CreatePlaySoundGoal (tm_3_41Sound); pGoal->AddStartAction (new ShowPaneAction (ofInventory)); pGoal->AddStartAction (new SetHUDOverlayAction (InventoryTrainingOverlay)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_42 // Check that out and make sure you are comfortable with it. { Goal* pGoal = CreatePlaySoundGoal (tm_3_42Sound); pGoal->AddStartAction (new SetHUDOverlayAction (NoTrainingOverlay)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_42r // Press the END key when you are ready to proceed. { Goal* pGoal = new Goal (new GetKeyCondition (TK_CommandFinishTM)); pGoal->AddStartAction (new MessageAction ("Press the END key when you are comfortable with the Inventory Display.")); pGoal->AddStartAction (new PlaySoundAction (tm_3_42rSound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_42rSound)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_43 // One more thing you?ll need to know about is your craft?s // kill bonus. { Goal* pGoal = CreatePlaySoundGoal (tm_3_43Sound); pGoal->AddStartAction (new SetHUDOverlayAction (KillBonusTrainingOverlay)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_44 // This number represents the percentage of extra damage your // craft is doing against enemies. This number will increase // every time you get a kill but will drop back to 0 every // time you die. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_44Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); return new Goal (pGoalList); } //------------------------------------------------------------------------------ Goal* Mission3::CreateGoal11 (void) { GoalList* pGoalList = new GoalList; // tm_3_45 // You've done well, Cadet! Here?s a chance to put your // learning to the test ? I'm going to give you a full load of // ammo and missiles now and enable all your controls. Fly // around the derelicts and destroy them, use your targeting // keys, throttle, and missiles. { Goal* pGoal = CreatePlaySoundGoal (tm_3_45Sound); SetControlConstraintsAction* pSetControlConstraintsAction = new SetControlConstraintsAction; pSetControlConstraintsAction->EnableInputAction (0xffffffff); pSetControlConstraintsAction->ScaleInputControl (c_axisThrottle, 1.0f); pGoal->AddStartAction (new SetHUDOverlayAction (NoTrainingOverlay)); pGoal->AddStartAction (pSetControlConstraintsAction); pGoal->AddStartAction (new ToggleWeaponAction (1)); pGoal->AddStartAction (new RepairRearmAction); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_46 // When you are ready to go home, press the END key. { Goal* pGoal = new Goal (new GetKeyCondition (TK_CommandFinishTM)); pGoal->AddStartAction (new MessageAction ("Press the END key when you are ready to go home.")); pGoal->AddStartAction (new PlaySoundAction (tm_3_46Sound)); pGoal->AddConstraintCondition (CreateTooLongCondition (120.0f, tm_3_46Sound)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); return new Goal (pGoalList); } //------------------------------------------------------------------------------ Goal* Mission3::CreateGoal12 (void) { GoalList* pGoalList = new GoalList; // tm_3_47 // All right, you are going to land the ship yourself this // time, Cadet. Remember what I told you about landing in the // green bays. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_47Sound)); // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); // tm_3_48 // Press the B key to target your nearest base. { Goal* pGoal = new Goal (new GetTargetCondition (trekClient.GetShip(), OT_station, 1010)); pGoal->AddStartAction (new MessageAction ("Press the B key to target the outpost.")); pGoal->AddStartAction (new PlaySoundAction (tm_3_48Sound)); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_48Sound)); pGoalList->AddGoal (pGoal); } // wait half second pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f))); return new Goal (pGoalList); } //------------------------------------------------------------------------------ Goal* Mission3::CreateGoal13 (void) { GoalList* pGoalList = new GoalList; // tm_3_49 // Good! Fly toward the base, and locate and land in a green // hangar. It might help if you fly close to the base, then // stop and line yourself up with the bay. That's how // autopilot works. pGoalList->AddGoal (CreatePlaySoundGoal (tm_3_49Sound)); // tm_3_49r // Land the ship in a green hangar bay to complete the mission. { Goal* pGoal = new Goal (new FalseCondition); pGoal->AddStartAction (new MessageAction ("Land in a green hangar to complete the mission.")); pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_3_49rSound)); pGoalList->AddGoal (pGoal); } return new Goal (pGoalList); } //------------------------------------------------------------------------------ }