/* ** Command & Conquer Generals Zero Hour(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 . */ //////////////////////////////////////////////////////////////////////////////// // // // (c) 2001-2003 Electronic Arts Inc. // // // //////////////////////////////////////////////////////////////////////////////// // FILE: MessageStream.h ////////////////////////////////////////////////////// // The message stream propagates all messages thru a series of "translators" // Author: Michael S. Booth, February 2001 #pragma once #ifndef _MESSAGE_STREAM_H_ #define _MESSAGE_STREAM_H_ #include "Common/GameCommon.h" // ensure we get DUMP_PERF_STATS, or not #include "Common/SubsystemInterface.h" #include "Lib/BaseType.h" #include "Common/GameMemory.h" enum { TRANSLATOR_ID_INVALID = -1 }; // how far the the cursor moves before a click becomes a drag typedef UnsignedInt TranslatorID; ///< Unique identifiers for message stream translators class Drawable; class GameMessageList; enum ObjectID; enum DrawableID; union GameMessageArgumentType ///< Union of possible data for given message type { Int integer; Real real; Bool boolean; ObjectID objectID; DrawableID drawableID; UnsignedInt teamID; UnsignedInt squadID; Coord3D location; ICoord2D pixel; IRegion2D pixelRegion; UnsignedInt timestamp; WideChar wChar; }; enum GameMessageArgumentDataType { ARGUMENTDATATYPE_INTEGER, ARGUMENTDATATYPE_REAL, ARGUMENTDATATYPE_BOOLEAN, ARGUMENTDATATYPE_OBJECTID, ARGUMENTDATATYPE_DRAWABLEID, ARGUMENTDATATYPE_TEAMID, ARGUMENTDATATYPE_LOCATION, ARGUMENTDATATYPE_PIXEL, ARGUMENTDATATYPE_PIXELREGION, ARGUMENTDATATYPE_TIMESTAMP, ARGUMENTDATATYPE_WIDECHAR, ARGUMENTDATATYPE_UNKNOWN }; class GameMessageArgument : public MemoryPoolObject { MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(GameMessageArgument, "GameMessageArgument") public: GameMessageArgument* m_next; ///< The next argument GameMessageArgumentType m_data; ///< The data storage of an argument GameMessageArgumentDataType m_type; ///< The type of the argument. }; EMPTY_DTOR(GameMessageArgument) /** * A game message that either lives on TheMessageStream or TheCommandList. * Messages consist of a type, defining what the message is, and zero or more arguments * of various data types. The user of a message must know how many and what type of * arguments are valid for a given message type. */ class GameMessage : public MemoryPoolObject { MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(GameMessage, "GameMessage") public: /// The various messages which can be sent in a MessageStream /// @todo Replace this hardcoded enum with a generalized system that can be easily changed and updated /** @todo Because the Client will run faster than Logic, we'll need "superceding" messages for events such as mouse movements so we only send the latest one over the net */ /** @todo Create two classes of message: raw input messages, and command messages. Raw input messages will be destroyed when they reach the end of the stream, whereas command messages will be transferred to TheCommandList */ enum Type { MSG_INVALID, ///< (none) this msg should never actually occur MSG_FRAME_TICK, ///< (timestamp) once each frame this message is sent thru the stream // Client to Server messages // Note: Please keep MSG_RAW_MOUSE between MSG_RAW_MOUSE_BEGIN and MSG_RAW_MOUSE_END MSG_RAW_MOUSE_BEGIN, MSG_RAW_MOUSE_POSITION, ///< (pixel) the cursor's position MSG_RAW_MOUSE_LEFT_BUTTON_DOWN, ///< (pixel, modifiers, time) MSG_RAW_MOUSE_LEFT_DOUBLE_CLICK, ///< (pixel, modifiers, time) MSG_RAW_MOUSE_LEFT_BUTTON_UP, ///< (pixel, modifiers, time) MSG_RAW_MOUSE_LEFT_CLICK, ///< (pixel, modifiers, time) MSG_RAW_MOUSE_LEFT_DRAG, ///< drag of the mouse with a button held down MSG_RAW_MOUSE_MIDDLE_BUTTON_DOWN, ///< (pixel, modifiers, time) MSG_RAW_MOUSE_MIDDLE_DOUBLE_CLICK, ///< (pixel, modifiers, time) MSG_RAW_MOUSE_MIDDLE_BUTTON_UP, ///< (pixel, modifiers, time) MSG_RAW_MOUSE_MIDDLE_DRAG, ///< drag of the mouse with a button held down MSG_RAW_MOUSE_RIGHT_BUTTON_DOWN, ///< (pixel, modifiers, time) MSG_RAW_MOUSE_RIGHT_DOUBLE_CLICK, ///< (pixel, modifiers, time) MSG_RAW_MOUSE_RIGHT_BUTTON_UP, ///< (pixel, modifiers, time) MSG_RAW_MOUSE_RIGHT_DRAG, ///< drag of the mouse with a button held down MSG_RAW_MOUSE_WHEEL, ///< (Int spin, + is away, - is toward user) MSG_RAW_MOUSE_END, MSG_RAW_KEY_DOWN, ///< (KeyDefType) the given key was pressed (uses Microsoft VK_ codes) MSG_RAW_KEY_UP, ///< (KeyDefType) the given key was released // Refined Mouse messages // NOTE: All processing should attempt to use these refined mouse messages, rather than the // RAW_* variants. (Please.) :-) jkmcd MSG_MOUSE_LEFT_CLICK, ///< (pixelRegion, 0 sized means its a point), (Int, modifier keys) MSG_MOUSE_LEFT_DOUBLE_CLICK, ///< (pixelRegion, 0 sized means its a point), (Int, modifier keys) MSG_MOUSE_MIDDLE_CLICK, ///< (pixelRegion, 0 sized means its a point), (Int, modifier keys) MSG_MOUSE_MIDDLE_DOUBLE_CLICK, ///< (pixelRegion, 0 sized means its a point), (Int, modifier keys) MSG_MOUSE_RIGHT_CLICK, ///< (pixelRegion, 0 sized means its a point), (Int, modifier keys) MSG_MOUSE_RIGHT_DOUBLE_CLICK, ///< (pixelRegion, 0 sized means its a point), (Int, modifier keys) // End Refined Mouse Messages MSG_CLEAR_GAME_DATA, ///< Clear all game data in memory MSG_NEW_GAME, ///< Start a new game // "meta" messages should be thought of as "virtual keystrokes" -- they exist // solely to provide an abstraction layer useful for keyboard/mouse remapping. // they should NEVER be sent over the network. MSG_BEGIN_META_MESSAGES, ///< Marker to delineate "meta" messages MSG_META_SAVE_VIEW1, ///< save current view as the given user-defined view MSG_META_SAVE_VIEW2, ///< save current view as the given user-defined view MSG_META_SAVE_VIEW3, ///< save current view as the given user-defined view MSG_META_SAVE_VIEW4, ///< save current view as the given user-defined view MSG_META_SAVE_VIEW5, ///< save current view as the given user-defined view MSG_META_SAVE_VIEW6, ///< save current view as the given user-defined view MSG_META_SAVE_VIEW7, ///< save current view as the given user-defined view MSG_META_SAVE_VIEW8, ///< save current view as the given user-defined view MSG_META_VIEW_VIEW1, ///< center view on the given user-defined view MSG_META_VIEW_VIEW2, ///< center view on the given user-defined view MSG_META_VIEW_VIEW3, ///< center view on the given user-defined view MSG_META_VIEW_VIEW4, ///< center view on the given user-defined view MSG_META_VIEW_VIEW5, ///< center view on the given user-defined view MSG_META_VIEW_VIEW6, ///< center view on the given user-defined view MSG_META_VIEW_VIEW7, ///< center view on the given user-defined view MSG_META_VIEW_VIEW8, ///< center view on the given user-defined view MSG_META_CREATE_TEAM0, ///< create user-defined team from the selected objects MSG_META_CREATE_TEAM1, ///< create user-defined team from the selected objects MSG_META_CREATE_TEAM2, ///< create user-defined team from the selected objects MSG_META_CREATE_TEAM3, ///< create user-defined team from the selected objects MSG_META_CREATE_TEAM4, ///< create user-defined team from the selected objects MSG_META_CREATE_TEAM5, ///< create user-defined team from the selected objects MSG_META_CREATE_TEAM6, ///< create user-defined team from the selected objects MSG_META_CREATE_TEAM7, ///< create user-defined team from the selected objects MSG_META_CREATE_TEAM8, ///< create user-defined team from the selected objects MSG_META_CREATE_TEAM9, ///< create user-defined team from the selected objects MSG_META_SELECT_TEAM0, ///< deselect all, then select all units in the given user-defined team MSG_META_SELECT_TEAM1, ///< deselect all, then select all units in the given user-defined team MSG_META_SELECT_TEAM2, ///< deselect all, then select all units in the given user-defined team MSG_META_SELECT_TEAM3, ///< deselect all, then select all units in the given user-defined team MSG_META_SELECT_TEAM4, ///< deselect all, then select all units in the given user-defined team MSG_META_SELECT_TEAM5, ///< deselect all, then select all units in the given user-defined team MSG_META_SELECT_TEAM6, ///< deselect all, then select all units in the given user-defined team MSG_META_SELECT_TEAM7, ///< deselect all, then select all units in the given user-defined team MSG_META_SELECT_TEAM8, ///< deselect all, then select all units in the given user-defined team MSG_META_SELECT_TEAM9, ///< deselect all, then select all units in the given user-defined team MSG_META_ADD_TEAM0, ///< add the user-defined team to the current selection MSG_META_ADD_TEAM1, ///< add the user-defined team to the current selection MSG_META_ADD_TEAM2, ///< add the user-defined team to the current selection MSG_META_ADD_TEAM3, ///< add the user-defined team to the current selection MSG_META_ADD_TEAM4, ///< add the user-defined team to the current selection MSG_META_ADD_TEAM5, ///< add the user-defined team to the current selection MSG_META_ADD_TEAM6, ///< add the user-defined team to the current selection MSG_META_ADD_TEAM7, ///< add the user-defined team to the current selection MSG_META_ADD_TEAM8, ///< add the user-defined team to the current selection MSG_META_ADD_TEAM9, ///< add the user-defined team to the current selection MSG_META_VIEW_TEAM0, ///< center view on given user-defined team (but do not affect selection) MSG_META_VIEW_TEAM1, ///< center view on given user-defined team (but do not affect selection) MSG_META_VIEW_TEAM2, ///< center view on given user-defined team (but do not affect selection) MSG_META_VIEW_TEAM3, ///< center view on given user-defined team (but do not affect selection) MSG_META_VIEW_TEAM4, ///< center view on given user-defined team (but do not affect selection) MSG_META_VIEW_TEAM5, ///< center view on given user-defined team (but do not affect selection) MSG_META_VIEW_TEAM6, ///< center view on given user-defined team (but do not affect selection) MSG_META_VIEW_TEAM7, ///< center view on given user-defined team (but do not affect selection) MSG_META_VIEW_TEAM8, ///< center view on given user-defined team (but do not affect selection) MSG_META_VIEW_TEAM9, ///< center view on given user-defined team (but do not affect selection) MSG_META_SELECT_MATCHING_UNITS, ///< selects mathcing units, used for both on screen and across map MSG_META_SELECT_NEXT_UNIT, ///< select 'next' unit MSG_META_SELECT_PREV_UNIT, ///< select 'prev' unit MSG_META_SELECT_NEXT_WORKER, ///< select 'next' worker MSG_META_SELECT_PREV_WORKER, ///< select 'prev' worker MSG_META_VIEW_COMMAND_CENTER, ///< center view on command center MSG_META_VIEW_LAST_RADAR_EVENT, ///< center view on last radar event MSG_META_SELECT_HERO, ///< selects player's hero character, if exists... MSG_META_SELECT_ALL, ///< selects all units across screen MSG_META_SELECT_ALL_AIRCRAFT, ///< selects all air units just like select all MSG_META_SCATTER, ///< selected units scatter MSG_META_STOP, ///< selected units stop MSG_META_DEPLOY, ///< selected units 'deploy' MSG_META_CREATE_FORMATION, ///< selected units become a formation MSG_META_FOLLOW, ///< selected units 'follow' MSG_META_CHAT_PLAYERS, ///< send chat msg to all players MSG_META_CHAT_ALLIES, ///< send chat msg to allied players MSG_META_CHAT_EVERYONE, ///< send chat msg to everyone (incl. observers) MSG_META_DIPLOMACY, ///< bring up diplomacy screen MSG_META_OPTIONS, ///< bring up options screen #if defined(_DEBUG) || defined(_INTERNAL) MSG_META_HELP, ///< bring up help screen #endif MSG_META_TOGGLE_LOWER_DETAILS, ///< toggles graphics options to crappy mode instantly MSG_META_TOGGLE_CONTROL_BAR, ///< show/hide controlbar MSG_META_BEGIN_PATH_BUILD, ///< enter path-building mode MSG_META_END_PATH_BUILD, ///< exit path-building mode MSG_META_BEGIN_FORCEATTACK, ///< enter force-attack mode MSG_META_END_FORCEATTACK, ///< exit force-attack mode MSG_META_BEGIN_FORCEMOVE, ///< enter force-move mode MSG_META_END_FORCEMOVE, ///< exit force-move mode MSG_META_BEGIN_WAYPOINTS, ///< enter waypoint mode MSG_META_END_WAYPOINTS, ///< exit waypoint mode MSG_META_BEGIN_PREFER_SELECTION, ///< The Shift key has been depressed alone MSG_META_END_PREFER_SELECTION, ///< The Shift key has been released. MSG_META_TAKE_SCREENSHOT, ///< take screenshot MSG_META_ALL_CHEER, ///< Yay! :) MSG_META_TOGGLE_ATTACKMOVE, ///< enter attack-move mode MSG_META_BEGIN_CAMERA_ROTATE_LEFT, MSG_META_END_CAMERA_ROTATE_LEFT, MSG_META_BEGIN_CAMERA_ROTATE_RIGHT, MSG_META_END_CAMERA_ROTATE_RIGHT, MSG_META_BEGIN_CAMERA_ZOOM_IN, MSG_META_END_CAMERA_ZOOM_IN, MSG_META_BEGIN_CAMERA_ZOOM_OUT, MSG_META_END_CAMERA_ZOOM_OUT, MSG_META_CAMERA_RESET, MSG_META_TOGGLE_CAMERA_TRACKING_DRAWABLE, MSG_META_TOGGLE_FAST_FORWARD_REPLAY, ///< Toggle the fast forward feature MSG_META_DEMO_INSTANT_QUIT, ///< bail out of game immediately #if defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE)//may be defined in GameCommon.h MSG_CHEAT_RUNSCRIPT1, ///< run script named "KEY_F1" MSG_CHEAT_RUNSCRIPT2, ///< run script named "KEY_F2" MSG_CHEAT_RUNSCRIPT3, ///< run script named "KEY_F3" MSG_CHEAT_RUNSCRIPT4, ///< run script named "KEY_F4" MSG_CHEAT_RUNSCRIPT5, ///< run script named "KEY_F5" MSG_CHEAT_RUNSCRIPT6, ///< run script named "KEY_F6" MSG_CHEAT_RUNSCRIPT7, ///< run script named "KEY_F7" MSG_CHEAT_RUNSCRIPT8, ///< run script named "KEY_F8" MSG_CHEAT_RUNSCRIPT9, ///< run script named "KEY_F9" MSG_CHEAT_TOGGLE_SPECIAL_POWER_DELAYS, ///< Toggle special power delays on/off MSG_CHEAT_SWITCH_TEAMS, ///< switch local control to another team MSG_CHEAT_KILL_SELECTION, ///< kill the selected units (yeah!) MSG_CHEAT_TOGGLE_HAND_OF_GOD_MODE, ///< do 100% damage to the selected units (w00t!) MSG_CHEAT_INSTANT_BUILD, ///< All building is with a timer of 1 MSG_CHEAT_DESHROUD, ///< de-shroud the world for the local player MSG_CHEAT_ADD_CASH, ///< adds 10000 cash to the player MSG_CHEAT_GIVE_ALL_SCIENCES, ///< grant all grantable sciences MSG_CHEAT_GIVE_SCIENCEPURCHASEPOINTS, ///< give yourself an SPP (but no rank change) MSG_CHEAT_SHOW_HEALTH, ///< show object health MSG_CHEAT_TOGGLE_MESSAGE_TEXT, ///< hides/shows the onscreen messages #endif // META items that are really for debug/demo/development use only... // They do not get built into RELEASE builds. #if defined(_DEBUG) || defined(_INTERNAL) MSG_META_DEMO_TOGGLE_BEHIND_BUILDINGS, ///< Toggles showing units behind buildings or not MSG_META_DEMO_TOGGLE_LETTERBOX, ///< enable/disable letterbox mode MSG_META_DEMO_TOGGLE_MESSAGE_TEXT, ///< toggle the text from the UI messages MSG_META_DEMO_LOD_DECREASE, ///< decrease LOD by 1 MSG_META_DEMO_LOD_INCREASE, ///< increase LOD by 1 MSG_META_DEMO_TOGGLE_ZOOM_LOCK, ///< Toggle the camera zoom lock on/off MSG_META_DEMO_PLAY_CAMEO_MOVIE, ///< Play a movie in the cameo spot MSG_META_DEMO_TOGGLE_SPECIAL_POWER_DELAYS, ///< Toggle special power delays on/off MSG_META_DEMO_BATTLE_CRY, ///< battle cry MSG_META_DEMO_SWITCH_TEAMS, ///< switch local control to another team MSG_META_DEMO_SWITCH_TEAMS_BETWEEN_CHINA_USA, ///< switch the local player between china and usa MSG_META_DEMO_TOGGLE_PARTICLEDEBUG, ///< show/hide the particle system debug info MSG_META_DEMO_TOGGLE_SHADOW_VOLUMES, ///< show/hide shadow volumes MSG_META_DEMO_TOGGLE_FOGOFWAR, MSG_META_DEMO_KILL_ALL_ENEMIES, ///< kill ALL ENEMIES! (yeah!) MSG_META_DEMO_KILL_SELECTION, ///< kill the selected units (yeah!) MSG_META_DEMO_TOGGLE_HURT_ME_MODE, ///< do 10% damage to the selected units (yeah!) MSG_META_DEMO_TOGGLE_HAND_OF_GOD_MODE, ///< do 100% damage to the selected units (w00t!) MSG_META_DEMO_DEBUG_SELECTION, ///< select a given unit for state-machine debugging MSG_META_DEMO_LOCK_CAMERA_TO_SELECTION, ///< lock the view camera to the selected object MSG_META_DEMO_TOGGLE_SOUND, ///< toggle sound/video on/off MSG_META_DEMO_TOGGLE_TRACKMARKS, ///< toggle tank tread marks on/off MSG_META_DEMO_TOGGLE_WATERPLANE, ///< toggle waterplane on/off MSG_META_DEMO_TIME_OF_DAY, ///< change time-of-day lighting MSG_META_DEMO_TOGGLE_MUSIC, ///< turn background music on/off MSG_META_DEMO_MUSIC_NEXT_TRACK, ///< play next track MSG_META_DEMO_MUSIC_PREV_TRACK, ///< play prev track MSG_META_DEMO_NEXT_OBJECTIVE_MOVIE, ///< play next "Objective" movie MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE1, ///< play specific "Objective" movie MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE2, ///< play specific "Objective" movie MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE3, ///< play specific "Objective" movie MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE4, ///< play specific "Objective" movie MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE5, ///< play specific "Objective" movie MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE6, ///< play specific "Objective" movie MSG_META_DEMO_BEGIN_ADJUST_PITCH, ///< enter adjust-pitch mode MSG_META_DEMO_END_ADJUST_PITCH, ///< exit adjust-pitch mode MSG_META_DEMO_BEGIN_ADJUST_FOV, ///< enter adjust-FOV mode MSG_META_DEMO_END_ADJUST_FOV, ///< exit adjust-FOV mode MSG_META_DEMO_LOCK_CAMERA_TO_PLANES, ///< lock camera to airborne thingies MSG_META_DEMO_REMOVE_PREREQ, ///< Turn of Prerequisite checks in building legality MSG_META_DEMO_INSTANT_BUILD, ///< All building is with a timer of 1 MSG_META_DEMO_FREE_BUILD, ///< All building is for 0 money MSG_META_DEMO_RUNSCRIPT1, ///< run script named "KEY_F1" MSG_META_DEMO_RUNSCRIPT2, ///< run script named "KEY_F2" MSG_META_DEMO_RUNSCRIPT3, ///< run script named "KEY_F3" MSG_META_DEMO_RUNSCRIPT4, ///< run script named "KEY_F4" MSG_META_DEMO_RUNSCRIPT5, ///< run script named "KEY_F5" MSG_META_DEMO_RUNSCRIPT6, ///< run script named "KEY_F6" MSG_META_DEMO_RUNSCRIPT7, ///< run script named "KEY_F7" MSG_META_DEMO_RUNSCRIPT8, ///< run script named "KEY_F8" MSG_META_DEMO_RUNSCRIPT9, ///< run script named "KEY_F9" MSG_META_DEMO_ENSHROUD, ///< re-shroud the world for the local player MSG_META_DEMO_DESHROUD, ///< de-shroud the world for the local player MSG_META_DEBUG_SHOW_EXTENTS, ///< show object extents MSG_META_DEBUG_SHOW_AUDIO_LOCATIONS, ///< show audio objects and radii MSG_META_DEBUG_SHOW_HEALTH, ///< show object health MSG_META_DEBUG_GIVE_VETERANCY, ///< give a veterancy level to selected objects MSG_META_DEBUG_TAKE_VETERANCY, ///< take a veterancy level from selected objects MSG_META_DEMO_TOGGLE_AI_DEBUG, ///< show/hide the ai debug stats MSG_META_DEMO_TOGGLE_SUPPLY_CENTER_PLACEMENT, ///