/*============================================================================= Name : select.h Purpose : Logic for selecting ships and groups of ships. Created 7/2/1997 by lmoloney Copyright Relic Entertainment, Inc. All rights reserved. =============================================================================*/ #ifndef ___SELECT_H #define ___SELECT_H #include "types.h" #include "prim2d.h" #include "matrix.h" #include "spaceobj.h" #include "commandlayer.h" #include "camera.h" #include "font.h" #include "pieplate.h" /*============================================================================= Switches: =============================================================================*/ #ifndef HW_Release #define SEL_DRAW_BOXES 1 #define SEL_ERROR_CHECKING 1 //general error checking #else //HW_Debug #define SEL_ERROR_CHECKING 0 //general error checking #endif //HW_Debug /*============================================================================= Definitions: =============================================================================*/ //smallest box within which mouse movement is a click, not a drag #define SEL_ClickBoxWidth 6 #define SEL_ClickBoxHeight 6 //amount of selection circle which needs to be inside selection rectangle for it to be selected/deselected #define SEL_BandBoxInsideIn 0.2f #define SEL_BandBoxInsideOut 0.25f #define SEL_ClickMargin 4 //'fuzzy' logic for selection #define SEL_DragMargin 1 //'fuzzy' logic for drag-selecting #define SEL_NumberSelections COMMAND_MAX_SHIPS #define SEL_NumberHotKeyGroups 10 extern real32 SEL_MinSelectionRadius; #define SEL_SelectedColor colRGB(100, 200, 200) #define SEL_SelectingColor colRGB(75, 150, 150) #define SEL_OutlineColor colRGB(75, 75, 95) #define SEL_ShipHealthGreen colRGB(107, 227, 99) #define SEL_ShipHealthYellow colRGB(213, 215, 29) #define SEL_ShipHealthRed colRGB(215, 29, 29) #define SEL_ShipHealthDarkGreen colRGB(107 * 2 / 3, 227 * 2 / 3, 99 * 2 / 3) #define SEL_ShipHealthDarkYellow colRGB(213 * 2 / 3, 215 * 2 / 3, 29 * 2 / 3) #define SEL_ShipHealthDarkRed colRGB(213 * 2 / 3, 29 * 2 / 3, 29 * 2 / 3) #define SEL_ShipHealthSolidGreen colRGB(107 * 2 / 3, 227 * 2 / 3, 99 * 2 / 3) #define SEL_ShipHealthSolidYellow colRGB(213 * 2 / 3, 215 * 2 / 3, 29 * 2 / 3) #define SEL_ShipHealthSolidRed colRGB(213 * 2 / 3, 29 * 2 / 3, 29 * 2 / 3) #define SEL_FuelGreen colRGB(44, 62, 249) #define SEL_FuelDarkGreen colRGB(44 * 2 / 3, 62 * 2 / 3, 249 * 2 / 3) #define SEL_FuelGreenFactor 0.2f #define SEL_ShipHealthGreenFactor 0.5f #define SEL_ShipHealthYellowFactor 0.25f #define SEL_SelectionWidthFactor0 0.7f #define SEL_NumberLOD 6 #define SEL_AsteroidMoveNeartoSize 300.0f #define SEL_DepthSelectMultiplier 3.5f //hot-key group definitions #define SEL_InvalidHotKey 0xf #define SEL_HotKeyNumberBits 5 #define SEL_HotKeyNumberMask 0xf #define SEL_HotKeyGroupsMask 0x7fe0 #define SEL_HotKeyNumberColor colRGB(250, 250, 250) #define SEL_NumberMargin 3 #define SEL_ReinforceFactor 215/256 /*============================================================================= Data: =============================================================================*/ //script-adjustable parameters extern sdword selClickBoxWidth; extern sdword selClickBoxHeight; extern real32 selBandBoxInsideIn; extern real32 selBandBoxInsideOut; //selection lists extern MaxSelection selSelected; extern MaxAnySelection selSelecting; extern MaxSelection selHotKeyGroup[SEL_NumberHotKeyGroups]; //centre of selection extern vector selCentrePoint; extern real32 selAverageSize; //camera-space location of centre point of ship most recently considered for selection extern hvector selCameraSpace; //fonts used for printing group numbers extern fonthandle selGroupFont0; extern fonthandle selGroupFont1; extern fonthandle selGroupFont2; extern fonthandle selGroupFont3; //hot-key number stuff extern color selHotKeyNumberColor; extern udword selNumberMargin; extern char *selHotKeyString[10]; #if PIE_MOVE_NEARTO //movement mechanism 'move near to' stuff extern SpaceObjRotImpTarg *selClosestTarget; extern sdword selClosestDistance; #endif //PIE_MOVE_NEARTO /*============================================================================= Macros: =============================================================================*/ #define selRectNone() selSelecting.numTargets = 0 #define selSelectNone() selSelected.numShips = 0; \ ioUpdateShipTotals() #define selRectDrag(c, r) selRectDragFunction(universe.RenderList.head, (c), (r), selSelecting.TargetPtr, &selSelecting.numTargets, TRUE, FALSE, FALSE) #define selRectDragAnywhere(c, r) selRectDragFunction(universe.SpaceObjList.head, (c), (r), selSelecting.TargetPtr, &selSelecting.numTargets, TRUE, FALSE, FALSE) #define selRectSelect(c, r) selRectDragFunction(universe.RenderList.head, (c), (r), (SpaceObjRotImpTarg **)selSelected.ShipPtr, &selSelected.numShips, TRUE, FALSE, FALSE); \ ioUpdateShipTotals() #define selRectDragAnybody(c, r) selRectDragFunction(universe.RenderList.head, (c), (r), selSelecting.TargetPtr, &selSelecting.numTargets, FALSE, FALSE, FALSE) #define selRectDragAnybodyAnywhere(c, r) selRectDragFunction(universe.SpaceObjList.head, (c), (r), selSelecting.TargetPtr, &selSelecting.numTargets, FALSE, FALSE, FALSE) #define selRectSelectAnybody(c, r) selRectDragFunction(universe.RenderList.head, (c), (r), (SpaceObjRotImpTarg **)selSelected.ShipPtr, &selSelected.numShips, FALSE, FALSE, FALSE); \ ioUpdateShipTotals() #define selRectDragAnybodyToAttack(c, r) selRectDragFunction(universe.RenderList.head, (c), (r), selSelecting.TargetPtr, &selSelecting.numTargets, FALSE, FALSE, TRUE) #define selRectDragAnybodyAnywhereToAttack(c, r) selRectDragFunction(universe.SpaceObjList.head, (c), (r), selSelecting.TargetPtr, &selSelecting.numTargets, FALSE, FALSE, TRUE) #define selRectSelectAnybodyToAttack(c, r) selRectDragFunction(universe.RenderList.head, (c), (r), (SpaceObjRotImpTarg **)selSelected.ShipPtr, &selSelected.numShips, FALSE, FALSE, TRUE); \ ioUpdateShipTotals() #define selRectDragAnything(c, r) selRectDragFunction(universe.RenderList.head, (c), (r), selSelecting.TargetPtr, &selSelecting.numTargets, FALSE, TRUE, FALSE) #define selRectSelectAnything(c, r) selRectDragFunction(universe.RenderList.head, (c), (r), selSelected.ShipPtr, &selSelected.numShips, FALSE, TRUE, FALSE); \ ioUpdateShipTotals() #define selRectDragAnythingToAttack(c, r) selRectDragFunction(universe.RenderList.head, (c), (r), selSelecting.TargetPtr, &selSelecting.numTargets, FALSE, TRUE, TRUE) #define selRectSelectAnythingToAttack(c, r) selRectDragFunction(universe.RenderList.head, (c), (r), selSelected.ShipPtr, &selSelected.numShips, FALSE, TRUE, TRUE); \ ioUpdateShipTotals() #define selRectSelectAdd(c, r) selRectDragAddFunction(universe.RenderList.head, (c), (r)) #define selSelectionSize(n) (sizeof(SelectCommand) + ((n) - 1) * sizeof(ShipPtr)) #define selSelectionNumber(size) (((size) - sizeof(sdword)) / sizeof(ShipPtr)) //#define selHotKeyNumber(n) ((uword)((n) | SEL_HotKeyBit)) //set/test/clear the active hot key group number. This number appears on the selection overlay #define selHotKeyGroupNumberSet(ship, n) ((ship)->hotKeyGroup = ((ship)->hotKeyGroup & (~SEL_HotKeyNumberMask)) + (n) + 1) #define selHotKeyGroupNumberTest(ship) (((ship)->hotKeyGroup - 1) & SEL_HotKeyNumberMask) #define selHotKeyGroupNumberClear(ship) ((ship)->hotKeyGroup = (ship)->hotKeyGroup & (~SEL_HotKeyNumberMask)) //set/test/clear bits corresponding to hot-key groups #define selHotKeySet(ship, n) bitSet((ship)->hotKeyGroup, (1 << (SEL_HotKeyNumberBits + (n)))) #define selHotKeyTest(ship, n) bitTest((ship)->hotKeyGroup, (1 << (SEL_HotKeyNumberBits + (n)))) #define selHotKeyClear(ship, n) bitClear((ship)->hotKeyGroup, (1 << (SEL_HotKeyNumberBits + (n)))) #define selAnyHotKeyTest(ship) ((ship)->hotKeyGroup & SEL_HotKeyGroupsMask) #define selHotKeyClearAll(ship) ((ship)->hotKeyGroup &= SEL_HotKeyNumberMask) /*============================================================================= Functions: =============================================================================*/ //startup/shutdown void selStartup(void); void selShutdown(void); void selReset(void); //compute screen size/location of selection circle for selected ship or mission sphere void selCircleComputeGeneral(hmatrix *modelView, hmatrix *projection, vector *location, real32 radius, real32 *destX, real32 *destY, real32 *destRadius); void selCircleCompute(hmatrix *modelView, hmatrix *projection, SpaceObjRotImpTarg *target); //explicit selections void selSelectionSetSingleShip(Ship *ship); void selSelectionAddSingleShip(MaxSelection *dest, Ship *ship); //void selSelectionAddSingleShip(Ship *ship); void selSelectionRemoveSingleShip(MaxSelection *dest, Ship *ship); sdword selShipInSelection(ShipPtr *shipList, sdword nShips, ShipPtr ship); bool selShipsInSelection(MaxSelection *dest, MaxSelection *list); //selections by mouse dragging void selRectDragFunction(Node *startNode, Camera *camera, rectangle *rect, SpaceObjRotImpTarg **destList, sdword *destCount, sdword playerSpecific, bool selectAnything, bool bAttack); void selRectDragAddFunction(Node *startNode, Camera *camera, rectangle *rect); //selection by mouse click (on release) Ship *selSelectionClick(Node *listhead, Camera *camera, sdword x, sdword y, bool bIncludeDerelicts, bool bIncludeResources); SpaceObj *selClickFromArray(SpaceObj **list, sdword length, sdword x, sdword y); //selections by key //draw selected lists void selSelectedDraw(void); void selSelectingDraw(void); //commpute centre of selection vector selCentrePointComputeGeneral(MaxSelection *selection, real32 *average_size); //update selCentrePoint and selAverageSize void selCentrePointCompute(void); //on-screen position of a selection of ships void selSelectionDimensions(hmatrix *modelView, hmatrix *projection, SelectCommand *selection, real32 *destX, real32 *destY, real32 *destRad); //selection manipulation sdword selSelectionCopy(MaxAnySelection *dest, MaxAnySelection *source); bool selSelectionIsReinforced(MaxAnySelection *dest, MaxAnySelection *source); sdword selSelectionCopyByClass(MaxSelection *dest, MaxSelection *source, ShipClass classMask); sdword selSelectionCopyByType(MaxSelection *dest, MaxSelection *source, ShipType typeMask); sdword selHotKeyNumbersSet(sdword group); void selHotKeyGroupRemoveReferences(sdword group); void selHotKeyGroupRemoveReferencesFromAllGroups(void); sdword selSelectionCompare(MaxAnySelection *s0, MaxAnySelection *s1); #if SEL_ERROR_CHECKING void selHotKeyGroupsVerify(void); #endif void selSelectHotKeyGroup(MaxSelection *hotkeygroup); //debug functions #if SEL_DRAW_BOXES void selDrawBoxes(SpaceObjRotImpTarg *target); #endif #endif //___SELECT_H