799 lines
43 KiB
C++
799 lines
43 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. //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// 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_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,
|
|
|
|
// 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_INSTANT_QUIT, ///< bail out of game immediately
|
|
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_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_CAMERA_DEBUG, ///< show/hide the camera debug stats
|
|
MSG_META_DEMO_TOGGLE_AVI, ///< start capturing video
|
|
MSG_META_DEMO_TOGGLE_BW_VIEW, ///< enable/disable black & white camera mode
|
|
MSG_META_DEMO_TOGGLE_RED_VIEW, ///< enable/disable red tinted view
|
|
MSG_META_DEMO_TOGGLE_GREEN_VIEW, ///< enable/disable green view
|
|
MSG_META_DEMO_TOGGLE_MOTION_BLUR_ZOOM, ///< enable/disable green view
|
|
MSG_META_DEMO_TOGGLE_MILITARY_SUBTITLES, ///< enable/disable military subtitles
|
|
MSG_META_DEMO_ADD_CASH, ///< adds 10000 cash to the player
|
|
#ifdef ALLOW_SURRENDER
|
|
MSG_META_DEMO_TEST_SURRENDER, ///< Test key to show surrender animation in game.
|
|
#endif
|
|
MSG_META_DEMO_TOGGLE_RENDER, ///< toggle rendering on/off
|
|
MSG_META_DEMO_KILL_AREA_SELECTION, ///< (teamID, objectID1, objectID2, ... objectIDN)
|
|
MSG_META_DEMO_CYCLE_LOD_LEVEL, ///< cycles through dynamic game detail levels.
|
|
|
|
MSG_META_DEBUG_INCR_ANIM_SKATE_SPEED, ///< for debugging anim skate speeds
|
|
MSG_META_DEBUG_DECR_ANIM_SKATE_SPEED, ///< for debugging anim skate speeds
|
|
MSG_META_DEBUG_CYCLE_EXTENT_TYPE, ///< change extent
|
|
MSG_META_DEBUG_INCREASE_EXTENT_MAJOR, ///< change extent
|
|
MSG_META_DEBUG_INCREASE_EXTENT_MAJOR_BIG, ///< change extent
|
|
MSG_META_DEBUG_DECREASE_EXTENT_MAJOR, ///< change extent
|
|
MSG_META_DEBUG_DECREASE_EXTENT_MAJOR_BIG, ///< change extent
|
|
MSG_META_DEBUG_INCREASE_EXTENT_MINOR, ///< change extent
|
|
MSG_META_DEBUG_INCREASE_EXTENT_MINOR_BIG, ///< change extent
|
|
MSG_META_DEBUG_DECREASE_EXTENT_MINOR, ///< change extent
|
|
MSG_META_DEBUG_DECREASE_EXTENT_MINOR_BIG, ///< change extent
|
|
MSG_META_DEBUG_INCREASE_EXTENT_HEIGHT, ///< change extent
|
|
MSG_META_DEBUG_INCREASE_EXTENT_HEIGHT_BIG, ///< change extent
|
|
MSG_META_DEBUG_DECREASE_EXTENT_HEIGHT, ///< change extent
|
|
MSG_META_DEBUG_DECREASE_EXTENT_HEIGHT_BIG, ///< change extent
|
|
MSG_META_DEBUG_VTUNE_ON, ///< turn on/off Vtune
|
|
MSG_META_DEBUG_VTUNE_OFF, ///< turn on/off Vtune
|
|
MSG_META_DEBUG_TOGGLE_FEATHER_WATER, ///< toggle lorenzen's feather water
|
|
|
|
MSG_META_DEBUG_DUMP_ASSETS, ///< dumps currently used map assets to a file.
|
|
|
|
MSG_NO_DRAW, ///< show/hide all objects to test Drawing code
|
|
MSG_META_DEMO_TOGGLE_METRICS, ///< Toggle the metrics on/off
|
|
MSG_META_DEMO_TOGGLE_PROJECTILEDEBUG, ///< Toggles bezier curves on projectiles on/off
|
|
MSG_META_DEMO_TOGGLE_VISIONDEBUG, ///< Toggles vision debug circles on/off
|
|
MSG_META_DEMO_TOGGLE_THREATDEBUG, ///< Toggle the threat debugger on/off
|
|
MSG_META_DEMO_TOGGLE_CASHMAPDEBUG, ///< Toggle the cash map debugger on/off
|
|
MSG_META_DEMO_TOGGLE_GRAPHICALFRAMERATEBAR, ///< Toggle the graphical framerate bar on/off
|
|
MSG_META_DEMO_GIVE_ALL_SCIENCES, ///< grant all grantable sciences
|
|
MSG_META_DEMO_GIVE_RANKLEVEL, ///< up one RankLevel
|
|
MSG_META_DEMO_TAKE_RANKLEVEL, ///< up one RankLevel
|
|
MSG_META_DEMO_GIVE_SCIENCEPURCHASEPOINTS, ///< give yourself an SPP (but no rank change)
|
|
MSG_META_DEBUG_TOGGLE_NETWORK, ///< toggle between having and not having network traffic.
|
|
MSG_META_DEBUG_DUMP_PLAYER_OBJECTS, ///< Dump numbers of objects owned by each player to the script debug window
|
|
MSG_META_DEBUG_DUMP_ALL_PLAYER_OBJECTS, ///< Dump numbers of objects owned by each player to the script debug window, and additional object info
|
|
|
|
MSG_META_DEBUG_WIN, ///< Instant Win
|
|
MSG_META_DEMO_TOGGLE_DEBUG_STATS, ///< show/hide the debug stats
|
|
/// @todo END section to REMOVE (not disable) for release
|
|
#endif // defined(_DEBUG) || defined(_INTERNAL)
|
|
|
|
#if defined(_INTERNAL) || defined(_DEBUG) || defined(_PLAYTEST)
|
|
MSG_META_DEMO_TOGGLE_AUDIODEBUG, ///< show/hide the audio debug info
|
|
#endif//defined(_INTERNAL) || defined(_DEBUG) || defined(_PLAYTEST)
|
|
#ifdef DUMP_PERF_STATS
|
|
MSG_META_DEMO_PERFORM_STATISTICAL_DUMP, ///< dump performance stats for this frame to StatisticsDump.txt
|
|
#endif//DUMP_PERF_STATS
|
|
|
|
MSG_META_PLACE_BEACON,
|
|
MSG_META_REMOVE_BEACON,
|
|
|
|
MSG_END_META_MESSAGES, ///< Marker to delineate "meta" messages
|
|
|
|
MSG_MOUSEOVER_DRAWABLE_HINT, ///< (drawableid) the given drawable is under the mouse, regardless of button states
|
|
MSG_MOUSEOVER_LOCATION_HINT, ///< (location) The cursor is not over a drawable, but is here.
|
|
MSG_VALID_GUICOMMAND_HINT, ///< posted when the gui command is valid if the user clicked to execute it.
|
|
MSG_INVALID_GUICOMMAND_HINT, ///< posted when the gui command is not valid if the user were to click to attempt to execute it.
|
|
MSG_AREA_SELECTION_HINT, ///< (pixelRegion) rectangular selection area under construction, not confirmed
|
|
|
|
//Command hints
|
|
MSG_DO_ATTACK_OBJECT_HINT, ///< (victim objectID) If clicked, an attack would be ordered, "Current Selection" is assumed
|
|
MSG_IMPOSSIBLE_ATTACK_HINT, ///< we can't do anything, and target is out of range.
|
|
MSG_DO_FORCE_ATTACK_OBJECT_HINT, ///< (victim objectID) If clicked, an attack would be ordered, "Current Selection" is assumed
|
|
MSG_DO_FORCE_ATTACK_GROUND_HINT, ///< (victim objectID) If clicked, an attack would be ordered, "Current Selection" is assumed
|
|
MSG_GET_REPAIRED_HINT, ///< If clicked, selected unit will go get repaired at clicked object
|
|
MSG_GET_HEALED_HINT, ///< If clicked, selected unit will go get healed at clicked object
|
|
MSG_DO_REPAIR_HINT, ///< if clicked, dozer will go repair the clicked target
|
|
MSG_RESUME_CONSTRUCTION_HINT, ///< if clicked, dozer will go construct a partially constructed building
|
|
MSG_ENTER_HINT, ///< if clicked, selected unit(s) will attempt to enter clicked object
|
|
MSG_DOCK_HINT, ///< If clicked, selected unit(s) will dock
|
|
MSG_DO_MOVETO_HINT, ///< (location) If clicked, a move would be ordered, "Current Selection" is assumed
|
|
MSG_DO_ATTACKMOVETO_HINT, ///< (location) If clicked, a move would be ordered, "Current Selection" is assumed
|
|
MSG_ADD_WAYPOINT_HINT, ///< (location) If clicked, a waypoint will be added for currently selected units.
|
|
//Context command hints
|
|
MSG_HIJACK_HINT, ///< if clicked, selected unit(s) will attempt to take over vehicle.
|
|
MSG_FIREBOMB_HINT, ///< throw a molotov cocktail
|
|
MSG_CONVERT_TO_CARBOMB_HINT, ///< if clicked, selected unit(s) will attempt to convert clicked object into a carbomb.
|
|
MSG_CAPTUREBUILDING_HINT,
|
|
#ifdef ALLOW_SURRENDER
|
|
MSG_PICK_UP_PRISONER_HINT,
|
|
#endif
|
|
MSG_SNIPE_VEHICLE_HINT,
|
|
MSG_DEFECTOR_HINT,
|
|
MSG_SET_RALLY_POINT_HINT, ///< (location) if clicked, we will place a rally point here.
|
|
MSG_DO_SPECIAL_POWER_OVERRIDE_DESTINATION_HINT,
|
|
MSG_DO_SALVAGE_HINT,
|
|
MSG_DO_INVALID_HINT, ///< Display invalid cursor because no real command can be done in this context.
|
|
MSG_DO_ATTACK_OBJECT_AFTER_MOVING_HINT,
|
|
MSG_HACK_HINT,
|
|
|
|
//*********************************************************************************************************
|
|
//*********************************************************************************************************
|
|
/*
|
|
Note that we start this at a fixed value, so that (regardless of ifdefs upstream from us) we have the same
|
|
numeric values for all enums that are saved in replay files. This helps improve compatibility between
|
|
replay files created in internal vs. release builds (though they will still generate sync errors in
|
|
some situations due to other reasons, e.g., DEBUG_LOG using the FPU and thus changing its state).
|
|
|
|
there should be NO IFDEFS OF ANY KIND FROM HERE UNTIL MSG_END_NETWORK_MESSAGES.
|
|
|
|
there should be NO IFDEFS OF ANY KIND FROM HERE UNTIL MSG_END_NETWORK_MESSAGES.
|
|
|
|
there should be NO IFDEFS OF ANY KIND FROM HERE UNTIL MSG_END_NETWORK_MESSAGES.
|
|
|
|
*/
|
|
MSG_BEGIN_NETWORK_MESSAGES = 1000, ///< MARKER TO DELINEATE MESSAGES THAT GO OVER THE NETWORK
|
|
//*********************************************************************************************************
|
|
MSG_CREATE_SELECTED_GROUP, /**< (Bool createNewGroup, objectID1, objectID2, ... objectIDN)
|
|
* The selected team is created/augmented with the given team members
|
|
*/
|
|
MSG_CREATE_SELECTED_GROUP_NO_SOUND, /**< (Bool createNewGroup, objectID1, objectID2, ... objectIDN)
|
|
* The selected team is created/augmented with the given team members.
|
|
* Do not play their selection sounds.
|
|
*/
|
|
MSG_DESTROY_SELECTED_GROUP, ///< (teamID) the given team is no longer valid
|
|
MSG_REMOVE_FROM_SELECTED_GROUP, /**< (objectID1, objectID2, ... objectIDN)
|
|
* Remove these units from the selected group. (N should almost always be 1)
|
|
*/
|
|
MSG_SELECTED_GROUP_COMMAND, ///< (teamID) the NEXT COMMAND acts upon all members of this team
|
|
MSG_CREATE_TEAM0, ///< Creates a hotkey squad from the currently selected units.
|
|
MSG_CREATE_TEAM1,
|
|
MSG_CREATE_TEAM2,
|
|
MSG_CREATE_TEAM3,
|
|
MSG_CREATE_TEAM4,
|
|
MSG_CREATE_TEAM5,
|
|
MSG_CREATE_TEAM6,
|
|
MSG_CREATE_TEAM7,
|
|
MSG_CREATE_TEAM8,
|
|
MSG_CREATE_TEAM9,
|
|
MSG_SELECT_TEAM0, ///< Set a hotkey squad to be the currently selected units.
|
|
MSG_SELECT_TEAM1, ///< Set a hotkey squad to be the currently selected units.
|
|
MSG_SELECT_TEAM2, ///< Set a hotkey squad to be the currently selected units.
|
|
MSG_SELECT_TEAM3, ///< Set a hotkey squad to be the currently selected units.
|
|
MSG_SELECT_TEAM4, ///< Set a hotkey squad to be the currently selected units.
|
|
MSG_SELECT_TEAM5, ///< Set a hotkey squad to be the currently selected units.
|
|
MSG_SELECT_TEAM6, ///< Set a hotkey squad to be the currently selected units.
|
|
MSG_SELECT_TEAM7, ///< Set a hotkey squad to be the currently selected units.
|
|
MSG_SELECT_TEAM8, ///< Set a hotkey squad to be the currently selected units.
|
|
MSG_SELECT_TEAM9, ///< Set a hotkey squad to be the currently selected units.
|
|
MSG_ADD_TEAM0, ///< Add hotkey squad to the currently selected units.
|
|
MSG_ADD_TEAM1, ///< Add hotkey squad to the currently selected units.
|
|
MSG_ADD_TEAM2, ///< Add hotkey squad to the currently selected units.
|
|
MSG_ADD_TEAM3, ///< Add hotkey squad to the currently selected units.
|
|
MSG_ADD_TEAM4, ///< Add hotkey squad to the currently selected units.
|
|
MSG_ADD_TEAM5, ///< Add hotkey squad to the currently selected units.
|
|
MSG_ADD_TEAM6, ///< Add hotkey squad to the currently selected units.
|
|
MSG_ADD_TEAM7, ///< Add hotkey squad to the currently selected units.
|
|
MSG_ADD_TEAM8, ///< Add hotkey squad to the currently selected units.
|
|
MSG_ADD_TEAM9, ///< Add hotkey squad to the currently selected units.
|
|
MSG_DO_ATTACKSQUAD, ///< (numObjects) (numObjects * objectID)
|
|
MSG_DO_WEAPON, ///< fire specific weapon
|
|
MSG_DO_WEAPON_AT_LOCATION, ///< fire a specific weapon at location
|
|
MSG_DO_WEAPON_AT_OBJECT, ///< fire a specific weapon at a target object
|
|
MSG_DO_SPECIAL_POWER, ///< do special
|
|
MSG_DO_SPECIAL_POWER_AT_LOCATION, ///< do special with target location
|
|
MSG_DO_SPECIAL_POWER_AT_OBJECT, ///< do special at with target object
|
|
MSG_SET_RALLY_POINT, ///< (objectID, location)
|
|
MSG_PURCHASE_SCIENCE, ///< purchase a science
|
|
MSG_QUEUE_UPGRADE, ///< queue the "research" of an upgrade
|
|
MSG_CANCEL_UPGRADE, ///< cancel the "research" of an upgrade
|
|
MSG_QUEUE_UNIT_CREATE, ///< clicked on a button to queue the production of a unit
|
|
MSG_CANCEL_UNIT_CREATE, ///< clicked on UI button to cancel production of a unit
|
|
MSG_DOZER_CONSTRUCT, /**< building things requires clicking on a dozer
|
|
selecting what to build, selecting where to
|
|
build it ... this construct message will
|
|
start the actual build process */
|
|
MSG_DOZER_CONSTRUCT_LINE, ///< Like MSG_CONSTRUCT, but for build procesess that occur in a line (like walls)
|
|
MSG_DOZER_CANCEL_CONSTRUCT, ///< cancel construction of a building
|
|
MSG_SELL, ///< sell a structure
|
|
MSG_EXIT, ///< WE want to exit from whatever WE are inside of
|
|
MSG_EVACUATE, ///< Dump out all of OUR contained objects
|
|
MSG_EXECUTE_RAILED_TRANSPORT, ///< Execute railed transport sequence
|
|
MSG_COMBATDROP_AT_LOCATION, ///< dump out all rappellers
|
|
MSG_COMBATDROP_AT_OBJECT, ///< dump out all rappellers
|
|
MSG_AREA_SELECTION, ///< (pixelRegion) rectangular selection area
|
|
MSG_DO_ATTACK_OBJECT, ///< (objectID, victim objectID)
|
|
MSG_DO_FORCE_ATTACK_OBJECT, ///< force attack the given object if picked
|
|
MSG_DO_FORCE_ATTACK_GROUND, ///< (locationID) bombard the given location if picked
|
|
MSG_GET_REPAIRED, ///< selected unit will go get repaired at clicked object
|
|
MSG_GET_HEALED, ///< selected unit will go get healed at clicked object
|
|
MSG_DO_REPAIR, ///< dozer will go repair the clicked target
|
|
MSG_RESUME_CONSTRUCTION, ///< resume construction on a structure
|
|
MSG_ENTER, ///< Enter object
|
|
MSG_DOCK, ///< Dock with this object
|
|
MSG_DO_MOVETO, ///< location
|
|
MSG_DO_ATTACKMOVETO, ///< location
|
|
MSG_DO_FORCEMOVETO, ///< location
|
|
MSG_ADD_WAYPOINT, ///< location
|
|
MSG_DO_GUARD_POSITION, ///< Guard with the currently selected group
|
|
MSG_DO_GUARD_OBJECT, ///< Guard with the currently selected group
|
|
MSG_DO_STOP, ///< Stop with the currently selected group
|
|
MSG_DO_SCATTER, ///< Scatter the currently selected group
|
|
MSG_INTERNET_HACK, ///< Begin a persistent internet hack (free slow income)
|
|
MSG_DO_CHEER, ///< Orders selected units to play cheer animation (if possible)
|
|
MSG_TOGGLE_OVERCHARGE, ///< Toggle overcharge status of a power plant
|
|
MSG_SWITCH_WEAPONS, ///< Switches which weapon slot to use for an object
|
|
MSG_CONVERT_TO_CARBOMB,
|
|
MSG_CAPTUREBUILDING,
|
|
MSG_DISABLEVEHICLE_HACK,
|
|
MSG_STEALCASH_HACK,
|
|
MSG_DISABLEBUILDING_HACK,
|
|
MSG_SNIPE_VEHICLE,
|
|
MSG_DO_SPECIAL_POWER_OVERRIDE_DESTINATION,
|
|
MSG_DO_SALVAGE,
|
|
MSG_CLEAR_INGAME_POPUP_MESSAGE, ///< If we want a replay to work with the popup messages then we need it to be passed
|
|
MSG_PLACE_BEACON,
|
|
MSG_REMOVE_BEACON,
|
|
MSG_SET_BEACON_TEXT,
|
|
MSG_SET_REPLAY_CAMERA, ///< Track camera pos for replays
|
|
MSG_SELF_DESTRUCT, ///< Destroys a player's units (for copy protection or to quit to observer)
|
|
MSG_CREATE_FORMATION, ///< Creates a formation.
|
|
MSG_LOGIC_CRC, ///< CRC from the logic passed around in a network game :)
|
|
MSG_SET_MINE_CLEARING_DETAIL, ///< CRC from the logic passed around in a network game :)
|
|
|
|
MSG_BEGIN_DEBUG_NETWORK_MESSAGES = 1900, ///< network messages that exist only in debug/internal builds. all grouped separately.
|
|
|
|
#if defined(_DEBUG) || defined(_INTERNAL)
|
|
// all debug/internal-only messages must go here.
|
|
MSG_DEBUG_KILL_SELECTION,
|
|
MSG_DEBUG_HURT_OBJECT,
|
|
MSG_DEBUG_KILL_OBJECT,
|
|
#endif
|
|
|
|
//*********************************************************************************************************
|
|
MSG_END_NETWORK_MESSAGES = 1999, ///< MARKER TO DELINEATE MESSAGES THAT GO OVER THE NETWORK
|
|
//*********************************************************************************************************
|
|
//*********************************************************************************************************
|
|
|
|
|
|
// Server to Client messages
|
|
MSG_TIMESTAMP, ///< The current frame number
|
|
MSG_OBJECT_CREATED, ///< (objectID, Int type) Cause a drawable to be created and bound to this ID
|
|
MSG_OBJECT_DESTROYED, ///< (objectID) Free bound drawable
|
|
MSG_OBJECT_POSITION, ///< (objectID, location) New position of object
|
|
MSG_OBJECT_ORIENTATION, ///< (objectID, angle) New orientation of object
|
|
MSG_OBJECT_JOINED_TEAM, ///< (objectID) New team affiliation of object
|
|
|
|
MSG_COUNT
|
|
};
|
|
|
|
GameMessage( Type type );
|
|
|
|
GameMessage *next( void ) { return m_next; } ///< Return next message in the stream
|
|
GameMessage *prev( void ) { return m_prev; } ///< Return prev message in the stream
|
|
|
|
Type getType( void ) const { return m_type; } ///< Return the message type
|
|
UnsignedByte getArgumentCount( void ) const { return m_argCount; } ///< Return the number of arguments for this msg
|
|
|
|
AsciiString getCommandAsAsciiString( void ); ///< returns a string representation of the command type.
|
|
static AsciiString getCommandTypeAsAsciiString(GameMessage::Type t);
|
|
|
|
Int getPlayerIndex( void ) const { return m_playerIndex; } ///< Return the originating player
|
|
|
|
// access methods for GameMessageArgumentType enum
|
|
void appendIntegerArgument( Int arg );
|
|
void appendRealArgument( Real arg );
|
|
void appendBooleanArgument( Bool arg );
|
|
void appendDrawableIDArgument( DrawableID arg );
|
|
void appendObjectIDArgument( ObjectID arg );
|
|
void appendTeamIDArgument( UnsignedInt arg );
|
|
void appendLocationArgument( const Coord3D& arg );
|
|
void appendPixelArgument( const ICoord2D& arg );
|
|
void appendPixelRegionArgument( const IRegion2D& arg );
|
|
void appendWideCharArgument( const WideChar& arg );
|
|
|
|
void appendTimestampArgument( UnsignedInt arg );
|
|
|
|
/**
|
|
* Return the given argument union.
|
|
* @todo This should be a more list-like interface. Very inefficient.
|
|
*/
|
|
const GameMessageArgumentType *getArgument( Int argIndex ) const;
|
|
GameMessageArgumentDataType getArgumentDataType( Int argIndex );
|
|
|
|
void friend_setNext(GameMessage* m) { m_next = m; }
|
|
void friend_setPrev(GameMessage* m) { m_prev = m; }
|
|
void friend_setList(GameMessageList* m) { m_list = m; }
|
|
void friend_setPlayerIndex(Int i) { m_playerIndex = i; }
|
|
|
|
private:
|
|
// friend classes are bad. don't use them. no, really.
|
|
// if for no other reason than the fact that they subvert MemoryPoolObject. (srj)
|
|
|
|
GameMessage *m_next, *m_prev; ///< List links for message list
|
|
GameMessageList *m_list; ///< The list this message is on
|
|
|
|
Type m_type; ///< The type of this message
|
|
|
|
Int m_playerIndex; ///< The Player who issued the command
|
|
|
|
/// @todo If a GameMessage needs more than 255 arguments, it needs to be split up into multiple GameMessage's.
|
|
UnsignedByte m_argCount; ///< The number of arguments of this message
|
|
|
|
GameMessageArgument *m_argList, *m_argTail; ///< This message's arguments
|
|
|
|
/// allocate a new argument, add it to list, return pointer to its data
|
|
GameMessageArgument *allocArg( void );
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* The GameMessageList class encapsulates the manipulation of lists of GameMessages.
|
|
* Both MessageStream and CommandList derive from this class.
|
|
*/
|
|
class GameMessageList : public SubsystemInterface
|
|
{
|
|
|
|
public:
|
|
|
|
GameMessageList( void );
|
|
virtual ~GameMessageList();
|
|
|
|
virtual void init( void ) { }; ///< Initialize system
|
|
virtual void reset( void ) { }; ///< Reset system
|
|
virtual void update( void ) { }; ///< Update system
|
|
|
|
GameMessage *getFirstMessage( void ) { return m_firstMessage; } ///< Return the first message
|
|
|
|
virtual void appendMessage( GameMessage *msg ); ///< Add message to end of the list
|
|
virtual void insertMessage( GameMessage *msg, GameMessage *messageToInsertAfter ); // Insert message after messageToInsertAfter.
|
|
virtual void removeMessage( GameMessage *msg ); ///< Remove message from the list
|
|
virtual Bool containsMessageOfType( GameMessage::Type type ); ///< Return true if a message of type is in the message stream
|
|
|
|
|
|
|
|
protected:
|
|
GameMessage *m_firstMessage; ///< The first message on the list
|
|
GameMessage *m_lastMessage; ///< The last message on the list
|
|
};
|
|
|
|
/**
|
|
What to do with a GameMessage after a translator has handled it.
|
|
Use a custom enum (rather than a Bool) to make the code more obvious.
|
|
*/
|
|
enum GameMessageDisposition
|
|
{
|
|
KEEP_MESSAGE, ///< continue processing this message thru other translators
|
|
DESTROY_MESSAGE ///< destroy this message immediately and don't hand it to any other translators
|
|
};
|
|
|
|
class GameMessageTranslator
|
|
{
|
|
public:
|
|
virtual GameMessageDisposition translateGameMessage(const GameMessage *msg) = 0;
|
|
virtual ~GameMessageTranslator() { }
|
|
};
|
|
|
|
/**
|
|
* A MessageStream contains an ordered list of messages which can have one or more
|
|
* prioritized message handler functions ("translators") attached to it.
|
|
*/
|
|
class MessageStream : public GameMessageList
|
|
{
|
|
|
|
public:
|
|
|
|
MessageStream( void );
|
|
virtual ~MessageStream();
|
|
|
|
// Inherited Methods ----------------------------------------------------------------------------
|
|
virtual void init( void );
|
|
virtual void reset( void );
|
|
virtual void update( void );
|
|
|
|
virtual GameMessage *appendMessage( GameMessage::Type type ); ///< Append a message to the end of the stream
|
|
virtual GameMessage *insertMessage( GameMessage::Type type, GameMessage *messageToInsertAfter ); // Insert message after messageToInsertAfter.
|
|
|
|
// Methods NOT Inherited ------------------------------------------------------------------------
|
|
void propagateMessages( void ); ///< Propagate messages through attached translators
|
|
|
|
/**
|
|
Attach a translator function to the stream at a priority value. Lower priorities are executed first.
|
|
Note that MessageStream assumes ownership of the translator, and is responsible for freeing it!
|
|
*/
|
|
TranslatorID attachTranslator( GameMessageTranslator *translator, UnsignedInt priority);
|
|
GameMessageTranslator* findTranslator( TranslatorID id );
|
|
void removeTranslator( TranslatorID ); ///< Remove a previously attached translator
|
|
|
|
protected:
|
|
|
|
struct TranslatorData
|
|
{
|
|
TranslatorData *m_next, *m_prev; ///< List links for list of translators
|
|
TranslatorID m_id; ///< The unique ID of this translator
|
|
GameMessageTranslator *m_translator; ///< The translor's interface function
|
|
UnsignedInt m_priority; ///< The priority level of this translator
|
|
|
|
TranslatorData() : m_next(0), m_prev(0), m_id(0), m_translator(0), m_priority(0)
|
|
{
|
|
}
|
|
|
|
~TranslatorData()
|
|
{
|
|
delete m_translator;
|
|
}
|
|
};
|
|
|
|
TranslatorData *m_firstTranslator; ///< List of registered translators, in order of priority
|
|
TranslatorData *m_lastTranslator;
|
|
TranslatorID m_nextTranslatorID; ///< For issuing unique translator ID's
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* The CommandList is the final set of messages that have made their way through
|
|
* all of the Translators of the MessageStream, and reached the end.
|
|
* This set of commands will be executed by the GameLogic on its next iteration.
|
|
*/
|
|
class CommandList : public GameMessageList
|
|
{
|
|
public:
|
|
CommandList( void );
|
|
virtual ~CommandList();
|
|
|
|
virtual void init( void ); ///< Init command list
|
|
virtual void reset( void ); ///< Destroy all messages and reset list to empty
|
|
virtual void update( void ); ///< Update hook
|
|
|
|
void appendMessageList( GameMessage *list ); ///< Adds messages to the end of the command list
|
|
|
|
protected:
|
|
|
|
void destroyAllMessages( void ); ///< The meat of a reset and a shutdown
|
|
|
|
};
|
|
|
|
//
|
|
// The message stream that filters client input into game commands
|
|
//
|
|
extern MessageStream *TheMessageStream;
|
|
|
|
//
|
|
// The list of commands awaiting execution by the GameLogic
|
|
//
|
|
extern CommandList *TheCommandList;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
// Functions used in multiple translators should go here.
|
|
//
|
|
|
|
/**
|
|
* Given an "anchor" point and the current mouse position (dest),
|
|
* construct a valid 2D bounding region.
|
|
*/
|
|
extern void buildRegion( const ICoord2D *anchor, const ICoord2D *dest, IRegion2D *region );
|
|
|
|
#endif // _MESSAGE_STREAM_H_
|