239 lines
9.8 KiB
C
239 lines
9.8 KiB
C
/*
|
|
** Command & Conquer Generals(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program 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.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// (c) 2001-2003 Electronic Arts Inc. //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ModelState.h
|
|
// Basic data types needed for the game engine. This is an extension of BaseType.h.
|
|
// Author: Michael S. Booth, April 2001
|
|
|
|
#pragma once
|
|
|
|
#ifndef _ModelState_H_
|
|
#define _ModelState_H_
|
|
|
|
#include "Lib/BaseType.h"
|
|
#include "Common/INI.h"
|
|
#include "Common/BitFlags.h"
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
THE PROBLEM
|
|
-----------
|
|
|
|
-- there are lots of different states. (consider that structures can be: day/night, snow/nosnow,
|
|
powered/not, garrisoned/empty, damaged/not... you do the math.)
|
|
|
|
-- some states are mutually exclusive (idle vs. moving), others are not (snow/nosnow, day/night).
|
|
generally, humanoid units have mostly the former, while structure units have mostly the latter.
|
|
The current ModelState system really only supports the mutually-exclusive states well.
|
|
|
|
-- we'd rather not have to specify every state in the INI files, BUT we do want to be able
|
|
to intelligently choose the best model for a given state, whether or not a "real" state exists for it.
|
|
|
|
-- it would be desirable to have a unified way of representing "ModelState" so that we don't
|
|
have multiple similar-yet-different systems.
|
|
|
|
YUCK, WHAT NOW
|
|
--------------
|
|
|
|
Let's represent the Model State with two dictinct pieces:
|
|
|
|
-- an "ActionState" piece, representing the mutually-exclusive states, which are almost
|
|
always an action of some sort
|
|
|
|
-- and a "ConditionState" piece, which is a set of bitflags to indicate the static "condition"
|
|
of the model.
|
|
|
|
Note that these are usually set independently in code, but they are lumped together in order to
|
|
determine the actual model to be used.
|
|
|
|
(Let's require all objects would be required to have an "Idle" ActionState, which is the
|
|
normal, just-sitting there condition.)
|
|
|
|
From a code point of view, this becomes an issue of requesting a certain state, and
|
|
finding the best-fit match for it. So, what are the rules for finding a good match?
|
|
|
|
-- Action states must match exactly. If the desired action state is not found, then the
|
|
IDLE state is substituted (but this should generally be considered an error condition).
|
|
|
|
-- Condition states choose the match with the closest match among the "Condition" bits in the
|
|
INI file, based on satisfying the most of the "required" conditions and the fewest of the
|
|
"forbidden" conditions.
|
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
// IMPORTANT NOTE: you should endeavor to set up states such that the most "normal"
|
|
// state is defined by the bit being off. That is, the typical "normal" condition
|
|
// has all condition flags set to zero.
|
|
enum ModelConditionFlagType
|
|
{
|
|
MODELCONDITION_INVALID = -1,
|
|
|
|
MODELCONDITION_FIRST = 0,
|
|
|
|
//
|
|
// Note: these values are saved in save files, so you MUST NOT REMOVE OR CHANGE
|
|
// existing values!
|
|
//
|
|
MODELCONDITION_TOPPLED = MODELCONDITION_FIRST,
|
|
MODELCONDITION_FRONTCRUSHED,
|
|
MODELCONDITION_BACKCRUSHED,
|
|
MODELCONDITION_DAMAGED,
|
|
MODELCONDITION_REALLY_DAMAGED,
|
|
MODELCONDITION_RUBBLE,
|
|
MODELCONDITION_SPECIAL_DAMAGED,
|
|
MODELCONDITION_NIGHT,
|
|
MODELCONDITION_SNOW,
|
|
MODELCONDITION_PARACHUTING,
|
|
MODELCONDITION_GARRISONED,
|
|
MODELCONDITION_ENEMYNEAR,
|
|
MODELCONDITION_WEAPONSET_VETERAN,
|
|
MODELCONDITION_WEAPONSET_ELITE,
|
|
MODELCONDITION_WEAPONSET_HERO,
|
|
MODELCONDITION_WEAPONSET_CRATEUPGRADE_ONE,
|
|
MODELCONDITION_WEAPONSET_CRATEUPGRADE_TWO,
|
|
MODELCONDITION_WEAPONSET_PLAYER_UPGRADE,
|
|
MODELCONDITION_DOOR_1_OPENING,
|
|
MODELCONDITION_DOOR_1_CLOSING,
|
|
MODELCONDITION_DOOR_1_WAITING_OPEN,
|
|
MODELCONDITION_DOOR_1_WAITING_TO_CLOSE,
|
|
MODELCONDITION_DOOR_2_OPENING,
|
|
MODELCONDITION_DOOR_2_CLOSING,
|
|
MODELCONDITION_DOOR_2_WAITING_OPEN,
|
|
MODELCONDITION_DOOR_2_WAITING_TO_CLOSE,
|
|
MODELCONDITION_DOOR_3_OPENING,
|
|
MODELCONDITION_DOOR_3_CLOSING,
|
|
MODELCONDITION_DOOR_3_WAITING_OPEN,
|
|
MODELCONDITION_DOOR_3_WAITING_TO_CLOSE,
|
|
MODELCONDITION_DOOR_4_OPENING,
|
|
MODELCONDITION_DOOR_4_CLOSING,
|
|
MODELCONDITION_DOOR_4_WAITING_OPEN,
|
|
MODELCONDITION_DOOR_4_WAITING_TO_CLOSE,
|
|
MODELCONDITION_ATTACKING, //Simply set when a unit is fighting -- terrorist moving with a target will flail arms like a psycho.
|
|
MODELCONDITION_PREATTACK_A, //Use for pre-attack animations (like aiming, pulling out a knife, or detonating explosives).
|
|
MODELCONDITION_FIRING_A,
|
|
MODELCONDITION_BETWEEN_FIRING_SHOTS_A,
|
|
MODELCONDITION_RELOADING_A,
|
|
MODELCONDITION_PREATTACK_B, //Use for pre-attack animations (like aiming, pulling out a knife, or detonating explosives).
|
|
MODELCONDITION_FIRING_B,
|
|
MODELCONDITION_BETWEEN_FIRING_SHOTS_B,
|
|
MODELCONDITION_RELOADING_B,
|
|
MODELCONDITION_PREATTACK_C, //Use for pre-attack animations (like aiming, pulling out a knife, or detonating explosives).
|
|
MODELCONDITION_FIRING_C,
|
|
MODELCONDITION_BETWEEN_FIRING_SHOTS_C,
|
|
MODELCONDITION_RELOADING_C,
|
|
MODELCONDITION_TURRET_ROTATE,
|
|
MODELCONDITION_POST_COLLAPSE,
|
|
MODELCONDITION_MOVING,
|
|
MODELCONDITION_DYING,
|
|
MODELCONDITION_AWAITING_CONSTRUCTION,
|
|
MODELCONDITION_PARTIALLY_CONSTRUCTED,
|
|
MODELCONDITION_ACTIVELY_BEING_CONSTRUCTED,
|
|
MODELCONDITION_PRONE,
|
|
MODELCONDITION_FREEFALL,
|
|
MODELCONDITION_ACTIVELY_CONSTRUCTING,
|
|
MODELCONDITION_CONSTRUCTION_COMPLETE,
|
|
MODELCONDITION_RADAR_EXTENDING,
|
|
MODELCONDITION_RADAR_UPGRADED,
|
|
MODELCONDITION_PANICKING, // yes, it's spelled with a "k". look it up.
|
|
MODELCONDITION_AFLAME,
|
|
MODELCONDITION_SMOLDERING,
|
|
MODELCONDITION_BURNED,
|
|
MODELCONDITION_DOCKING, ///< This encloses the whole time you are Entering, Actioning, and Exiting a dock
|
|
MODELCONDITION_DOCKING_BEGINNING, ///< From Enter to Action
|
|
MODELCONDITION_DOCKING_ACTIVE, ///< From Action to Exit
|
|
MODELCONDITION_DOCKING_ENDING, ///< Exit all the way to next enter (use only animations that end with this)
|
|
MODELCONDITION_CARRYING,
|
|
MODELCONDITION_FLOODED,
|
|
MODELCONDITION_LOADED, // loaded woot! ... like a transport is loaded
|
|
MODELCONDITION_JETAFTERBURNER,// shows "flames" for extra motive force (eg, when taking off)
|
|
MODELCONDITION_JETEXHAUST, // shows "exhaust" for motive force
|
|
MODELCONDITION_PACKING, // packs an object
|
|
MODELCONDITION_UNPACKING, // unpacks an object
|
|
MODELCONDITION_DEPLOYED, // a deployed object state
|
|
MODELCONDITION_OVER_WATER, // Units that can go over water want cool effects for doing so
|
|
MODELCONDITION_POWER_PLANT_UPGRADED, // to show special control rods on the cold fusion plant
|
|
MODELCONDITION_CLIMBING, //For units climbing up or down cliffs.
|
|
MODELCONDITION_SOLD, // object is being sold
|
|
#ifdef ALLOW_SURRENDER
|
|
MODELCONDITION_SURRENDER, //When units surrender...
|
|
#endif
|
|
MODELCONDITION_RAPPELLING,
|
|
MODELCONDITION_ARMED, // armed like a mine or bomb is armed (not like a human is armed)
|
|
MODELCONDITION_POWER_PLANT_UPGRADING, // while special control rods on the cold fusion plant are extending
|
|
|
|
//Special model conditions work as following:
|
|
//Something turns it on... but a timer in the object will turn them off after a given
|
|
//amount of time. If you add any more special animations, then you'll need to add the
|
|
//code to turn off the state.
|
|
MODELCONDITION_SPECIAL_CHEERING, //When units do a victory cheer (or player initiated cheer).
|
|
|
|
MODELCONDITION_CONTINUOUS_FIRE_SLOW,
|
|
MODELCONDITION_CONTINUOUS_FIRE_MEAN,
|
|
MODELCONDITION_CONTINUOUS_FIRE_FAST,
|
|
|
|
MODELCONDITION_RAISING_FLAG,
|
|
MODELCONDITION_CAPTURED,
|
|
|
|
MODELCONDITION_EXPLODED_FLAILING,
|
|
MODELCONDITION_EXPLODED_BOUNCING,
|
|
MODELCONDITION_SPLATTED,
|
|
|
|
// this is an easier-to-use variant on the whole FIRING_A deal...
|
|
// these bits are set if firing, reloading, between shots, or preattack.
|
|
MODELCONDITION_USING_WEAPON_A,
|
|
MODELCONDITION_USING_WEAPON_B,
|
|
MODELCONDITION_USING_WEAPON_C,
|
|
|
|
MODELCONDITION_PREORDER,
|
|
|
|
//
|
|
// Note: these values are saved in save files, so you MUST NOT REMOVE OR CHANGE
|
|
// existing values!
|
|
//
|
|
|
|
MODELCONDITION_COUNT // keep last!
|
|
};
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
typedef BitFlags<MODELCONDITION_COUNT> ModelConditionFlags;
|
|
|
|
#define MAKE_MODELCONDITION_MASK(k) ModelConditionFlags(ModelConditionFlags::kInit, (k))
|
|
#define MAKE_MODELCONDITION_MASK2(k,a) ModelConditionFlags(ModelConditionFlags::kInit, (k), (a))
|
|
#define MAKE_MODELCONDITION_MASK3(k,a,b) ModelConditionFlags(ModelConditionFlags::kInit, (k), (a), (b))
|
|
#define MAKE_MODELCONDITION_MASK4(k,a,b,c) ModelConditionFlags(ModelConditionFlags::kInit, (k), (a), (b), (c))
|
|
#define MAKE_MODELCONDITION_MASK5(k,a,b,c,d) ModelConditionFlags(ModelConditionFlags::kInit, (k), (a), (b), (c), (d))
|
|
#define MAKE_MODELCONDITION_MASK12(a,b,c,d,e,f,g,h,i,j,k,l) ModelConditionFlags(ModelConditionFlags::kInit, (a), (b), (c), (d), (e), (f), (g), (h), (i), (j), (k), (l))
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
#endif // _ModelState_H_
|
|
|