CnC_Remastered_Collection/TIBERIANDAWN/MISSION.CPP

475 lines
26 KiB
C++

//
// Copyright 2020 Electronic Arts Inc.
//
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
// software: you can redistribute it and/or modify it under the terms of
// the GNU General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
// in the hope that it will be useful, but with permitted additional restrictions
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
// distributed with this program. You should have received a copy of the
// GNU General Public License along with permitted additional restrictions
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
/* $Header: F:\projects\c&c\vcs\code\mission.cpv 2.18 16 Oct 1995 16:49:12 JOE_BOSTIC $ */
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Command & Conquer *
* *
* File Name : MISSION.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 23, 1994 *
* *
* Last Update : June 25, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* MissionClass::AI -- Processes order script. *
* MissionClass::Assign_Mission -- Give an order to a unit. *
* MissionClass::Commence -- Start script with new order. *
* MissionClass::Debug_Dump -- Dumps status values to mono screen. *
* MissionClass::Get_Mission -- Fetches the mission that this object is acting under. *
* MissionClass::MissionClass -- Default constructor for the mission object type. *
* MissionClass::Mission_From_Name -- Fetch order pointer from its name. *
* MissionClass::Mission_Name -- Converts a mission number into an ASCII string. *
* MissionClass::Overide_Mission -- temporarily overides the units mission *
* MissionClass::Restore_Mission -- Restores overidden mission *
* MissionClass::Set_Mission -- Sets the mission to the specified value. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* MissionClass::MissionClass -- Default constructor for the mission object type. *
* *
* This is the default constructor for the mission class object. It sets the mission *
* handler into a default -- do nothing -- state. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/23/1995 JLB : Created. *
*=============================================================================================*/
MissionClass::MissionClass(void)
{
Status = 0;
Timer = 0;
Mission = MISSION_NONE;
SuspendedMission = MISSION_NONE;
MissionQueue = MISSION_NONE;
}
int MissionClass::Mission_Sleep(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Ambush(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Attack(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Capture(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Guard(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Guard_Area(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Harvest(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Hunt(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Timed_Hunt(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Move(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Retreat(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Return(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Stop(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Unload(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Enter(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Construction(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Deconstruction(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Repair(void) {return TICKS_PER_SECOND*30;};
int MissionClass::Mission_Missile(void) {return TICKS_PER_SECOND*30;};
/***********************************************************************************************
* MissionClass::Set_Mission -- Sets the mission to the specified value. *
* *
* Use this routine to set the current mission for this object. This routine will blast *
* over the current mission, bypassing the queue method. Call it when the mission needs *
* to be changed immediately. *
* *
* INPUT: mission -- The mission to set to. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/23/1995 JLB : Created. *
*=============================================================================================*/
void MissionClass::Set_Mission(MissionType mission)
{
Mission = mission;
MissionQueue = MISSION_NONE;
}
/***********************************************************************************************
* MissionClass::Get_Mission -- Fetches the mission that this object is acting under. *
* *
* Use this routine to fetch the mission that this object is CURRENTLY acting under. The *
* mission queue may be filled with a immanent mission change, but this routine does not *
* consider that. It only returns the CURRENT mission. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the mission that this unit is currently following. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/23/1995 JLB : Created. *
*=============================================================================================*/
MissionType MissionClass::Get_Mission(void) const
{
return(Mission == MISSION_NONE ? MissionQueue : Mission);
}
#ifdef CHEAT_KEYS
/***********************************************************************************************
* MissionClass::Debug_Dump -- Dumps status values to mono screen. *
* *
* This is a debugging function that dumps this class' status to the monochrome screen *
* for review. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/28/1994 JLB : Created. *
*=============================================================================================*/
void MissionClass::Debug_Dump(MonoClass *mono) const
{
mono->Set_Cursor(21, 1);mono->Printf("%5.5s[%4.4s]", MissionClass::Mission_Name(Mission), MissionClass::Mission_Name(MissionQueue));
// mono->Text_Print(MissionClass::Mission_Name(Mission), 21, 1);
mono->Set_Cursor(20, 7);mono->Printf("%2d", (long)Timer);
mono->Set_Cursor(74, 1);mono->Printf("%2d", Status);
ObjectClass::Debug_Dump(mono);
}
#endif
/***********************************************************************************************
* MissionClass::AI -- Processes order script. *
* *
* This routine will process the order script for as much time as *
* possible or until a script delay is detected. This routine should *
* be called for every unit once per game loop (if possible). *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 04/23/1994 JLB : Created. *
* 06/25/1995 JLB : Added new missions. *
*=============================================================================================*/
void MissionClass::AI(void)
{
ObjectClass::AI();
/*
** This is the script AI equivalent processing.
*/
if (Timer.Expired() && Strength > 0) {
switch (Mission) {
default:
case MISSION_STICKY:
case MISSION_SLEEP:
Timer = Mission_Sleep();
break;
case MISSION_GUARD:
Timer = Mission_Guard();
break;
case MISSION_ENTER:
Timer = Mission_Enter();
break;
case MISSION_CONSTRUCTION:
Timer = Mission_Construction();
break;
case MISSION_DECONSTRUCTION:
Timer = Mission_Deconstruction();
break;
case MISSION_CAPTURE:
case MISSION_SABOTAGE:
Timer = Mission_Capture();
break;
case MISSION_MOVE:
Timer = Mission_Move();
break;
case MISSION_ATTACK:
Timer = Mission_Attack();
break;
case MISSION_RETREAT:
Timer = Mission_Retreat();
break;
case MISSION_HARVEST:
Timer = Mission_Harvest();
break;
case MISSION_GUARD_AREA:
Timer = Mission_Guard_Area();
break;
case MISSION_RETURN:
Timer = Mission_Return();
break;
case MISSION_STOP:
Timer = Mission_Stop();
break;
case MISSION_AMBUSH:
Timer = Mission_Ambush();
break;
case MISSION_HUNT:
case MISSION_RESCUE:
Timer = Mission_Hunt();
break;
case MISSION_TIMED_HUNT:
Timer = Mission_Timed_Hunt();
break;
case MISSION_UNLOAD:
Timer = Mission_Unload();
break;
case MISSION_REPAIR:
Timer = Mission_Repair();
break;
case MISSION_MISSILE:
Timer = Mission_Missile();
break;
}
}
}
/***********************************************************************************************
* MissionClass::Commence -- Start script with new order. *
* *
* This routine will start script processing according to any queued *
* order it may have. If there is no queued order, then this routine *
* does nothing. Call this routine whenever the unit is in a good *
* position to change its order (such as when it is stopped). *
* *
* INPUT: none *
* *
* OUTPUT: Did the mission actually change? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 04/23/1994 JLB : Created. *
* 07/14/1994 JLB : Simplified. *
* 06/17/1995 JLB : Returns success flag. *
*=============================================================================================*/
bool MissionClass::Commence(void)
{
if (MissionQueue != MISSION_NONE) {
Mission = MissionQueue;
MissionQueue = MISSION_NONE;
/*
** Force immediate state machine processing at the first state machine state value.
*/
Timer = 0;
Status = 0;
return(true);
}
return(false);
}
/***********************************************************************************************
* MissionClass::Assign_Mission -- Give an order to a unit. *
* *
* This assigns an order to a unit. It does NOT do the AI, but merely *
* flags the unit for normal AI processing. At that time the computer *
* will determine the unit's course of action. *
* *
* INPUT: order -- Mission to give the unit. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/04/1991 JLB : Created. *
* 04/15/1994 JLB : Converted to member function. *
*=============================================================================================*/
void MissionClass::Assign_Mission(MissionType order)
{
if (order == MISSION_NONE || Mission == order) return;
// Status = 0;
MissionQueue = order;
}
/***********************************************************************************************
* MissionClass::Mission_From_Name -- Fetch order pointer from its name. *
* *
* This routine is used to convert an ASCII order name into the actual *
* order number it represents. Typically, this is used when processing *
* a scenario INI file. *
* *
* INPUT: name -- The ASCII order name to process. *
* *
* OUTPUT: Returns with the actual order number that the ASCII name *
* represents. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 10/07/1992 JLB : Created. *
* 04/22/1994 JLB : Converted to static member function. *
*=============================================================================================*/
MissionType MissionClass::Mission_From_Name(char const *name)
{
MissionType order;
if (name) {
for (order = MISSION_FIRST; order < MISSION_COUNT; order++) {
if (stricmp(Missions[order], name) == 0) {
return(order);
}
}
}
return(MISSION_NONE);
}
/***********************************************************************************************
* MissionClass::Mission_Name -- Converts a mission number into an ASCII string. *
* *
* Use this routine to convert a mission number into the ASCII string that represents *
* it. Typical use of this is when generating an INI file. *
* *
* INPUT: mission -- The mission number to convert. *
* *
* OUTPUT: Returns with a pointer to the ASCII string that represents the mission type. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/23/1995 JLB : Created. *
*=============================================================================================*/
char const * MissionClass::Mission_Name(MissionType mission)
{
return(mission == MISSION_NONE ? "None" : Missions[mission]);
}
/***********************************************************************************************
* MissionClass::Override_Mission -- temporarily overides the units mission *
* *
* *
* *
* INPUT: MissionType mission - the mission we want to overide *
* TARGET tarcom - the new target we want to overide *
* TARGET navcom - the new navigation point to overide *
* *
* OUTPUT: none *
* *
* WARNINGS: If a mission is already overidden, the current mission is *
* just re-assigned. *
* *
* HISTORY: *
* 04/28/1995 PWG : Created. *
*=============================================================================================*/
void MissionClass::Override_Mission(MissionType mission, TARGET, TARGET)
{
if (MissionQueue != MISSION_NONE) {
SuspendedMission = MissionQueue;
} else {
SuspendedMission = Mission;
}
Assign_Mission(mission);
}
/***********************************************************************************************
* MissionClass::Restore_Mission -- Restores overidden mission *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 04/28/1995 PWG : Created. *
*=============================================================================================*/
bool MissionClass::Restore_Mission(void)
{
if (SuspendedMission != MISSION_NONE) {
Assign_Mission(SuspendedMission);
SuspendedMission= MISSION_NONE;
return(true);
}
return(false);
}
/***********************************************************************************************
** Unit order names. These names correspond to the player selectable orders
** a unit can have. The system initiated orders have no use for the ASCII name
** associated, but they are listed here for completeness sake.
*/
char const * MissionClass::Missions[MISSION_COUNT] = {
"Sleep",
"Attack",
"Move",
"Retreat",
"Guard",
"Sticky",
"Enter",
"Capture",
"Harvest",
"Area Guard",
"Return",
"Stop",
"Ambush",
"Hunt",
"Timed Hunt",
"Unload",
"Sabotage",
"Construction",
"Selling",
"Repair",
"Rescue",
"Missile",
};