2007-01-15 12:09:25 -08:00
|
|
|
/*
|
|
|
|
This file is part of Warzone 2100.
|
|
|
|
Copyright (C) 1999-2004 Eidos Interactive
|
|
|
|
Copyright (C) 2005-2007 Warzone Resurrection Project
|
|
|
|
|
|
|
|
Warzone 2100 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 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
Warzone 2100 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 Warzone 2100; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
2007-06-28 10:47:08 -07:00
|
|
|
/*
|
|
|
|
* Display.c
|
|
|
|
*
|
|
|
|
* Display routines.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
#include "lib/framework/frame.h"
|
2006-09-23 10:24:55 -07:00
|
|
|
#include "lib/framework/input.h"
|
|
|
|
#include "lib/framework/strres.h"
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "display.h"
|
|
|
|
#include "map.h"
|
|
|
|
#include "loop.h"
|
|
|
|
#include "atmos.h" // temporary only for here
|
|
|
|
#include "csnap.h"
|
|
|
|
/* Includes direct access to render library */
|
2006-05-27 09:37:17 -07:00
|
|
|
#include "lib/ivis_common/piedef.h"
|
|
|
|
#include "lib/ivis_common/piestate.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
// FIXME Direct iVis implementation include!
|
2006-08-11 15:08:48 -07:00
|
|
|
#include "lib/ivis_common/rendmode.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
#include "lib/ivis_common/tex.h"//make a call for this
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "component.h"
|
|
|
|
#include "display3d.h"
|
|
|
|
#include "resource.h"
|
|
|
|
#include "hci.h"
|
|
|
|
#include "text.h"
|
|
|
|
#include "edit3d.h"
|
|
|
|
#include "geometry.h"
|
2006-05-27 09:37:17 -07:00
|
|
|
#include "lib/gamelib/gtime.h"
|
|
|
|
#include "lib/sound/audio.h"
|
2007-03-27 11:59:03 -07:00
|
|
|
#include "lib/sound/audio_id.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "radar.h"
|
|
|
|
#include "miscimd.h"
|
|
|
|
#include "lighting.h"
|
2006-05-27 09:37:17 -07:00
|
|
|
#include "lib/framework/fractions.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "console.h"
|
|
|
|
#include "order.h"
|
|
|
|
#include "wrappers.h"
|
|
|
|
#include "power.h"
|
|
|
|
#include "map.h"
|
|
|
|
#include "keymap.h"
|
|
|
|
#include "intimage.h"
|
|
|
|
#include "mechanics.h"
|
|
|
|
#include "ingameop.h"
|
|
|
|
#include "oprint.h"
|
|
|
|
#include "warcam.h"
|
|
|
|
#include "keybind.h"
|
|
|
|
#include "keymap.h"
|
|
|
|
#include "projectile.h"
|
|
|
|
#include "message.h"
|
|
|
|
#include "effects.h"
|
2006-05-27 09:37:17 -07:00
|
|
|
#include "lib/script/script.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "scripttabs.h"
|
|
|
|
#include "scriptextern.h"
|
|
|
|
#include "scriptcb.h"
|
|
|
|
#include "target.h"
|
|
|
|
#include "drive.h"
|
|
|
|
#include "cmddroid.h"
|
|
|
|
#include "gateway.h"
|
|
|
|
#include "selection.h"
|
|
|
|
#include "transporter.h"
|
|
|
|
#include "intorder.h"
|
|
|
|
|
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
#include "lib/ivis_common/pieclip.h" // ffs am
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "multiplay.h"
|
|
|
|
|
|
|
|
#define SHAKE_TIME (1500)
|
|
|
|
|
|
|
|
#define TD_SCROLL_DIV 2
|
|
|
|
|
|
|
|
//#define TEST_EFFECT // Kick off an effect when left mouse button pressed.
|
|
|
|
|
|
|
|
struct _dragBox dragBox3D,wallDrag;
|
|
|
|
|
|
|
|
// control whether the scroll is limited to visible tiles
|
|
|
|
//#define VISIBLE_SCROLL
|
|
|
|
|
|
|
|
#define POSSIBLE_SELECTIONS 13
|
|
|
|
#define POSSIBLE_TARGETS 23
|
|
|
|
|
|
|
|
UDWORD arnMPointers[POSSIBLE_TARGETS][POSSIBLE_SELECTIONS] =
|
|
|
|
{
|
|
|
|
// empty terrain tile
|
|
|
|
{IDC_MOVE,IDC_MOVE,IDC_MOVE,IDC_MOVE,IDC_MOVE,IDC_MOVE,IDC_MOVE,IDC_MOVE,IDC_MOVE,
|
|
|
|
IDC_BOMB,IDC_NOTPOSSIBLE,IDC_MOVE,IDC_MOVE},
|
|
|
|
// resource tile
|
|
|
|
{IDC_BUILD,IDC_MOVE,IDC_MOVE,IDC_MOVE,IDC_MOVE,IDC_MOVE,IDC_MOVE,IDC_MOVE,IDC_MOVE,
|
|
|
|
IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE},
|
|
|
|
// impassible tile
|
|
|
|
{IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,
|
|
|
|
IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,
|
|
|
|
IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE},
|
|
|
|
// river tile
|
|
|
|
{IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,
|
|
|
|
IDC_BRIDGE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,
|
|
|
|
IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE},
|
|
|
|
// trench tile
|
|
|
|
{IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,
|
|
|
|
IDC_BRIDGE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,
|
|
|
|
IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE},
|
|
|
|
// damaged friendly structure
|
|
|
|
{IDC_FIX,IDC_GUARD,IDC_GUARD,IDC_GUARD,IDC_GUARD,IDC_GUARD,IDC_MOVE,IDC_MOVE,
|
|
|
|
IDC_GUARD,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_DEST,IDC_MOVE},
|
|
|
|
// undamaged friendly structure
|
|
|
|
{IDC_NOTPOSSIBLE,IDC_GUARD,IDC_GUARD,IDC_GUARD,IDC_GUARD,IDC_GUARD,IDC_MOVE,IDC_MOVE,
|
|
|
|
IDC_GUARD,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_DEST,IDC_MOVE},
|
|
|
|
// partially built friendly structure
|
|
|
|
{IDC_BUILD,IDC_GUARD,IDC_GUARD,IDC_GUARD,IDC_GUARD,IDC_GUARD,IDC_MOVE,IDC_MOVE,
|
|
|
|
IDC_GUARD,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_DEST,IDC_MOVE},
|
|
|
|
// friendly repair facility
|
|
|
|
{IDC_SEEKREPAIR,IDC_SEEKREPAIR,IDC_SEEKREPAIR,IDC_SEEKREPAIR,IDC_SEEKREPAIR,
|
|
|
|
IDC_SEEKREPAIR,IDC_SEEKREPAIR,IDC_SEEKREPAIR,IDC_SEEKREPAIR,IDC_SEEKREPAIR,
|
|
|
|
IDC_NOTPOSSIBLE,IDC_DEST,IDC_SEEKREPAIR},
|
|
|
|
// friendly damagedrepair facility
|
|
|
|
{IDC_FIX,IDC_SEEKREPAIR,IDC_SEEKREPAIR,IDC_SEEKREPAIR,IDC_SEEKREPAIR,
|
|
|
|
IDC_SEEKREPAIR,IDC_SEEKREPAIR,IDC_SEEKREPAIR,IDC_SEEKREPAIR,IDC_SEEKREPAIR,
|
|
|
|
IDC_NOTPOSSIBLE,IDC_DEST,IDC_SEEKREPAIR},
|
|
|
|
// enemy structure
|
|
|
|
{IDC_MOVE,IDC_ATTACK,IDC_ATTACK,IDC_ATTACK,IDC_LOCKON,IDC_JAM,IDC_ATTACK,
|
|
|
|
IDC_ATTACK,IDC_ATTACK,IDC_BOMB,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_MOVE},
|
|
|
|
// transport
|
|
|
|
{IDC_EMBARK,IDC_EMBARK,IDC_EMBARK,IDC_EMBARK,IDC_EMBARK,IDC_EMBARK,IDC_EMBARK,
|
|
|
|
IDC_EMBARK,IDC_EMBARK,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_EMBARK},
|
|
|
|
// friendly droid
|
|
|
|
{IDC_SELECT,IDC_SELECT,IDC_SELECT,IDC_SELECT,IDC_SELECT,IDC_SELECT,IDC_SELECT,
|
|
|
|
IDC_SELECT,IDC_SELECT,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_SELECT},
|
|
|
|
// damaged friendly droid
|
|
|
|
{IDC_SELECT,IDC_SELECT,IDC_SELECT,IDC_SELECT,IDC_SELECT,IDC_SELECT,IDC_SELECT,
|
|
|
|
IDC_PICKUP,IDC_SELECT,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_FIX},
|
|
|
|
// enemy droid
|
|
|
|
{IDC_MOVE,IDC_ATTACK,IDC_ATTACK,IDC_ATTACK,IDC_LOCKON,IDC_JAM,IDC_MOVE,
|
|
|
|
IDC_MOVE,IDC_ATTACK,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_MOVE},
|
|
|
|
// command droid
|
|
|
|
{IDC_SELECT,IDC_ATTACH,IDC_ATTACH,IDC_ATTACH,IDC_ATTACH,IDC_ATTACH,IDC_ATTACH,
|
|
|
|
IDC_ATTACH,IDC_SELECT,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_ATTACH},
|
|
|
|
// artefact
|
|
|
|
{IDC_PICKUP,IDC_PICKUP,IDC_PICKUP,IDC_PICKUP,IDC_PICKUP,IDC_PICKUP,IDC_PICKUP,
|
|
|
|
IDC_PICKUP,IDC_PICKUP,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_PICKUP,IDC_PICKUP},
|
|
|
|
// feature that can be damaged ie attacked
|
|
|
|
{IDC_NOTPOSSIBLE,IDC_ATTACK,IDC_ATTACK,IDC_ATTACK,IDC_LOCKON,IDC_NOTPOSSIBLE,
|
|
|
|
IDC_NOTPOSSIBLE,IDC_ATTACK,IDC_ATTACK,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,
|
|
|
|
IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE},
|
|
|
|
// sensor droid
|
|
|
|
{IDC_SELECT,IDC_GUARD,IDC_LOCKON,IDC_SELECT,IDC_SELECT,IDC_SELECT,IDC_SELECT,
|
|
|
|
IDC_SELECT,IDC_SELECT,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_FIX},
|
|
|
|
// wrecked building feature
|
|
|
|
{IDC_DEST,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,
|
|
|
|
IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,
|
|
|
|
IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE},
|
|
|
|
// construction droid
|
|
|
|
{IDC_SELECT,IDC_GUARD,IDC_SELECT,IDC_SELECT,IDC_SELECT,IDC_SELECT,IDC_SELECT,
|
|
|
|
IDC_SELECT,IDC_SELECT,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_FIX},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// sensor structure
|
|
|
|
{IDC_BUILD,IDC_GUARD,IDC_LOCKON,IDC_GUARD,IDC_GUARD,IDC_GUARD,IDC_MOVE,IDC_MOVE,
|
|
|
|
IDC_GUARD,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_DEST,IDC_MOVE},
|
|
|
|
|
|
|
|
// damaged sensor structure.
|
|
|
|
{IDC_FIX,IDC_GUARD,IDC_LOCKON,IDC_GUARD,IDC_GUARD,IDC_GUARD,IDC_MOVE,IDC_MOVE,
|
|
|
|
IDC_GUARD,IDC_NOTPOSSIBLE,IDC_NOTPOSSIBLE,IDC_DEST,IDC_MOVE},
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
UWORD MPointerImageIDs[]={
|
|
|
|
IMAGE_CURSOR_DEST, // IDC_DEST
|
|
|
|
IMAGE_CURSOR_DEFAULT, // IDC_SIGHT
|
|
|
|
IMAGE_CURSOR_DEFAULT, // IDC_TARGET
|
2006-05-27 09:37:17 -07:00
|
|
|
IMAGE_CURSOR_DEFAULT, // IDC_LARROW
|
|
|
|
IMAGE_CURSOR_DEFAULT, // IDC_RARROW
|
|
|
|
IMAGE_CURSOR_DEFAULT, // IDC_DARROW
|
|
|
|
IMAGE_CURSOR_DEFAULT, // IDC_UARROW
|
|
|
|
IMAGE_CURSOR_DEFAULT, // IDC_DEFAULT
|
|
|
|
IMAGE_CURSOR_DEFAULT, // IDC_EDGEOFMAP
|
|
|
|
IMAGE_CURSOR_ATTACH, // IDC_ATTACH
|
|
|
|
IMAGE_CURSOR_ATTACK, // IDC_ATTACK
|
|
|
|
IMAGE_CURSOR_DEFAULT, // IDC_BOMB
|
|
|
|
IMAGE_CURSOR_BRIDGE, // IDC_BRIDGE
|
|
|
|
IMAGE_CURSOR_BUILD, // IDC_BUILD
|
|
|
|
IMAGE_CURSOR_EMBARK, // IDC_EMBARK
|
|
|
|
IMAGE_CURSOR_FIX, // IDC_FIX
|
|
|
|
IMAGE_CURSOR_GUARD, // IDC_GUARD
|
|
|
|
IMAGE_CURSOR_ECM, // IDC_JAM
|
|
|
|
IMAGE_CURSOR_LOCKON, // IDC_LOCKON
|
|
|
|
IMAGE_CURSOR_DEFAULT, // IDC_MENU
|
|
|
|
IMAGE_CURSOR_MOVE, // IDC_MOVE
|
|
|
|
IMAGE_CURSOR_NOTPOS, // IDC_NOTPOSSIBLE
|
|
|
|
IMAGE_CURSOR_PICKUP, // IDC_PICKUP
|
|
|
|
IMAGE_CURSOR_REPAIR, // IDC_SEEKREPAIR
|
|
|
|
IMAGE_CURSOR_SELECT, // IDC_SELECT
|
2007-06-28 10:47:08 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
UDWORD scroll_speed_accel=800; // acceleration on scrolling. Game Option.
|
|
|
|
|
|
|
|
BOOL buildingDamaged(STRUCTURE *psStructure);
|
|
|
|
static BOOL repairDroidSelected(UDWORD player);
|
|
|
|
//static DROID *constructorDroidSelected(UDWORD player);
|
|
|
|
static BOOL vtolDroidSelected(UDWORD player);
|
|
|
|
static BOOL anyDroidSelected(UDWORD player);
|
|
|
|
static BOOL cyborgDroidSelected(UDWORD player);
|
|
|
|
//static BOOL ctrlShiftDown(void);
|
|
|
|
static BOOL bInvertMouse = TRUE;
|
2006-02-28 06:04:59 -08:00
|
|
|
static BOOL bDrawShadows = TRUE;
|
2007-06-28 10:47:08 -07:00
|
|
|
//BOOL widgetsOn=TRUE; //FALSE;
|
|
|
|
//BOOL forceWidgetsOn = FALSE;
|
|
|
|
SELECTION_TYPE establishSelection(UDWORD selectedPlayer);
|
|
|
|
void dealWithLMB( void );
|
|
|
|
void dealWithLMBDClick( void );
|
|
|
|
void dealWithRMB( void );
|
|
|
|
BOOL mouseInBox(SDWORD x0, SDWORD y0, SDWORD x1, SDWORD y1);
|
|
|
|
BASE_OBJECT *mouseTarget( void );
|
|
|
|
OBJECT_POSITION * checkMouseLoc(void);
|
|
|
|
|
|
|
|
/* Mouse x and y - no point checking them more than once per frame */
|
2007-05-29 19:06:46 -07:00
|
|
|
Uint16 mouseXPos = OFF_SCREEN, mouseYPos = OFF_SCREEN;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
BOOL bInstantRadarJump = FALSE;
|
|
|
|
|
|
|
|
BOOL rotActive = FALSE;
|
|
|
|
SDWORD desiredPitch = 340;
|
|
|
|
UDWORD currentFrame;
|
|
|
|
static UDWORD StartOfLastFrame;
|
|
|
|
SDWORD rotX;
|
|
|
|
SDWORD rotY;
|
|
|
|
UDWORD worldAngle;
|
|
|
|
UDWORD rotInitial;
|
|
|
|
UDWORD rotInitialUp;
|
|
|
|
UDWORD xMoved,yMoved;
|
|
|
|
//DROID *psSelected3D = NULL;
|
|
|
|
BOOL gameStats = FALSE;
|
|
|
|
STRUCTURE *psBuilding;
|
|
|
|
SDWORD direction = 0;
|
|
|
|
BOOL edgeOfMap = FALSE;
|
|
|
|
UDWORD scrollRefTime;
|
|
|
|
float scrollAccel;
|
|
|
|
float scrollSpeedLeftRight; //use two directions and add them because its simple
|
|
|
|
float scrollStepLeftRight;
|
|
|
|
float scrollSpeedUpDown;
|
|
|
|
float scrollStepUpDown;
|
|
|
|
BOOL noDrag3D;
|
|
|
|
BOOL mouseOverRadar = FALSE;
|
|
|
|
BOOL mouseOverConsole = FALSE;
|
|
|
|
BOOL ignoreOrder = FALSE;
|
|
|
|
BOOL ignoreRMBC = TRUE;
|
|
|
|
/* Hackety hack hack hack */
|
|
|
|
/* Has the big blue droid been added to the world? */
|
|
|
|
BOOL bigBlueInWorld = FALSE;
|
|
|
|
BOOL missionComplete = FALSE;
|
|
|
|
UWORD RadarZoomLevel = 0;
|
2006-11-26 04:12:34 -08:00
|
|
|
int gammaValue = 20;
|
2007-06-28 10:47:08 -07:00
|
|
|
DROID *psSelectedVtol;
|
|
|
|
DROID *psDominantSelected;
|
|
|
|
|
|
|
|
BOOL CheckScrollLimits(void);
|
|
|
|
|
|
|
|
|
|
|
|
/* Hackety hack hack hack */
|
|
|
|
|
|
|
|
SDWORD screenShakeTable[100] =
|
|
|
|
{
|
|
|
|
-2,-2,-3,-4,-3,-3,-5,-4,-4,-4,
|
|
|
|
-4,-5,-5,-5,-5,-7,-5,-6,-8,-6,
|
|
|
|
-7,-8,-6,-4,-8,-7,-7,-7,-6,-5,
|
|
|
|
-6,-5,-2,-5,-6,-3,-5,-3,-2,-4,
|
|
|
|
-5,-3,-2,-0,1,2,2,1,0,0,
|
|
|
|
0,1,1,3,2,1,0,2,3,4,
|
|
|
|
4,2,6,4,5,3,7,7,3,6,
|
|
|
|
4,7,9,10,9,8,6,4,7,5,
|
|
|
|
5,4,6,2,4,5,3,3,2,1,
|
|
|
|
1,0,-1,-1,-2,-1,1,0,1,0
|
|
|
|
};
|
|
|
|
|
|
|
|
#define TESTLEVEL_ID (0)
|
|
|
|
|
2007-02-10 08:39:39 -08:00
|
|
|
#define METAKEY_DOWN (keyDown(KEY_LALT) || keyDown(KEY_RALT) || keyDown(KEY_LSHIFT) || keyDown(KEY_RSHIFT) )
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
static BOOL bScreenShakeActive = FALSE;
|
|
|
|
static UDWORD screenShakeStarted;
|
|
|
|
static UDWORD screenShakeLength;
|
|
|
|
//used to determine is a weapon droid is assigned to a sensor tower or sensor droid
|
|
|
|
static BOOL bSensorAssigned;
|
|
|
|
//used to determine if the player has selected a Las Sat structure
|
|
|
|
static BOOL bLasSatStruct;
|
|
|
|
|
|
|
|
// Local prototypes
|
|
|
|
static MOUSE_TARGET itemUnderMouse(BASE_OBJECT **ppObjUnderCursor);
|
|
|
|
BOOL bShakingPermitted = TRUE;
|
|
|
|
|
|
|
|
void setRadarJump(BOOL val)
|
|
|
|
{
|
|
|
|
bInstantRadarJump = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL getRadarJumpStatus( void )
|
|
|
|
{
|
|
|
|
return(bInstantRadarJump);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL getShakeStatus( void )
|
|
|
|
{
|
|
|
|
return(bShakingPermitted);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL getInvertMouseStatus( void )
|
|
|
|
{
|
|
|
|
return(bInvertMouse);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setInvertMouseStatus( BOOL val )
|
|
|
|
{
|
|
|
|
bInvertMouse = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-02-28 06:04:59 -08:00
|
|
|
BOOL getDrawShadows( void )
|
|
|
|
{
|
|
|
|
return(bDrawShadows);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setDrawShadows( BOOL val )
|
|
|
|
{
|
|
|
|
bDrawShadows = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
void setShakeStatus( BOOL val )
|
|
|
|
{
|
|
|
|
bShakingPermitted = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void shakeStart(void)
|
|
|
|
{
|
|
|
|
if(bShakingPermitted)
|
|
|
|
{
|
|
|
|
if(!bScreenShakeActive)
|
|
|
|
{
|
|
|
|
bScreenShakeActive = TRUE;
|
|
|
|
screenShakeStarted = gameTime;
|
|
|
|
screenShakeLength = SHAKE_TIME;//1500;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void shakeStop(void)
|
|
|
|
{
|
|
|
|
bScreenShakeActive = FALSE;
|
|
|
|
player.r.z = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-20 08:18:37 -07:00
|
|
|
static void shakeUpdate(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
UDWORD screenShakePercentage;
|
|
|
|
|
|
|
|
/* Check if we're shaking the screen or not */
|
|
|
|
if(bScreenShakeActive)
|
|
|
|
{
|
|
|
|
// screenShakePercentage = (((gameTime-screenShakeStarted)<<8) / screenShakeLength) * 100;
|
|
|
|
screenShakePercentage = PERCENT(gameTime2-screenShakeStarted,screenShakeLength);
|
|
|
|
// screenShakePercentage = screenShakePercentage >> 8;
|
|
|
|
|
|
|
|
if(screenShakePercentage<100)
|
|
|
|
{
|
|
|
|
player.r.z = 0 + DEG(screenShakeTable[screenShakePercentage]);
|
|
|
|
}
|
|
|
|
if(gameTime>(screenShakeStarted+screenShakeLength))
|
|
|
|
{
|
|
|
|
bScreenShakeActive = FALSE;
|
|
|
|
player.r.z = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(!getWarCamStatus())
|
|
|
|
{
|
|
|
|
player.r.z = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL LoadLevelGraphics(UBYTE LevelNumber)
|
|
|
|
{
|
|
|
|
|
|
|
|
(void)LevelNumber;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialise the display system */
|
|
|
|
BOOL dispInitialise(void)
|
|
|
|
{
|
|
|
|
noDrag3D = FALSE;
|
|
|
|
RadarZoomLevel = 0;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2007-05-12 09:10:20 -07:00
|
|
|
BOOL bRadarDragging = FALSE;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
void ProcessRadarInput(void)
|
|
|
|
{
|
|
|
|
SDWORD PosX,PosY;
|
|
|
|
int x = mouseX();
|
|
|
|
int y = mouseY();
|
|
|
|
UDWORD temp1,temp2;
|
|
|
|
|
|
|
|
/* Only allow jump-to-area-of-map if radar is on-screen */
|
|
|
|
mouseOverRadar = FALSE;
|
2007-02-10 08:39:39 -08:00
|
|
|
if(radarOnScreen && getHQExists(selectedPlayer))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2006-05-27 09:37:17 -07:00
|
|
|
if(CoordInRadar(x,y))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
mouseOverRadar = TRUE;
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
if (mousePressed(MOUSE_LMB))
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
if(driveModeActive()) {
|
|
|
|
driveProcessRadarInput(x,y);
|
|
|
|
} else {
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
/* If we're tracking a droid, then cancel that */
|
|
|
|
// if(getWarCamStatus() == TRUE)
|
|
|
|
// {
|
|
|
|
// camToggleStatus();
|
|
|
|
// }
|
|
|
|
CalcRadarPosition(x,y,(UDWORD *)&PosX,(UDWORD *)&PosY);
|
|
|
|
if(mouseOverRadar)
|
|
|
|
{
|
|
|
|
// requestRadarTrack(PosX*TILE_UNITS,PosY*TILE_UNITS);
|
|
|
|
// MARKER
|
|
|
|
// Send all droids to that location
|
|
|
|
orderSelectedLoc(selectedPlayer, (PosX*TILE_UNITS)+TILE_UNITS/2,
|
|
|
|
(PosY*TILE_UNITS)+TILE_UNITS/2);
|
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
// setViewPos(PosX,PosY);
|
2007-05-29 19:06:46 -07:00
|
|
|
CheckScrollLimits();
|
|
|
|
audio_PlayTrack( ID_SOUND_MESSAGEEND );
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
|
2007-02-10 08:39:39 -08:00
|
|
|
if(mouseDrag(MOUSE_RMB,&temp1,&temp2) && !rotActive)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
CalcRadarPosition(x,y,(UDWORD*)&PosX,(UDWORD*)&PosY);
|
2007-06-28 10:47:08 -07:00
|
|
|
setViewPos(PosX,PosY,TRUE);
|
|
|
|
bRadarDragging = TRUE;
|
2007-02-10 08:39:39 -08:00
|
|
|
if(keyDown(KEY_LCTRL) || keyDown(KEY_RCTRL))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
player.r.y = 0;
|
|
|
|
}
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
else if (mousePressed(MOUSE_RMB))
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
#ifdef RADAR_POSITION_AT_ZOOM
|
2007-05-29 19:06:46 -07:00
|
|
|
CalcRadarPosition(x,y,&PosX,&PosY);
|
|
|
|
setViewPos(PosX,PosY,TRUE);
|
|
|
|
CheckScrollLimits();
|
2007-06-28 10:47:08 -07:00
|
|
|
#endif
|
|
|
|
/*
|
2007-05-29 19:06:46 -07:00
|
|
|
RadarZoomLevel++;
|
|
|
|
if(RadarZoomLevel > MAX_RADARZOOM) {
|
|
|
|
RadarZoomLevel = 0;
|
|
|
|
}
|
|
|
|
SetRadarZoom(RadarZoomLevel);
|
|
|
|
audio_PlayTrack( ID_SOUND_BUTTON_CLICK_5 );
|
2007-06-28 10:47:08 -07:00
|
|
|
*/
|
|
|
|
CalcRadarPosition(x,y,(UDWORD*)&PosX,(UDWORD*)&PosY);
|
|
|
|
|
|
|
|
if(bInstantRadarJump)
|
|
|
|
{
|
|
|
|
/* Go instantly */
|
2006-05-27 09:37:17 -07:00
|
|
|
setViewPos(PosX,PosY,TRUE);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Pan to it */
|
|
|
|
requestRadarTrack(PosX*TILE_UNITS,PosY*TILE_UNITS);
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
}
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// reset the input state
|
|
|
|
void resetInput(void)
|
|
|
|
{
|
|
|
|
rotActive = FALSE;
|
|
|
|
dragBox3D.status = DRAG_INACTIVE;
|
|
|
|
wallDrag.status = DRAG_INACTIVE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Process the user input. This just processes the key input and jumping around the radar*/
|
|
|
|
void processInput(void)
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
BOOL mOverRadar = FALSE;
|
|
|
|
int WheelZoomIterator;
|
|
|
|
|
|
|
|
mouseXPos = mouseX();
|
|
|
|
mouseYPos = mouseY();
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
if(radarOnScreen && getHQExists(selectedPlayer) && CoordInRadar(mouseXPos, mouseYPos))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
mOverRadar = TRUE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
StartOfLastFrame = currentFrame;
|
|
|
|
currentFrame = frameGetFrameNumber();
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
psBuilding = NULL;
|
|
|
|
|
|
|
|
edgeOfMap = FALSE;
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
ignoreRMBC = FALSE;
|
|
|
|
|
|
|
|
/* Process all of our key mappings */
|
2007-05-29 19:06:46 -07:00
|
|
|
if (mousePressed(MOUSE_LMB) && !mOverRadar && getRadarTrackingStatus())
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
camToggleStatus();
|
|
|
|
}
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
if (mousePressed(MOUSE_LMB) && !mOverRadar && getRadarTrackingStatus())
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
camToggleStatus();
|
|
|
|
}
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
if (mousePressed(MOUSE_WUP))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2006-08-30 10:02:58 -07:00
|
|
|
/* CTRL+WheelUp makes game speed up */
|
2007-05-29 19:06:46 -07:00
|
|
|
if (keyDown(KEY_LCTRL))
|
2006-08-30 10:02:58 -07:00
|
|
|
{
|
|
|
|
kf_SpeedUp();
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
/* Decide if radar or world zoom in */
|
|
|
|
else if (mOverRadar)
|
|
|
|
{
|
|
|
|
kf_RadarZoomIn();
|
|
|
|
}
|
2006-08-30 10:02:58 -07:00
|
|
|
else
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
for (WheelZoomIterator = 0; WheelZoomIterator < 10; WheelZoomIterator++)
|
|
|
|
kf_ZoomIn();
|
2006-08-30 10:02:58 -07:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
if (mousePressed(MOUSE_WDN))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2006-08-30 10:02:58 -07:00
|
|
|
/* CTRL+WheelDown makes game slow down */
|
2007-05-29 19:06:46 -07:00
|
|
|
if (keyDown(KEY_LCTRL))
|
2006-08-30 10:02:58 -07:00
|
|
|
{
|
|
|
|
kf_SlowDown();
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
/* Decide if radar or world zoom out */
|
|
|
|
else if (mOverRadar)
|
2006-08-30 10:02:58 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
kf_RadarZoomOut();
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
for (WheelZoomIterator = 0; WheelZoomIterator < 10; WheelZoomIterator++)
|
|
|
|
kf_ZoomOut();
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
|
|
|
|
if (intMode == INT_DESIGN)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
/* Only process the function keys */
|
|
|
|
keyProcessMappings(TRUE);
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
else if (bAllowOtherKeyPresses)
|
|
|
|
{
|
|
|
|
/* Run all standard mappings */
|
|
|
|
keyProcessMappings(FALSE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
kf_SendTextMessage(); // process multiplayer chat message.
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
/* Allow the user to clear the console if need be */
|
|
|
|
mouseOverConsole = mouseOverConsoleBox();
|
2007-02-10 08:39:39 -08:00
|
|
|
if(mouseOverConsole && mousePressed(MOUSE_LMB))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
setConsolePermanence(FALSE, TRUE);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-14 06:15:40 -07:00
|
|
|
static BOOL OverRadarAndNotDragging(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2006-09-14 06:15:40 -07:00
|
|
|
BOOL OverRadar = mouseOverRadar;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
if(getHQExists(selectedPlayer)==FALSE)
|
|
|
|
{
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( (dragBox3D.status == DRAG_DRAGGING) || (wallDrag.status == DRAG_DRAGGING) ) {
|
|
|
|
OverRadar = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return OverRadar;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-14 06:15:40 -07:00
|
|
|
static void CheckFinishedDrag(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
if(driveModeActive()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mouseReleased(MOUSE_LMB))
|
|
|
|
{
|
|
|
|
selectAttempt = FALSE;
|
|
|
|
if(dragBox3D.status == DRAG_DRAGGING)
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
if(wallDrag.status == DRAG_DRAGGING)
|
|
|
|
{
|
|
|
|
//if invalid location keep looking for a valid one
|
|
|
|
if (buildState == BUILD3D_VALID || buildState == BUILD3D_FINISHED)
|
|
|
|
{
|
2007-05-30 11:03:26 -07:00
|
|
|
if ((((STRUCTURE_STATS *)sBuildDetails.psStats)->type == REF_WALL
|
|
|
|
|| ((STRUCTURE_STATS *)sBuildDetails.psStats)->type == REF_DEFENSE)
|
|
|
|
&& !isLasSat((STRUCTURE_STATS *)sBuildDetails.psStats))
|
2007-05-29 19:06:46 -07:00
|
|
|
{
|
|
|
|
wallDrag.x2 = mouseTileX;
|
|
|
|
wallDrag.y2 = mouseTileY;
|
|
|
|
wallDrag.status = DRAG_RELEASED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
/* Only clear if shift isn't down - this is for the drag selection box for units*/
|
2007-02-10 08:39:39 -08:00
|
|
|
if(!keyDown(KEY_LCTRL) && !keyDown(KEY_RCTRL)
|
|
|
|
&& !keyDown(KEY_LSHIFT) && !keyDown(KEY_RSHIFT) && wallDrag.status==DRAG_INACTIVE)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
clearSelection();
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
dragBox3D.status = DRAG_RELEASED;
|
|
|
|
dragBox3D.x2 = mouseXPos;
|
|
|
|
dragBox3D.y2 = mouseYPos;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
else
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
dragBox3D.status = DRAG_INACTIVE;
|
|
|
|
wallDrag.status = DRAG_INACTIVE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-14 06:15:40 -07:00
|
|
|
static void CheckStartWallDrag(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
if(driveModeActive()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mousePressed(MOUSE_LMB))
|
|
|
|
{
|
|
|
|
/* Store away the details if we're building */
|
|
|
|
// You can start dragging walls from invalid locations so check for
|
|
|
|
// BUILD3D_POS or BUILD3D_VALID, used tojust check for BUILD3D_VALID.
|
|
|
|
if( (buildState == BUILD3D_POS) || (buildState == BUILD3D_VALID) )
|
|
|
|
{
|
2007-05-30 11:03:26 -07:00
|
|
|
if ((((STRUCTURE_STATS *)sBuildDetails.psStats)->type == REF_WALL
|
|
|
|
|| ((STRUCTURE_STATS *)sBuildDetails.psStats)->type == REF_DEFENSE)
|
|
|
|
&& !isLasSat((STRUCTURE_STATS *)sBuildDetails.psStats))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
wallDrag.x1 = wallDrag.x2 = mouseTileX;
|
|
|
|
wallDrag.y1 = wallDrag.y2 = mouseTileY;
|
|
|
|
wallDrag.status = DRAG_PLACING;
|
2006-08-22 07:28:49 -07:00
|
|
|
debug( LOG_NEVER, "Start Wall Drag\n" );
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (intBuildSelectMode())//if we were in build select mode
|
|
|
|
{
|
|
|
|
//uhoh no place to build here
|
|
|
|
audio_PlayTrack(ID_SOUND_BUILD_FAIL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//this function is called when a location has been chosen to place a structure or a DP
|
2006-09-14 06:15:40 -07:00
|
|
|
static BOOL CheckFinishedFindPosition(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
BOOL OverRadar = OverRadarAndNotDragging();
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
/* Do not let the player position buildings 'under' the radar */
|
|
|
|
if(mouseReleased(MOUSE_LMB) && !OverRadar)
|
|
|
|
{
|
|
|
|
if (buildState == BUILD3D_VALID)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-30 11:03:26 -07:00
|
|
|
if ((((STRUCTURE_STATS *)sBuildDetails.psStats)->type == REF_WALL
|
|
|
|
|| ((STRUCTURE_STATS *)sBuildDetails.psStats)->type == REF_DEFENSE)
|
|
|
|
&& !isLasSat((STRUCTURE_STATS *)sBuildDetails.psStats))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
int dx, dy;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
wallDrag.x2 = mouseTileX;
|
|
|
|
wallDrag.y2 = mouseTileY;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
dx = abs(mouseTileX - wallDrag.x1);
|
|
|
|
dy = abs(mouseTileY - wallDrag.y1);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
if(dx >= dy) {
|
|
|
|
wallDrag.y2 = wallDrag.y1;
|
|
|
|
} else if(dx < dy) {
|
|
|
|
wallDrag.x2 = wallDrag.x1;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
|
|
|
|
wallDrag.status = DRAG_RELEASED;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
debug( LOG_NEVER, "BUILD3D_FINISHED\n" );
|
|
|
|
buildState = BUILD3D_FINISHED;
|
|
|
|
return TRUE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-14 06:15:40 -07:00
|
|
|
static void HandleDrag(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
UDWORD dragX, dragY;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
if(driveModeActive()) {
|
|
|
|
if(mouseDown(MOUSE_LMB)) {
|
|
|
|
if(buildState == BUILD3D_VALID)
|
|
|
|
{
|
2007-05-30 11:03:26 -07:00
|
|
|
if ((((STRUCTURE_STATS *)sBuildDetails.psStats)->type == REF_WALL
|
|
|
|
|| ((STRUCTURE_STATS *)sBuildDetails.psStats)->type == REF_DEFENSE)
|
|
|
|
&& !isLasSat((STRUCTURE_STATS *)sBuildDetails.psStats))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
int dx,dy;
|
|
|
|
|
|
|
|
wallDrag.x2 = mouseTileX;
|
|
|
|
wallDrag.y2 = mouseTileY;
|
|
|
|
|
|
|
|
dx = abs(mouseTileX - wallDrag.x1);
|
|
|
|
dy = abs(mouseTileY - wallDrag.y1);
|
|
|
|
|
|
|
|
if(dx >= dy) {
|
|
|
|
wallDrag.y2 = wallDrag.y1;
|
|
|
|
} else if(dx < dy) {
|
|
|
|
wallDrag.x2 = wallDrag.x1;
|
|
|
|
}
|
|
|
|
|
|
|
|
wallDrag.status = DRAG_DRAGGING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
if(mouseDrag(MOUSE_LMB, &dragX, &dragY) && !mouseOverRadar && !mouseDown(MOUSE_RMB))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
dragBox3D.x1 = dragX;
|
2007-05-29 19:06:46 -07:00
|
|
|
dragBox3D.x2 = mouseXPos;
|
2007-06-28 10:47:08 -07:00
|
|
|
dragBox3D.y1 = dragY;
|
2007-05-29 19:06:46 -07:00
|
|
|
dragBox3D.y2 = mouseYPos;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
if(buildState == BUILD3D_VALID)
|
|
|
|
{
|
2007-05-30 11:03:26 -07:00
|
|
|
if ((((STRUCTURE_STATS *)sBuildDetails.psStats)->type == REF_WALL
|
|
|
|
|| ((STRUCTURE_STATS *)sBuildDetails.psStats)->type == REF_DEFENSE)
|
|
|
|
&& !isLasSat((STRUCTURE_STATS *)sBuildDetails.psStats))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
int dx, dy;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
wallDrag.x2 = mouseTileX;
|
|
|
|
wallDrag.y2 = mouseTileY;
|
|
|
|
|
|
|
|
dx = abs(mouseTileX - wallDrag.x1);
|
|
|
|
dy = abs(mouseTileY - wallDrag.y1);
|
|
|
|
|
|
|
|
if(dx >= dy) {
|
|
|
|
wallDrag.y2 = wallDrag.y1;
|
|
|
|
} else if(dx < dy) {
|
|
|
|
wallDrag.x2 = wallDrag.x1;
|
|
|
|
}
|
|
|
|
|
|
|
|
wallDrag.status = DRAG_DRAGGING;
|
|
|
|
}
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
dragBox3D.status = DRAG_DRAGGING;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static UDWORD CurrentItemUnderMouse;
|
|
|
|
|
|
|
|
UDWORD getTargetType(void)
|
|
|
|
{
|
|
|
|
return CurrentItemUnderMouse;
|
|
|
|
}
|
|
|
|
|
|
|
|
//don't want to do any of these whilst in the Intelligence Screen
|
|
|
|
void processMouseClickInput(void)
|
|
|
|
{
|
|
|
|
UDWORD i;
|
|
|
|
SELECTION_TYPE selection;
|
|
|
|
MOUSE_TARGET item=MT_NOTARGET;
|
|
|
|
BOOL OverRadar = OverRadarAndNotDragging();
|
|
|
|
|
|
|
|
// These four functions were embedded in this function but I moved them out for readability. In the
|
|
|
|
// absense of any comments I had a guess as to there use and named them accordingly PD 28/05/98.
|
|
|
|
//ignoreOrder = CheckFinishedWallDrag(); - this name is misleading since called for all Structures AB
|
2007-05-29 19:06:46 -07:00
|
|
|
ignoreOrder = CheckFinishedFindPosition();
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
CheckStartWallDrag();
|
|
|
|
|
|
|
|
HandleDrag();
|
|
|
|
|
|
|
|
CheckFinishedDrag();
|
|
|
|
//
|
2007-02-10 08:39:39 -08:00
|
|
|
if ((mouseReleased(MOUSE_LMB) /*|| keyPressed(KEY_RCTRL)*/) && !OverRadar &&
|
|
|
|
dragBox3D.status!=DRAG_RELEASED && !ignoreOrder && !mouseOverConsole && !bDisplayMultiJoiningStatus)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
dealWithLMB();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mouseDClicked(MOUSE_LMB))
|
|
|
|
{
|
|
|
|
dealWithLMBDClick();
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
if(driveModeActive() && !driveTacticalActive()) {
|
|
|
|
driveProcessAquireButton();
|
|
|
|
} else {
|
|
|
|
if(!driveModeActive()) {
|
2007-02-10 08:39:39 -08:00
|
|
|
if(mouseReleased(MOUSE_RMB) && !rotActive && !ignoreRMBC)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
// clearSelection();
|
|
|
|
// psSelected3D = NULL;
|
|
|
|
dragBox3D.status = DRAG_INACTIVE;
|
|
|
|
// Pretty sure we wan't set walldrag status here aswell.
|
2006-05-27 09:37:17 -07:00
|
|
|
wallDrag.status = DRAG_INACTIVE;
|
2007-06-28 10:47:08 -07:00
|
|
|
// printf("Cancel Wall Drag\n");
|
|
|
|
bRadarDragging = FALSE;
|
|
|
|
dealWithRMB();
|
|
|
|
// Why?
|
|
|
|
if(getWarCamStatus())
|
|
|
|
{
|
|
|
|
camToggleStatus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-10 08:39:39 -08:00
|
|
|
if(!mouseDrag(MOUSE_RMB,(UDWORD*)&rotX,(UDWORD*)&rotY) && bRadarDragging)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
bRadarDragging = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Right mouse click kills a building placement */
|
2007-02-10 08:39:39 -08:00
|
|
|
if( mouseReleased(MOUSE_RMB) &&
|
|
|
|
(buildState == BUILD3D_POS || buildState == BUILD3D_VALID))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
/* Stop the placement */
|
|
|
|
kill3DBuilding();
|
|
|
|
bRadarDragging = FALSE;
|
|
|
|
}
|
2007-02-10 08:39:39 -08:00
|
|
|
if(mouseDrag(MOUSE_RMB,(UDWORD *)&rotX,(UDWORD *)&rotY) && !rotActive && !bRadarDragging)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
rotInitial = player.r.y;
|
|
|
|
rotInitialUp = player.r.x;
|
|
|
|
xMoved = 0;
|
|
|
|
yMoved = 0;
|
|
|
|
rotActive = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
selection = establishSelection(selectedPlayer);
|
2006-08-23 05:58:48 -07:00
|
|
|
ASSERT( selection<=POSSIBLE_SELECTIONS,"Weirdy selection!" );
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
if((selection != SC_INVALID) && !gamePaused())
|
|
|
|
{
|
|
|
|
BASE_OBJECT *ObjUnderMouse;
|
|
|
|
|
|
|
|
item = itemUnderMouse(&ObjUnderMouse);
|
2006-08-23 05:58:48 -07:00
|
|
|
ASSERT( item<POSSIBLE_TARGETS,"Weirdy target!" );
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
// alliance override. If in alli then just use the move icon. - but not if its the same player
|
2007-05-29 19:06:46 -07:00
|
|
|
//in single player, the genexp script defaults to setting an alliance between player 0 and selectedPlayer
|
2006-05-27 09:37:17 -07:00
|
|
|
if(ObjUnderMouse && (selectedPlayer != ObjUnderMouse->player) &&
|
2007-05-29 19:06:46 -07:00
|
|
|
aiCheckAlliances(selectedPlayer,ObjUnderMouse->player))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
item = MT_NOTARGET;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
if(item != MT_NOTARGET)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2006-05-27 09:37:17 -07:00
|
|
|
// exceptions to the lookup table.
|
2007-06-28 10:47:08 -07:00
|
|
|
if (ctrlShiftDown() &&
|
|
|
|
(ObjUnderMouse != NULL) &&
|
|
|
|
(ObjUnderMouse->player == selectedPlayer) &&
|
|
|
|
(ObjUnderMouse->type == OBJ_DROID))
|
|
|
|
{
|
|
|
|
item = MT_OWNDROID;
|
|
|
|
}
|
|
|
|
else if ((keyDown(KEY_LALT) || keyDown(KEY_RALT)) &&
|
|
|
|
(ObjUnderMouse != NULL) &&
|
|
|
|
(ObjUnderMouse->player == selectedPlayer))
|
|
|
|
{
|
|
|
|
if (selection == SC_DROID_REPAIR)
|
|
|
|
{
|
|
|
|
item = MT_OWNDROIDDAM;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// attacking own unit
|
|
|
|
item = MT_ENEMYDROID;
|
|
|
|
}
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
//in multiPlayer can only put cyborgs onto a Transporter
|
|
|
|
else if (bMultiPlayer && item == MT_TRANDROID)
|
|
|
|
{
|
|
|
|
if (!cyborgDroidSelected(selectedPlayer))
|
|
|
|
{
|
|
|
|
item = MT_BLOCKING;
|
|
|
|
}
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
else if (selection==SC_DROID_CONSTRUCT)
|
|
|
|
{
|
|
|
|
// We don't allow the build cursor under certain circumstances ....
|
|
|
|
// can't build if res extractors arent available.
|
|
|
|
if (item == MT_RESOURCE)
|
|
|
|
{
|
|
|
|
for(i=0;(i<numStructureStats)&&(asStructureStats[i].type != REF_RESOURCE_EXTRACTOR);i++); // find resource stat
|
|
|
|
if( (i < numStructureStats) && (apStructTypeLists[selectedPlayer][i] == UNAVAILABLE)) // check if you can build it!
|
|
|
|
{
|
|
|
|
item = MT_BLOCKING; // don't allow build pointer.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// repair instead of sensor/guard with cons. droids.
|
|
|
|
else if (item == MT_SENSOR)
|
|
|
|
{
|
|
|
|
if(ObjUnderMouse // something valid
|
|
|
|
&& (ObjUnderMouse->type == OBJ_STRUCTURE))// check if struct
|
|
|
|
{
|
|
|
|
if(buildingDamaged((STRUCTURE *)ObjUnderMouse))
|
|
|
|
{
|
|
|
|
item = MT_OWNSTRDAM; // replace guard/sense with usual icons.
|
|
|
|
}else{
|
|
|
|
item = MT_OWNSTROK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
else if (item == MT_SENSOR
|
2007-02-10 08:39:39 -08:00
|
|
|
&& selection == SC_DROID_INDIRECT
|
|
|
|
&& (keyDown(KEY_LSHIFT) || keyDown(KEY_RSHIFT)))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
selection = SC_DROID_SENSOR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check the type of sensor for indirect weapons
|
2007-02-10 08:39:39 -08:00
|
|
|
else if ((item == MT_SENSOR || item == MT_SENSORSTRUCT || item == MT_SENSORSTRUCTDAM)
|
|
|
|
&& selection == SC_DROID_INDIRECT )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
if (!droidSensorDroidWeapon(ObjUnderMouse, psDominantSelected))
|
|
|
|
{
|
|
|
|
item = MT_BLOCKING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//check for VTOL droids being assigned to a sensor droid/structure
|
2007-02-10 08:39:39 -08:00
|
|
|
else if ( (item == MT_SENSOR || item == MT_SENSORSTRUCT || item == MT_SENSORSTRUCTDAM)
|
|
|
|
&& selection == SC_DROID_DIRECT
|
|
|
|
&& vtolDroidSelected((UBYTE)selectedPlayer))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
// NB. psSelectedVtol was set by vtolDroidSelected - yes I know its horrible, but it
|
|
|
|
// only smells as much as the rest of display.c so I don't feel so bad
|
|
|
|
if (droidSensorDroidWeapon(ObjUnderMouse, psSelectedVtol))
|
|
|
|
{
|
|
|
|
selection = SC_DROID_INDIRECT;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item = MT_BLOCKING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
//vtols cannot pick up artifacts
|
|
|
|
else if (item == MT_ARTIFACT
|
2007-02-10 08:39:39 -08:00
|
|
|
&& selection == SC_DROID_DIRECT
|
|
|
|
&& vtolDroidSelected((UBYTE)selectedPlayer))
|
2007-05-29 19:06:46 -07:00
|
|
|
{
|
|
|
|
item = MT_BLOCKING;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
//VTOL's can't be moved to empty terrain
|
2006-05-27 09:37:17 -07:00
|
|
|
/* else if (vtolDroidSelected((UBYTE)selectedPlayer)
|
2007-02-10 08:39:39 -08:00
|
|
|
&& item == MT_TERRAIN
|
|
|
|
&& selection == SC_DROID_DIRECT)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
item = MT_BLOCKING;
|
|
|
|
}*/
|
2007-05-29 19:06:46 -07:00
|
|
|
//in multiPlayer Transporters can be moved around the terrain - and repaired
|
|
|
|
if (bMultiPlayer && selection == SC_DROID_TRANSPORTER && (
|
|
|
|
item == MT_TERRAIN || item == MT_REPAIR))
|
|
|
|
{
|
|
|
|
//change to standard droid selection
|
|
|
|
selection = SC_DROID_INDIRECT;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
else if (item == MT_TERRAIN
|
2007-02-10 08:39:39 -08:00
|
|
|
&& TERRAIN_TYPE(mapTile(mouseTileX,mouseTileY)) == TER_CLIFFFACE)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
item = MT_BLOCKING;
|
|
|
|
}
|
|
|
|
|
2006-11-03 17:11:26 -08:00
|
|
|
frameSetCursorFromRes((SWORD)arnMPointers[item][selection]);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
else
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
//exceptions, exceptions...AB 10/06/99
|
|
|
|
if (bMultiPlayer && bLasSatStruct)
|
|
|
|
{
|
|
|
|
BASE_OBJECT *ObjUnderMouse;
|
|
|
|
|
|
|
|
item = itemUnderMouse(&ObjUnderMouse);
|
|
|
|
ASSERT( item<POSSIBLE_TARGETS,"Weirdy target!" );
|
|
|
|
if (item == MT_ENEMYDROID || item == MT_ENEMYSTR || item == MT_DAMFEATURE)
|
|
|
|
{
|
|
|
|
//display attack cursor
|
|
|
|
frameSetCursorFromRes(IDC_ATTACK);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//display block cursor
|
|
|
|
frameSetCursorFromRes(IDC_NOTPOSSIBLE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
frameSetCursorFromRes(IDC_DEFAULT);
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
CurrentItemUnderMouse= item;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void scroll(void)
|
|
|
|
{
|
|
|
|
float radians;
|
|
|
|
float cosine, sine;
|
|
|
|
SDWORD xDif,yDif;
|
|
|
|
#ifdef VISIBLE_SCROLL
|
|
|
|
SDWORD newx,newy;
|
|
|
|
#endif
|
|
|
|
UDWORD timeDiff;
|
|
|
|
BOOL bRetardScroll = FALSE;
|
2006-11-26 03:48:30 -08:00
|
|
|
BOOL mouseAtLeft = FALSE, mouseAtRight = FALSE,
|
2007-05-29 19:06:46 -07:00
|
|
|
mouseAtTop = FALSE, mouseAtBottom = FALSE;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
if(InGameOpUp || bDisplayMultiJoiningStatus ) // cant scroll when menu up. or when over radar
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-02-10 08:39:39 -08:00
|
|
|
if(!keyDown(KEY_LCTRL) && !keyDown(KEY_RCTRL))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
/* Scroll left */
|
2007-05-29 19:06:46 -07:00
|
|
|
if (keyDown(KEY_LEFTARROW) || mouseXPos < BOUNDARY_X)
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
mouseAtLeft = TRUE;
|
2007-05-29 19:06:46 -07:00
|
|
|
if(!keyDown(KEY_LEFTARROW) && mouseXPos > BOUNDARY_X/2)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
bRetardScroll = TRUE;
|
|
|
|
}
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
/* Scroll right */
|
2007-05-29 19:06:46 -07:00
|
|
|
if ( keyDown(KEY_RIGHTARROW) || mouseXPos > (pie_GetVideoBufferWidth() - BOUNDARY_X) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
mouseAtRight = TRUE;
|
2007-05-29 19:06:46 -07:00
|
|
|
if( !keyDown(KEY_RIGHTARROW) && mouseXPos < (pie_GetVideoBufferWidth() - BOUNDARY_X/2) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
bRetardScroll = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Scroll up */
|
2007-05-29 19:06:46 -07:00
|
|
|
if (keyDown(KEY_UPARROW) || (mouseYPos < BOUNDARY_Y))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
mouseAtBottom = TRUE;
|
2007-05-29 19:06:46 -07:00
|
|
|
if(!keyDown(KEY_UPARROW) && mouseYPos > BOUNDARY_Y/2)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
bRetardScroll = TRUE;
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
/* Scroll down */
|
2007-05-29 19:06:46 -07:00
|
|
|
if ( keyDown(KEY_DOWNARROW) || mouseYPos > (pie_GetVideoBufferHeight() - BOUNDARY_Y) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
mouseAtTop = TRUE;
|
2007-05-29 19:06:46 -07:00
|
|
|
if( !keyDown(KEY_DOWNARROW) && mouseYPos < (pie_GetVideoBufferHeight() - BOUNDARY_Y/2) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
bRetardScroll = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Scroll left */
|
2007-05-29 19:06:46 -07:00
|
|
|
if (mouseXPos < BOUNDARY_X)
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
mouseAtLeft = TRUE;
|
2007-05-29 19:06:46 -07:00
|
|
|
if(!keyDown(KEY_LEFTARROW) && mouseXPos > BOUNDARY_X/2)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
bRetardScroll = TRUE;
|
|
|
|
}
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
/* Scroll right */
|
2007-05-29 19:06:46 -07:00
|
|
|
if (mouseXPos > (pie_GetVideoBufferWidth() - BOUNDARY_X))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
mouseAtRight = TRUE;
|
2007-05-29 19:06:46 -07:00
|
|
|
if( !keyDown(KEY_RIGHTARROW) && mouseXPos < (pie_GetVideoBufferWidth() - BOUNDARY_X/2) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
bRetardScroll = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Scroll up */
|
2007-05-29 19:06:46 -07:00
|
|
|
if (mouseYPos < BOUNDARY_Y)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
mouseAtBottom = TRUE;
|
2007-05-29 19:06:46 -07:00
|
|
|
if(!keyDown(KEY_UPARROW) && mouseYPos > BOUNDARY_Y/2)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
bRetardScroll = TRUE;
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
/* Scroll down */
|
2007-05-29 19:06:46 -07:00
|
|
|
if (mouseYPos > (pie_GetVideoBufferHeight() - BOUNDARY_Y))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
mouseAtTop = TRUE;
|
2007-05-29 19:06:46 -07:00
|
|
|
if(!keyDown(KEY_DOWNARROW) && mouseYPos < (pie_GetVideoBufferHeight() - BOUNDARY_Y/2) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
bRetardScroll = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Time to update scroll - change to should be time */
|
2006-08-27 12:09:35 -07:00
|
|
|
timeDiff = SDL_GetTicks() - scrollRefTime;
|
2007-05-29 19:06:46 -07:00
|
|
|
|
|
|
|
// WHEN its fixed - you can uncomment it!
|
|
|
|
/*
|
|
|
|
if(bRetardScroll && FALSE) //temp until fixed
|
|
|
|
{
|
|
|
|
timeDiff/=2;
|
|
|
|
}
|
|
|
|
*/
|
2007-06-28 10:47:08 -07:00
|
|
|
/* Store reference time */
|
2006-08-27 12:09:35 -07:00
|
|
|
scrollRefTime = SDL_GetTicks();
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
if (timeDiff > GTIME_MAXFRAME)
|
|
|
|
{
|
|
|
|
timeDiff = GTIME_MAXFRAME;
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
scrollAccel = (float)scroll_speed_accel * (float)(timeDiff) / (float)GAME_TICKS_PER_SEC;
|
2007-06-28 10:47:08 -07:00
|
|
|
if(mouseAtLeft)
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
if(scrollSpeedLeftRight > 0)
|
|
|
|
scrollSpeedLeftRight = 0.0f;
|
2007-06-28 10:47:08 -07:00
|
|
|
scrollSpeedLeftRight -= scrollAccel;
|
|
|
|
if(scrollSpeedLeftRight < -(float)MAX_SCROLL_SPEED)
|
|
|
|
{
|
|
|
|
scrollSpeedLeftRight = -(float)MAX_SCROLL_SPEED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(mouseAtRight)
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
if(scrollSpeedLeftRight < 0)
|
|
|
|
scrollSpeedLeftRight = 0.0f;
|
2007-06-28 10:47:08 -07:00
|
|
|
scrollSpeedLeftRight += scrollAccel;
|
|
|
|
if(scrollSpeedLeftRight > (float)MAX_SCROLL_SPEED)
|
|
|
|
{
|
|
|
|
scrollSpeedLeftRight = (float)MAX_SCROLL_SPEED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // not at left or right so retard the scroll
|
|
|
|
{
|
|
|
|
if(scrollSpeedLeftRight > 2*scrollAccel)
|
|
|
|
{
|
|
|
|
scrollSpeedLeftRight -= 2*scrollAccel;
|
|
|
|
}
|
|
|
|
else if(scrollSpeedLeftRight < -2*scrollAccel)
|
|
|
|
{
|
|
|
|
scrollSpeedLeftRight += 2*scrollAccel;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
scrollSpeedLeftRight = 0.0f;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if(mouseAtBottom)//its at the top??
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
if(scrollSpeedUpDown < 0)
|
|
|
|
scrollSpeedUpDown = 0.0f;
|
2007-06-28 10:47:08 -07:00
|
|
|
scrollSpeedUpDown += scrollAccel;
|
|
|
|
if(scrollSpeedUpDown > (float)MAX_SCROLL_SPEED)
|
|
|
|
{
|
|
|
|
scrollSpeedUpDown = (float)MAX_SCROLL_SPEED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(mouseAtTop)//its at the bottom??
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
if(scrollSpeedUpDown > 0)
|
|
|
|
scrollSpeedUpDown = 0.0f;
|
2007-06-28 10:47:08 -07:00
|
|
|
scrollSpeedUpDown -= scrollAccel;
|
|
|
|
if(scrollSpeedUpDown < -(float)MAX_SCROLL_SPEED)
|
|
|
|
{
|
|
|
|
scrollSpeedUpDown = -(float)MAX_SCROLL_SPEED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // not at top or bottom so retard the scroll
|
|
|
|
{
|
|
|
|
if(scrollSpeedUpDown > scrollAccel)
|
|
|
|
{
|
|
|
|
scrollSpeedUpDown -= 2*scrollAccel;
|
|
|
|
}
|
|
|
|
else if(scrollSpeedUpDown < -scrollAccel)
|
|
|
|
{
|
|
|
|
scrollSpeedUpDown += 2*scrollAccel;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
scrollSpeedUpDown = 0.0f;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
// scrool speeds updated in proportion to frame time calculate how far to step in each direction
|
2007-06-28 10:47:08 -07:00
|
|
|
scrollStepLeftRight = scrollSpeedLeftRight * (float)(timeDiff) /
|
|
|
|
(float)GAME_TICKS_PER_SEC;
|
|
|
|
scrollStepUpDown = scrollSpeedUpDown * (float)(timeDiff) /
|
|
|
|
(float)GAME_TICKS_PER_SEC;
|
|
|
|
|
|
|
|
/* Get angle vector to scroll along */
|
|
|
|
worldAngle = (UDWORD) ((UDWORD)player.r.y/DEG_1)%360;
|
|
|
|
direction = (360) - worldAngle;
|
|
|
|
|
|
|
|
/* Convert to radians */
|
2007-05-29 19:06:46 -07:00
|
|
|
radians = ((M_PI / 180) * (direction));
|
|
|
|
cosine = cosf(radians);
|
|
|
|
sine = sinf(radians);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
/* Get x component of movement */
|
2007-06-28 10:47:08 -07:00
|
|
|
xDif = ROUND(cosine * scrollStepLeftRight + sine * scrollStepUpDown);
|
|
|
|
/* Get y component of movement */
|
|
|
|
yDif = ROUND(sine * scrollStepLeftRight - cosine * scrollStepUpDown);
|
|
|
|
|
|
|
|
/* Adjust player's position by these components */
|
|
|
|
#ifdef VISIBLE_SCROLL
|
|
|
|
newx = player.p.x + xDif;
|
|
|
|
newy = player.p.z + yDif;
|
|
|
|
if (mapTile((((VISIBLE_XTILES/2)<<TILE_SHIFT) + newx) >> TILE_SHIFT,
|
|
|
|
(((VISIBLE_YTILES/2)<<TILE_SHIFT) + newy) >> TILE_SHIFT)->tileVisBits & (1 << selectedPlayer))
|
|
|
|
{
|
|
|
|
player.p.x = newx;
|
|
|
|
player.p.z = newy;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (player.p.x >> TILE_SHIFT != newx >> TILE_SHIFT)
|
|
|
|
{
|
|
|
|
scrollSpeedLeftRight = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
player.p.x = newx;
|
|
|
|
}
|
|
|
|
if (player.p.z >> TILE_SHIFT != newy >> TILE_SHIFT)
|
|
|
|
{
|
|
|
|
scrollSpeedUpDown = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
player.p.z = newy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
player.p.x += xDif;
|
|
|
|
player.p.z += yDif;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
edgeOfMap = CheckScrollLimits();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check a coordinate is within the scroll limits, uses object type coords ie UWORDs.
|
|
|
|
// Returns TRUE if edge hit.
|
|
|
|
//
|
|
|
|
BOOL CheckObjInScrollLimits(UWORD *xPos,UWORD *zPos)
|
|
|
|
{
|
|
|
|
SDWORD xp = ((SWORD)(*xPos)) - VISIBLE_XTILES*TILE_UNITS/2;
|
|
|
|
SDWORD zp = ((SWORD)(*zPos)) - VISIBLE_YTILES*TILE_UNITS/2;
|
|
|
|
BOOL ret = CheckInScrollLimits(&xp,&zp);
|
|
|
|
|
|
|
|
*xPos = (UWORD)(xp + VISIBLE_XTILES*TILE_UNITS/2);
|
|
|
|
*zPos = (UWORD)(zp + VISIBLE_YTILES*TILE_UNITS/2);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check a coordinate is within the scroll limits, SDWORD version.
|
|
|
|
// Returns TRUE if edge hit.
|
|
|
|
//
|
|
|
|
BOOL CheckInScrollLimits(SDWORD *xPos,SDWORD *zPos)
|
|
|
|
{
|
|
|
|
BOOL EdgeHit = FALSE;
|
|
|
|
SDWORD minX,minY,maxX,maxY;
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
//always view that little bit more than the scroll limits...
|
2007-06-28 10:47:08 -07:00
|
|
|
/*minX = scrollMinX * TILE_UNITS;
|
|
|
|
minY = scrollMinY * TILE_UNITS;
|
|
|
|
maxX = (((scrollMaxX-1) - visibleXTiles) * TILE_UNITS);
|
|
|
|
maxY = (((scrollMaxY-1) - visibleYTiles) * TILE_UNITS);
|
|
|
|
|
|
|
|
if(scrollMinX==0)
|
|
|
|
{
|
|
|
|
minX = ((0 - visibleXTiles/2) * TILE_UNITS);
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
if((UDWORD)scrollMaxX == mapWidth)
|
|
|
|
{
|
2006-05-27 09:37:17 -07:00
|
|
|
maxX = ((mapWidth-1-(visibleXTiles/2)) * TILE_UNITS);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
if(scrollMinY==0)
|
|
|
|
{
|
|
|
|
minY = ((0 - visibleYTiles/2) * TILE_UNITS);
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
if((UDWORD)scrollMaxY == mapHeight)
|
|
|
|
{
|
2006-05-27 09:37:17 -07:00
|
|
|
maxY = ((mapHeight-1-(visibleYTiles/2)) * TILE_UNITS);
|
2007-06-28 10:47:08 -07:00
|
|
|
}*/
|
2007-05-29 19:06:46 -07:00
|
|
|
minX = (scrollMinX - (visibleXTiles/2)) * TILE_UNITS;
|
|
|
|
maxX = ((scrollMaxX - 1) - (visibleXTiles/2)) * TILE_UNITS;
|
|
|
|
minY = (scrollMinY - (visibleYTiles/2)) * TILE_UNITS;
|
|
|
|
maxY = ((scrollMaxY - 1) - (visibleYTiles/2)) * TILE_UNITS;
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
//scroll is limited to what can be seen for current campaign
|
|
|
|
if (*xPos < minX)
|
|
|
|
{
|
|
|
|
*xPos = minX;
|
|
|
|
EdgeHit = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (*xPos >= maxX)
|
|
|
|
{
|
|
|
|
*xPos = maxX;
|
|
|
|
EdgeHit = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*zPos < minY)
|
|
|
|
{
|
|
|
|
*zPos = minY;
|
|
|
|
EdgeHit = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (*zPos >= maxY)
|
|
|
|
{
|
|
|
|
*zPos = maxY;
|
|
|
|
EdgeHit = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return EdgeHit;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check the view is within the scroll limits,
|
|
|
|
// Returns TRUE if edge hit.
|
|
|
|
//
|
|
|
|
BOOL CheckScrollLimits(void)
|
|
|
|
{
|
|
|
|
SDWORD xp = player.p.x;
|
|
|
|
SDWORD zp = player.p.z;
|
|
|
|
BOOL ret = CheckInScrollLimits(&xp,&zp);
|
|
|
|
|
|
|
|
player.p.x = xp;
|
|
|
|
player.p.z = zp;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Do the 3D display */
|
|
|
|
void displayWorld(void)
|
|
|
|
{
|
2007-03-16 09:20:16 -07:00
|
|
|
Vector3i pos;
|
2007-06-28 10:47:08 -07:00
|
|
|
shakeUpdate();
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
if (mouseDown(MOUSE_RMB) && rotActive)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
if (abs(mouseXPos - rotX) > 8 || xMoved > 8)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
xMoved += abs(mouseXPos - rotX);
|
|
|
|
if (mouseXPos < rotX)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
player.r.y = rotInitial + (rotX - mouseXPos)/2 * DEG(1);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
player.r.y = rotInitial - (mouseXPos - rotX)/2 * DEG(1);
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
if (abs(mouseYPos - rotY) > 8 || yMoved > 8)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
yMoved += abs(mouseYPos - rotY);
|
|
|
|
if (bInvertMouse)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
if (mouseYPos < rotY)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
player.r.x = rotInitialUp + (rotY - mouseYPos)/3 * DEG(1);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
player.r.x = rotInitialUp - (mouseYPos - rotY)/3 * DEG(1);
|
2006-05-27 09:37:17 -07:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
if(mouseYPos < rotY)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
player.r.x = rotInitialUp - (rotY - mouseYPos)/3 * DEG(1);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
player.r.x = rotInitialUp + (mouseYPos - rotY)/3 * DEG(1);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
if(player.r.x > DEG(360 + MAX_PLAYER_X_ANGLE))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
player.r.x = DEG(360 + MAX_PLAYER_X_ANGLE);
|
|
|
|
}
|
|
|
|
if(player.r.x < DEG(360 + MIN_PLAYER_X_ANGLE))
|
|
|
|
{
|
|
|
|
player.r.x = DEG(360 + MIN_PLAYER_X_ANGLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
setDesiredPitch(player.r.x/DEG_1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-10 08:39:39 -08:00
|
|
|
if(mouseReleased(MOUSE_RMB) && rotActive)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
rotActive = FALSE;
|
|
|
|
xMoved = yMoved = 0;
|
|
|
|
ignoreRMBC = TRUE;
|
|
|
|
pos.x = player.r.x;
|
|
|
|
pos.y = player.r.y;
|
|
|
|
pos.z = player.r.z;
|
|
|
|
camInformOfRotation(&pos);
|
|
|
|
bRadarDragging = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
draw3DScene();
|
|
|
|
}
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
BOOL mouseInBox(SDWORD x0, SDWORD y0, SDWORD x1, SDWORD y1)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
if(mouseXPos > x0 && mouseXPos < x1 && mouseYPos > y0 && mouseYPos < y1)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
return TRUE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL DrawnInLastFrame(SDWORD Frame)
|
|
|
|
{
|
|
|
|
if (Frame>=(SDWORD)StartOfLastFrame)
|
|
|
|
{
|
|
|
|
return TRUE;
|
2006-05-27 09:37:17 -07:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
/*
|
2007-06-28 10:47:08 -07:00
|
|
|
Returns what the mouse was clicked on. Only called if there was a mouse pressed message
|
2006-05-27 09:37:17 -07:00
|
|
|
on MOUSE_LMB. We aren't concerned here with setting selection flags - just what it
|
|
|
|
actually was
|
2007-06-28 10:47:08 -07:00
|
|
|
*/
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
BASE_OBJECT *mouseTarget( void )
|
|
|
|
{
|
|
|
|
UDWORD i;
|
|
|
|
BASE_OBJECT *psReturn;
|
|
|
|
DROID *psDroid;
|
|
|
|
UDWORD dispX,dispY,dispR;
|
|
|
|
|
2007-02-10 08:39:39 -08:00
|
|
|
if( (mouseTileX < 0) ||
|
|
|
|
(mouseTileY < 0) ||
|
|
|
|
(mouseTileX > (SDWORD)(mapWidth-1)) ||
|
2007-06-28 10:47:08 -07:00
|
|
|
(mouseTileY > (SDWORD)(mapHeight-1)) )
|
|
|
|
{
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* We haven't found anything yet */
|
|
|
|
psReturn = NULL;
|
|
|
|
|
|
|
|
/* First have a look through the droid lists */
|
|
|
|
for (i=0; i<MAX_PLAYERS; i++)
|
|
|
|
{
|
|
|
|
/* Note the !psObject check isn't really necessary as the goto will jump out */
|
2006-05-27 09:37:17 -07:00
|
|
|
for (psDroid = apsDroidLists[i]; psDroid && !psReturn;
|
2007-05-29 19:06:46 -07:00
|
|
|
psDroid = psDroid->psNext)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
|
|
|
|
dispX = psDroid->sDisplay.screenX;
|
|
|
|
dispY = psDroid->sDisplay.screenY;
|
|
|
|
dispR = psDroid->sDisplay.screenR;
|
|
|
|
/* Only check droids that're on screen */
|
|
|
|
|
|
|
|
|
|
|
|
// Has the droid been drawn since the start of the last frame
|
2007-02-10 08:39:39 -08:00
|
|
|
if (psDroid->visible[selectedPlayer] && DrawnInLastFrame(psDroid->sDisplay.frameNumber)==TRUE)
|
2007-06-28 10:47:08 -07:00
|
|
|
// if(psDroid->sDisplay.frameNumber+1 == currentFrame)
|
|
|
|
{
|
|
|
|
if (mouseInBox(dispX-dispR, dispY-dispR, dispX+dispR, dispY+dispR))
|
|
|
|
{
|
|
|
|
/* We HAVE clicked on droid! */
|
|
|
|
psReturn = (BASE_OBJECT *) psDroid;
|
|
|
|
/* There's no point in checking other object types */
|
|
|
|
return(psReturn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // end of checking for droids
|
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
/* Not a droid, so maybe a structure or feature?
|
2007-06-28 10:47:08 -07:00
|
|
|
If still NULL after this then nothing */
|
|
|
|
psReturn = getTileOccupier(mouseTileX, mouseTileY);
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
/* Send the result back - if it's null then we clicked on an area of terrain */
|
2007-06-28 10:47:08 -07:00
|
|
|
return(psReturn);
|
|
|
|
}
|
|
|
|
|
|
|
|
UWORD lastangle; // debugging only
|
|
|
|
|
|
|
|
// Dummy structure stats used for positioning delivery points.
|
|
|
|
static STRUCTURE_STATS ReposStats;
|
|
|
|
static BOOL ReposValid = FALSE;
|
|
|
|
static BOOL BVReposValid = FALSE;
|
|
|
|
static FLAG_POSITION *ReposFlag;
|
|
|
|
|
|
|
|
void StartTacticalScroll(BOOL driveActive)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void StartTacticalScrollObj(BOOL driveActive,BASE_OBJECT *psObj)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void CancelTacticalScroll(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void displayInitVars(void)
|
|
|
|
{
|
|
|
|
ReposValid = FALSE;
|
|
|
|
BVReposValid = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Start repositioning a delivery point.
|
|
|
|
//
|
2007-02-19 08:46:48 -08:00
|
|
|
void StartDeliveryPosition( OBJECT_POSITION *psLocation )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
FLAG_POSITION *psFlagPos;
|
|
|
|
/* clear the selection */
|
|
|
|
// clearSelection();
|
|
|
|
//clear the Deliv Point if one
|
|
|
|
for (psFlagPos = apsFlagPosLists[selectedPlayer]; psFlagPos;
|
|
|
|
psFlagPos = psFlagPos->psNext)
|
|
|
|
{
|
|
|
|
psFlagPos->selected = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//set this object position to be highlighted
|
|
|
|
psLocation->selected = TRUE;
|
|
|
|
|
|
|
|
if(bInTutorial)
|
|
|
|
{
|
|
|
|
eventFireCallbackTrigger((TRIGGER_TYPE)CALL_DELIVPOINTMOVED);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup dummy structure stats for positioning a delivery point.
|
|
|
|
ReposValid = FALSE;
|
|
|
|
ReposFlag = NULL;
|
|
|
|
ReposStats.baseWidth = 1;
|
|
|
|
ReposStats.baseBreadth = 1;
|
|
|
|
ReposStats.ref = 0;//REF_STRUCTURE_START;
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
//set up the buildSite variable for drawing
|
2007-06-28 10:47:08 -07:00
|
|
|
buildSite.xTL = (UWORD)psLocation->screenX;
|
2007-05-29 19:06:46 -07:00
|
|
|
buildSite.yTL = (UWORD)psLocation->screenY;
|
2007-06-28 10:47:08 -07:00
|
|
|
buildSite.xBR = (UWORD)(buildSite.xTL-1);
|
2007-05-29 19:06:46 -07:00
|
|
|
buildSite.yBR = (UWORD)(buildSite.yTL-1);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
|
2007-03-16 12:31:15 -07:00
|
|
|
init3DBuilding((BASE_STATS *)&ReposStats, FinishDeliveryPosition, psLocation);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Finished repositioning a delivery point.
|
|
|
|
//
|
|
|
|
void FinishDeliveryPosition(UDWORD xPos,UDWORD yPos,void *UserData)
|
|
|
|
{
|
|
|
|
//This deals with adding waypoints and moving the primary
|
|
|
|
processDeliveryPoint(((FLAG_POSITION*)UserData)->player,
|
|
|
|
xPos<<TILE_SHIFT, yPos<<TILE_SHIFT);
|
|
|
|
|
|
|
|
//deselect it
|
|
|
|
((FLAG_POSITION*)UserData)->selected = FALSE;
|
|
|
|
|
|
|
|
CancelDeliveryRepos();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Cancel repositioning of the delivery point without moveing it.
|
|
|
|
//
|
|
|
|
/*void CancelDeliveryRepos(void)
|
|
|
|
{
|
|
|
|
if((ReposValid) && (ReposFlag!=NULL))
|
|
|
|
{
|
|
|
|
if(driveModeActive())
|
|
|
|
{
|
|
|
|
DROID *Driven = driveGetDriven();
|
|
|
|
if(Driven != NULL) {
|
|
|
|
Driven->selected = TRUE;
|
|
|
|
camAllignWithTarget(Driven);
|
|
|
|
}
|
|
|
|
driveEnableControl();
|
|
|
|
}
|
|
|
|
ReposValid = FALSE;
|
|
|
|
ReposFlag = NULL;
|
|
|
|
buildState = BUILD3D_NONE;
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
// Get the current screen position of the delivery point.
|
|
|
|
//
|
|
|
|
/*BOOL GetDeliveryRepos(UDWORD *xPos,UDWORD *yPos)
|
|
|
|
{
|
|
|
|
if((ReposValid) && (ReposFlag!=NULL))
|
|
|
|
{
|
|
|
|
*xPos = scoord_PC2PSXx(ReposFlag->screenX);
|
|
|
|
*yPos = scoord_PC2PSXy(ReposFlag->screenY);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
// Is there a valid delivery point repositioning going on.
|
|
|
|
//
|
|
|
|
BOOL DeliveryReposValid(void)
|
|
|
|
{
|
|
|
|
if(driveModeActive()) {
|
|
|
|
return ReposValid && (ReposFlag !=NULL);
|
|
|
|
} else {
|
|
|
|
return BVReposValid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Cancel repositioning of the delivery point without moving it.
|
|
|
|
//
|
|
|
|
void CancelDeliveryRepos(void)
|
|
|
|
{
|
|
|
|
if((ReposValid) && (ReposFlag!=NULL))
|
|
|
|
{
|
|
|
|
if(driveModeActive())
|
|
|
|
{
|
|
|
|
DROID *Driven = driveGetDriven();
|
|
|
|
if(Driven != NULL) {
|
|
|
|
// Driven->selected = TRUE;
|
|
|
|
SelectDroid(Driven);
|
|
|
|
camAllignWithTarget((BASE_OBJECT *)Driven);
|
|
|
|
}
|
|
|
|
driveEnableControl();
|
|
|
|
}
|
|
|
|
ReposValid = FALSE;
|
|
|
|
ReposFlag = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
BVReposValid = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// check whether a clicked on droid is in a command group or assigned to a sensor
|
2006-09-14 06:15:40 -07:00
|
|
|
static BOOL droidHasLeader(DROID *psDroid)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
BASE_OBJECT *psLeader;
|
|
|
|
|
|
|
|
if (psDroid->droidType == DROID_COMMAND ||
|
|
|
|
psDroid->droidType == DROID_SENSOR)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
psLeader = NULL;
|
|
|
|
if ((psDroid->psGroup != NULL) &&
|
|
|
|
(psDroid->psGroup->type == GT_COMMAND))
|
|
|
|
{
|
|
|
|
psLeader = (BASE_OBJECT *)psDroid->psGroup->psCommander;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
//psLeader can be either a droid or a structure
|
2007-06-28 10:47:08 -07:00
|
|
|
orderStateObj(psDroid, DORDER_FIRESUPPORT, &psLeader);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (psLeader != NULL)
|
|
|
|
{
|
|
|
|
// psLeader->selected = TRUE;
|
2007-05-29 19:06:46 -07:00
|
|
|
if (psLeader->type == OBJ_DROID)
|
|
|
|
{
|
|
|
|
SelectDroid((DROID *)psLeader);
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
assignSensorTarget(psLeader);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// deal with selecting a droid
|
|
|
|
void dealWithDroidSelect(DROID *psDroid, BOOL bDragBox)
|
|
|
|
{
|
|
|
|
DROID *psD;
|
|
|
|
BOOL bGotGroup;
|
|
|
|
SDWORD groupNumber = 0;
|
|
|
|
|
|
|
|
/* Toggle selection on and off - allows you drag around a big
|
|
|
|
area of droids and then exclude certain individuals */
|
|
|
|
if(!bDragBox &&
|
|
|
|
psDroid->selected==TRUE)
|
|
|
|
{
|
|
|
|
// psDroid->selected = FALSE;
|
|
|
|
DeSelectDroid(psDroid);
|
|
|
|
// was "=="
|
|
|
|
psDroid->group = UBYTE_MAX;
|
|
|
|
// if(OrderUp)
|
|
|
|
{
|
2006-05-27 09:37:17 -07:00
|
|
|
/* Fix this ALEX M!!! */
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (keyDown(KEY_LCTRL) || keyDown(KEY_RCTRL) || keyDown(KEY_LSHIFT) || keyDown(KEY_RSHIFT)
|
|
|
|
|| !droidHasLeader(psDroid))
|
|
|
|
{
|
|
|
|
|
|
|
|
for(psD = apsDroidLists[selectedPlayer],bGotGroup = FALSE;
|
2007-02-10 08:39:39 -08:00
|
|
|
psD && !bGotGroup; psD = psD->psNext)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-02-10 08:39:39 -08:00
|
|
|
if(psD->selected && (psD->group!=UBYTE_MAX))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
bGotGroup = TRUE;
|
|
|
|
groupNumber = psD->group;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(bGotGroup && ( keyDown(KEY_LCTRL) || keyDown(KEY_RCTRL) || keyDown(KEY_LSHIFT) || keyDown(KEY_RSHIFT)) )
|
|
|
|
{
|
|
|
|
psDroid->group = (UBYTE)groupNumber;
|
|
|
|
secondarySetAverageGroupState(selectedPlayer, (UDWORD)groupNumber);
|
|
|
|
}
|
|
|
|
// psDroid->selected = TRUE;
|
2007-02-10 08:39:39 -08:00
|
|
|
if(keyDown(KEY_LALT) || keyDown(KEY_RALT) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
/* We only want to select weapon units if ALT is down on a drag */
|
2007-05-29 19:06:46 -07:00
|
|
|
if(psDroid->asWeaps[0].nStat > 0)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
SelectDroid(psDroid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SelectDroid(psDroid);
|
|
|
|
}
|
|
|
|
/* if(psDroid->droidType == DROID_COMMAND)
|
|
|
|
{
|
|
|
|
cmdSelectSubDroids(psDroid);
|
|
|
|
}*/
|
|
|
|
// intObjectSelected((BASE_OBJECT *)psDroid);
|
|
|
|
if (bInTutorial)
|
|
|
|
{
|
|
|
|
psCBSelectedDroid = psDroid;
|
|
|
|
eventFireCallbackTrigger((TRIGGER_TYPE)CALL_DROID_SELECTED);
|
|
|
|
psCBSelectedDroid = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-14 06:15:40 -07:00
|
|
|
static void FeedbackOrderGiven(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
static UDWORD LastFrame = 0;
|
|
|
|
UDWORD ThisFrame = frameGetFrameNumber();
|
|
|
|
|
|
|
|
// Ensure only played once per game cycle.
|
|
|
|
if(ThisFrame != LastFrame) {
|
|
|
|
audio_PlayTrack(ID_SOUND_SELECT);
|
|
|
|
LastFrame = ThisFrame;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-14 06:15:40 -07:00
|
|
|
static void FeedbackClickedOn(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
FeedbackOrderGiven();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// check whether the queue order keys are pressed
|
|
|
|
BOOL ctrlShiftDown(void)
|
|
|
|
{
|
|
|
|
return keyDown(KEY_LCTRL) || keyDown(KEY_RCTRL) || keyDown(KEY_LSHIFT) || keyDown(KEY_RSHIFT);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void BeepMessage(UDWORD StringID)
|
|
|
|
{
|
|
|
|
static UDWORD LastFrame = 0;
|
|
|
|
UDWORD ThisFrame = frameGetFrameNumber();
|
|
|
|
|
|
|
|
// Ensure only done once per game cycle.
|
|
|
|
if(ThisFrame != LastFrame) {
|
|
|
|
addConsoleMessage(strresGetString(psStringRes,StringID),DEFAULT_JUSTIFY);
|
|
|
|
audio_PlayTrack( ID_SOUND_BUILD_FAIL );
|
|
|
|
LastFrame = ThisFrame;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AddDerrickBurningMessage(void)
|
|
|
|
{
|
2007-04-01 13:15:46 -07:00
|
|
|
addConsoleMessage(_("Cannot Build. Oil Resource Burning."),DEFAULT_JUSTIFY);
|
2007-06-28 10:47:08 -07:00
|
|
|
audio_PlayTrack( ID_SOUND_BUILD_FAIL );
|
|
|
|
}
|
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
static inline void dealWithLMBDroid(DROID* psDroid, SELECTION_TYPE selection)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
if(psDroid->player != selectedPlayer)
|
|
|
|
{
|
|
|
|
/* We've clicked on somebody else's droid */
|
|
|
|
// addConsoleMessage("Clicked on another player's droid",DEFAULT_JUSTIFY);
|
|
|
|
orderSelectedObjAdd(selectedPlayer, (BASE_OBJECT*)psDroid, ctrlShiftDown());
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
//lasSat structure can select a target - in multiPlayer only
|
|
|
|
if (bMultiPlayer && bLasSatStruct &&
|
|
|
|
aiCheckAlliances(selectedPlayer, psDroid->player) == FALSE)
|
|
|
|
{
|
|
|
|
orderStructureObj(selectedPlayer, (BASE_OBJECT*)psDroid);
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
FeedbackOrderGiven();
|
|
|
|
driveDisableTactical();
|
2007-06-18 08:46:12 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
return;
|
|
|
|
}
|
2007-06-18 08:46:12 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
if (ctrlShiftDown())
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
// select/deselect etc. the droid
|
|
|
|
dealWithDroidSelect(psDroid, FALSE);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-18 08:46:12 -07:00
|
|
|
else if (psDroid->droidType == DROID_TRANSPORTER)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
if (selection == SC_INVALID)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
//in multiPlayer mode we RMB to get the interface up
|
|
|
|
if (bMultiPlayer)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
psDroid->selected = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
intResetScreen(FALSE);
|
|
|
|
if(!getWidgetsStatus())
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
setWidgetsStatus(TRUE);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-17 14:02:57 -07:00
|
|
|
addTransporterInterface(psDroid, FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
orderSelectedObj(selectedPlayer, (BASE_OBJECT*)psDroid);
|
|
|
|
FeedbackOrderGiven();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (keyDown(KEY_LALT) || keyDown(KEY_RALT))
|
|
|
|
{
|
|
|
|
// try to attack your own unit
|
|
|
|
DROID* psCurr;
|
2007-06-18 08:46:12 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
for(psCurr = apsDroidLists[selectedPlayer]; psCurr; psCurr = psCurr->psNext)
|
|
|
|
{
|
|
|
|
if ((psCurr != psDroid) && // can't attack yourself
|
|
|
|
(psCurr->selected))
|
|
|
|
{
|
|
|
|
DROID_OACTION_INFO oaInfo = {{NULL}};
|
|
|
|
|
|
|
|
if ((psCurr->droidType == DROID_WEAPON) ||
|
|
|
|
(psCurr->droidType == DROID_CYBORG) ||
|
|
|
|
(psCurr->droidType == DROID_CYBORG_SUPER) ||
|
|
|
|
(psCurr->droidType == DROID_COMMAND))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
oaInfo.objects[0] = (BASE_OBJECT*)psDroid;
|
|
|
|
orderDroidObj(psCurr, DORDER_ATTACK, &oaInfo);
|
2007-06-28 10:47:08 -07:00
|
|
|
FeedbackOrderGiven();
|
|
|
|
}
|
2007-06-17 14:02:57 -07:00
|
|
|
else if (psCurr->droidType == DROID_SENSOR)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
oaInfo.objects[0] = (BASE_OBJECT*)psDroid;
|
|
|
|
orderDroidObj(psCurr, DORDER_OBSERVE, &oaInfo);
|
2007-06-28 10:47:08 -07:00
|
|
|
FeedbackOrderGiven();
|
|
|
|
}
|
2007-06-17 14:02:57 -07:00
|
|
|
else if (psCurr->droidType == DROID_REPAIR ||
|
|
|
|
psCurr->droidType == DROID_CYBORG_REPAIR)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
oaInfo.objects[0] = (BASE_OBJECT*)psDroid;
|
|
|
|
orderDroidObj(psCurr, DORDER_DROIDREPAIR, &oaInfo);
|
2007-06-28 10:47:08 -07:00
|
|
|
FeedbackOrderGiven();
|
|
|
|
}
|
|
|
|
}
|
2007-06-17 14:02:57 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// Clicked on a commander? Will link to it.
|
|
|
|
else if (psDroid->droidType == DROID_COMMAND && selection != SC_INVALID &&
|
|
|
|
selection != SC_DROID_COMMAND &&
|
|
|
|
selection != SC_DROID_CONSTRUCT &&
|
|
|
|
!( keyDown(KEY_LCTRL) || keyDown(KEY_RCTRL) ) &&
|
|
|
|
!( keyDown(KEY_LSHIFT) || keyDown(KEY_RSHIFT)) )
|
|
|
|
{
|
|
|
|
turnOffMultiMsg(TRUE);
|
|
|
|
orderSelectedObj(selectedPlayer, (BASE_OBJECT*)psDroid);
|
|
|
|
FeedbackOrderGiven();
|
|
|
|
clearSelection();
|
|
|
|
assignSensorTarget((BASE_OBJECT *)psDroid);
|
|
|
|
dealWithDroidSelect(psDroid, FALSE);
|
|
|
|
turnOffMultiMsg(FALSE);
|
|
|
|
}
|
|
|
|
// Clicked on a construction unit? Will guard it.
|
|
|
|
else if ( ((psDroid->droidType == DROID_CONSTRUCT) || (psDroid->droidType == DROID_SENSOR) )
|
|
|
|
&& selection == SC_DROID_DIRECT)
|
|
|
|
{
|
|
|
|
orderSelectedObj(selectedPlayer, (BASE_OBJECT*)psDroid);
|
|
|
|
FeedbackOrderGiven();
|
|
|
|
}
|
|
|
|
// Clicked on a damaged unit? Will repair it.
|
|
|
|
else if (droidIsDamaged(psDroid) && repairDroidSelected(selectedPlayer))
|
|
|
|
{
|
|
|
|
assignDestTarget();
|
|
|
|
orderSelectedObjAdd(selectedPlayer, (BASE_OBJECT*)psDroid, ctrlShiftDown());
|
|
|
|
FeedbackOrderGiven();
|
|
|
|
}
|
|
|
|
// Just plain clicked on?
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Display unit info.
|
|
|
|
/* We've clicked on one of our own droids */
|
|
|
|
if(godMode)
|
|
|
|
{
|
|
|
|
CONPRINTF(ConsoleString, (ConsoleString,
|
2007-06-23 04:54:48 -07:00
|
|
|
_("%s - Damage %d%% - Serial ID %d - Kills %d order %d action %d, %s"),
|
2007-06-17 14:02:57 -07:00
|
|
|
droidGetName(psDroid), 100 - PERCENT(psDroid->body,
|
2007-06-23 05:48:03 -07:00
|
|
|
psDroid->originalBody),psDroid->id, psDroid->numKills / 100,
|
2007-06-17 14:02:57 -07:00
|
|
|
psDroid->order, psDroid->action, getDroidLevelName(psDroid)));
|
|
|
|
FeedbackClickedOn();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(!psDroid->selected)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
CONPRINTF(ConsoleString, (ConsoleString,
|
|
|
|
_("%s - Damage %d%% - Kills %d, %s"),
|
|
|
|
droidGetName(psDroid), 100 - PERCENT(psDroid->body,
|
2007-06-23 05:48:03 -07:00
|
|
|
psDroid->originalBody), psDroid->numKills / 100,
|
2007-06-17 14:02:57 -07:00
|
|
|
getDroidLevelName(psDroid)));
|
|
|
|
FeedbackClickedOn();
|
|
|
|
}
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
if(psDroid->droidType == DROID_SENSOR)
|
|
|
|
{
|
|
|
|
DROID* psCurr;
|
2007-06-18 08:46:12 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
//bWeapDroidSelected = FALSE;
|
|
|
|
bSensorAssigned = FALSE;
|
|
|
|
for(psCurr = apsDroidLists[selectedPlayer]; psCurr; psCurr = psCurr->psNext)
|
|
|
|
{
|
|
|
|
//must be indirect weapon droid or VTOL weapon droid
|
|
|
|
if( (psCurr->droidType == DROID_WEAPON) &&
|
|
|
|
(psCurr->selected)&&
|
|
|
|
(psCurr->asWeaps[0].nStat > 0) &&
|
|
|
|
((!proj_Direct(asWeaponStats + psCurr->asWeaps[0].nStat)) ||
|
|
|
|
vtolDroid(psCurr)) &&
|
|
|
|
droidSensorDroidWeapon((BASE_OBJECT *)psDroid, psCurr))
|
2006-12-31 11:51:43 -08:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
DROID_OACTION_INFO oaInfo = {{NULL}};
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
//bWeapDroidSelected = TRUE;
|
|
|
|
bSensorAssigned = TRUE;
|
|
|
|
oaInfo.objects[0] = (BASE_OBJECT *)psDroid;
|
|
|
|
orderDroidObj(psCurr, DORDER_FIRESUPPORT, &oaInfo);
|
|
|
|
FeedbackOrderGiven();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//if(bWeapDroidSelected)
|
|
|
|
if (bSensorAssigned)
|
|
|
|
{
|
|
|
|
//assignSensorTarget(psDroid);
|
|
|
|
assignSensorTarget((BASE_OBJECT *)psDroid);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-17 14:02:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//cannot have LasSat struct and Droid selected
|
|
|
|
bLasSatStruct = FALSE;
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
// select/deselect etc. the droid
|
|
|
|
if(!ctrlShiftDown())
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
clearSelection();
|
|
|
|
dealWithDroidSelect(psDroid, FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
static inline void dealWithLMBStructure(STRUCTURE* psStructure, SELECTION_TYPE selection)
|
|
|
|
{
|
|
|
|
// clearSelection(); // Clear droid selection.
|
|
|
|
|
|
|
|
if(psStructure->player != selectedPlayer)
|
|
|
|
{
|
|
|
|
/* We've clicked on somebody else's building */
|
|
|
|
// addConsoleMessage("Clicked on another player's building",DEFAULT_JUSTIFY);
|
|
|
|
orderSelectedObjAdd(selectedPlayer, (BASE_OBJECT*)psStructure, ctrlShiftDown());
|
|
|
|
//lasSat structure can select a target - in multiPlayer only
|
|
|
|
if (bMultiPlayer && bLasSatStruct)
|
|
|
|
{
|
|
|
|
orderStructureObj(selectedPlayer, (BASE_OBJECT*)psStructure);
|
|
|
|
}
|
|
|
|
FeedbackOrderGiven();
|
|
|
|
driveDisableTactical();
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
return;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
/* We've clicked on our own building */
|
|
|
|
|
|
|
|
//print some info at the top of the screen for the specific structure
|
|
|
|
printStructureInfo(psStructure);
|
|
|
|
|
|
|
|
/* Got to be built. Also, you can't 'select' derricks */
|
|
|
|
if( (psStructure->status==SS_BUILT) &&
|
|
|
|
(psStructure->pStructureType->type != REF_RESOURCE_EXTRACTOR) )
|
|
|
|
{
|
|
|
|
//if selected object is an upgradeable structure then don't
|
|
|
|
//inform the interface (if not fully upgraded) and a any droid
|
|
|
|
//is selected
|
|
|
|
/* if (!(((psStructure->pStructureType->type == REF_FACTORY &&
|
|
|
|
((FACTORY *)psStructure->pFunctionality)->capacity <
|
|
|
|
NUM_FACTORY_MODULES) ||
|
|
|
|
(psStructure->pStructureType->type == REF_RESEARCH &&
|
|
|
|
((RESEARCH_FACILITY *)psStructure->pFunctionality)->capacity <
|
|
|
|
NUM_RESEARCH_MODULES) ||
|
|
|
|
(psStructure->pStructureType->type == REF_VTOL_FACTORY &&
|
|
|
|
((FACTORY *)psStructure->pFunctionality)->capacity <
|
|
|
|
NUM_FACTORY_MODULES)) &&
|
|
|
|
//constructorDroidSelected(selectedPlayer)))
|
|
|
|
anyDroidSelected(selectedPlayer)))*/
|
|
|
|
// now only display interface if nothing selected
|
|
|
|
if (!anyDroidSelected(selectedPlayer))
|
|
|
|
{
|
|
|
|
intObjectSelected((BASE_OBJECT *)psStructure);
|
|
|
|
FeedbackClickedOn();
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
// We don't actually wan't to select structures, just inform the interface we've clicked on it,
|
|
|
|
// might wan't to do this on PC as well as it fixes the problem with the interface locking multiple
|
|
|
|
// buttons in the object window.
|
2007-06-17 14:02:57 -07:00
|
|
|
if (selection == SC_INVALID)
|
|
|
|
{
|
|
|
|
STRUCTURE* psCurr;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
/* Clear old building selection(s) - should only be one */
|
|
|
|
for(psCurr = apsStructLists[selectedPlayer]; psCurr; psCurr = psCurr->psNext)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
psCurr->selected = FALSE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-17 14:02:57 -07:00
|
|
|
/* Establish new one */
|
|
|
|
psStructure->selected = TRUE;
|
|
|
|
}
|
|
|
|
//determine if LasSat structure has been selected
|
|
|
|
bLasSatStruct = FALSE;
|
|
|
|
if (lasSatStructSelected(psStructure))
|
|
|
|
{
|
|
|
|
bLasSatStruct = TRUE;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
}
|
|
|
|
else if ( (psStructure->status==SS_BUILT) &&
|
|
|
|
(psStructure->pStructureType->type == REF_RESOURCE_EXTRACTOR) &&
|
|
|
|
selection == SC_INVALID)
|
|
|
|
{
|
|
|
|
STRUCTURE* psCurr;
|
2007-06-18 08:46:12 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
/* Clear old building selection(s) - should only be one */
|
|
|
|
for(psCurr = apsStructLists[selectedPlayer]; psCurr; psCurr = psCurr->psNext)
|
|
|
|
{
|
|
|
|
psCurr->selected = FALSE;
|
|
|
|
}
|
|
|
|
/* Establish new one */
|
|
|
|
psStructure->selected = TRUE;
|
|
|
|
}
|
|
|
|
if (keyDown(KEY_LALT) || keyDown(KEY_RALT))
|
|
|
|
{
|
|
|
|
DROID* psCurr;
|
2007-06-18 08:46:12 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
// try to attack your own structure
|
|
|
|
for(psCurr = apsDroidLists[selectedPlayer]; psCurr; psCurr = psCurr->psNext)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
if (psCurr->selected)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
DROID_OACTION_INFO oaInfo = {{NULL}};
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
//if ((psCurr->droidType == DROID_WEAPON) || (psCurr->droidType == DROID_CYBORG) ||
|
|
|
|
if ((psCurr->droidType == DROID_WEAPON) || cyborgDroid(psCurr) ||
|
|
|
|
(psCurr->droidType == DROID_COMMAND))
|
|
|
|
{
|
|
|
|
oaInfo.objects[0] = (BASE_OBJECT*)psStructure;
|
|
|
|
orderDroidObj(psCurr, DORDER_ATTACK, &oaInfo);
|
|
|
|
FeedbackOrderGiven();
|
|
|
|
}
|
|
|
|
else if (psCurr->droidType == DROID_SENSOR)
|
2007-05-29 19:06:46 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
oaInfo.objects[0] = (BASE_OBJECT*)psStructure;
|
|
|
|
orderDroidObj(psCurr, DORDER_OBSERVE, &oaInfo);
|
|
|
|
FeedbackOrderGiven();
|
2007-05-29 19:06:46 -07:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-17 14:02:57 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bSensorAssigned = FALSE;
|
|
|
|
orderSelectedObjAdd(selectedPlayer, (BASE_OBJECT*)psStructure, ctrlShiftDown());
|
|
|
|
FeedbackOrderGiven();
|
|
|
|
if (bSensorAssigned)
|
|
|
|
{
|
|
|
|
clearSelection();
|
|
|
|
assignSensorTarget((BASE_OBJECT *)psStructure);
|
|
|
|
}
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
driveDisableTactical();
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
static inline void dealWithLMBFeature(FEATURE* psFeature)
|
|
|
|
{
|
|
|
|
//some features are targetable
|
|
|
|
//check for constructor droid trying to remove wrecked building first
|
|
|
|
if (psFeature->psStats->subType == FEAT_BUILD_WRECK &&
|
|
|
|
(constructorDroidSelected(selectedPlayer) != NULL) )
|
|
|
|
{
|
|
|
|
orderSelectedObjAdd(selectedPlayer, (BASE_OBJECT*)psFeature, ctrlShiftDown());
|
|
|
|
FeedbackOrderGiven();
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
//go on to check for
|
|
|
|
if (psFeature->psStats->damageable)
|
|
|
|
{
|
|
|
|
orderSelectedObjAdd(selectedPlayer, (BASE_OBJECT*)psFeature, ctrlShiftDown());
|
|
|
|
//lasSat structure can select a target - in multiPlayer only
|
|
|
|
if (bMultiPlayer && bLasSatStruct)
|
|
|
|
{
|
|
|
|
orderStructureObj(selectedPlayer, (BASE_OBJECT*)psFeature);
|
|
|
|
}
|
|
|
|
FeedbackOrderGiven();
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
//clicking an oil field should start a build..
|
|
|
|
//if(psFeature->subType == FEAT_OIL_RESOURCE)
|
|
|
|
if(psFeature->psStats->subType == FEAT_OIL_RESOURCE)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
// find any construction droids. and order them to build an oil resource.
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
// first find the derrick.
|
|
|
|
for(i = 0; (i < numStructureStats) && (asStructureStats[i].type != REF_RESOURCE_EXTRACTOR); ++i);
|
|
|
|
|
|
|
|
if( (i < numStructureStats) &&
|
|
|
|
(apStructTypeLists[selectedPlayer][i] == AVAILABLE) ) // dont go any further if no derrick stat found.
|
|
|
|
{
|
|
|
|
DROID* psCurr;
|
2007-06-18 08:46:12 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
// for each droid
|
|
|
|
for(psCurr = apsDroidLists[selectedPlayer]; psCurr; psCurr = psCurr->psNext)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
//if((droidType(psDroid) == DROID_CONSTRUCT) && (psDroid->selected))
|
|
|
|
if ((droidType(psCurr) == DROID_CONSTRUCT ||
|
|
|
|
droidType(psCurr) == DROID_CYBORG_CONSTRUCT) && (psCurr->selected))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
if(fireOnLocation(psFeature->x,psFeature->y))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
// Can't build because it's burning
|
|
|
|
AddDerrickBurningMessage();
|
|
|
|
break;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-18 08:46:12 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
if (ctrlShiftDown())
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
orderDroidStatsLocAdd(psCurr, DORDER_BUILD,
|
|
|
|
(BASE_STATS*) &asStructureStats[i],
|
|
|
|
psFeature->x, psFeature->y);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
orderDroidStatsLoc(psCurr, DORDER_BUILD,
|
|
|
|
(BASE_STATS*) &asStructureStats[i],
|
|
|
|
psFeature->x, psFeature->y);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-17 14:02:57 -07:00
|
|
|
addConsoleMessage(_("Truck ordered to build Oil Derrick"),DEFAULT_JUSTIFY);
|
|
|
|
// "Construction vehicle ordered to build a Derrick.",DEFAULT_JUSTIFY);
|
|
|
|
FeedbackOrderGiven();
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
}
|
2007-06-17 14:02:57 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-14 13:59:04 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
switch(psFeature->psStats->subType)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
case FEAT_GEN_ARTE:
|
|
|
|
case FEAT_OIL_DRUM:
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
DROID_OACTION_INFO oaInfo = {{NULL}};
|
|
|
|
DROID* psNearestUnit = getNearestDroid(mouseTileX*TILE_UNITS+TILE_UNITS/2,
|
|
|
|
mouseTileY*TILE_UNITS+TILE_UNITS/2,TRUE);
|
|
|
|
/* If so then find the nearest unit! */
|
|
|
|
if(psNearestUnit) // bloody well should be!!!
|
|
|
|
{
|
|
|
|
oaInfo.objects[0] = (BASE_OBJECT *)psFeature;
|
|
|
|
// orderDroidLoc(psNearestUnit,DORDER_MOVE, mouseTileX*TILE_UNITS+TILE_UNITS/2,mouseTileY*TILE_UNITS+TILE_UNITS/2);
|
|
|
|
orderDroidObj(psNearestUnit, DORDER_RECOVER, &oaInfo);
|
|
|
|
FeedbackOrderGiven();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// orderSelectedLoc(selectedPlayer, psFeature->x,psFeature->y); // recover it.
|
|
|
|
orderSelectedObj(selectedPlayer, (BASE_OBJECT*)psFeature);
|
|
|
|
FeedbackOrderGiven();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
/* case FEAT_OIL_DRUM:
|
|
|
|
psNearestUnit = getNearestDroid(mouseTileX*TILE_UNITS+TILE_UNITS/2,
|
|
|
|
mouseTileY*TILE_UNITS+TILE_UNITS/2,TRUE);
|
|
|
|
// If so then find the nearest unit!
|
|
|
|
if(psNearestUnit) // bloody well should be!!!
|
|
|
|
{
|
|
|
|
orderDroidLoc(psNearestUnit,DORDER_MOVE, mouseTileX*TILE_UNITS+TILE_UNITS/2,mouseTileY*TILE_UNITS+TILE_UNITS/2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
orderSelectedLoc(selectedPlayer, psFeature->x,psFeature->y); // recover it.
|
|
|
|
}
|
|
|
|
break;*/
|
|
|
|
case FEAT_BOULDER:
|
|
|
|
//addConsoleMessage("Clicked on a Boulder",DEFAULT_JUSTIFY);
|
|
|
|
break;
|
|
|
|
case FEAT_BUILD_WRECK:
|
|
|
|
// addConsoleMessage("Clicked on a Wrecked Building",DEFAULT_JUSTIFY);
|
|
|
|
break;
|
|
|
|
case FEAT_HOVER:
|
|
|
|
// addConsoleMessage("Clicked on a Hover",DEFAULT_JUSTIFY);
|
|
|
|
break;
|
|
|
|
case FEAT_OIL_RESOURCE:
|
|
|
|
case FEAT_VEHICLE:
|
|
|
|
default:
|
|
|
|
// addConsoleMessage("Clicked on an Obstacle",DEFAULT_JUSTIFY);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
driveDisableTactical();
|
|
|
|
}
|
2007-06-14 13:59:04 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
static inline void dealWithLMBObject(BASE_OBJECT* psClickedOn)
|
|
|
|
{
|
|
|
|
SELECTION_TYPE selection = establishSelection(selectedPlayer);
|
2007-06-14 13:59:04 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
switch (psClickedOn->type)
|
|
|
|
{
|
|
|
|
case OBJ_DROID:
|
|
|
|
dealWithLMBDroid((DROID*)psClickedOn, selection);
|
|
|
|
break;
|
2007-06-18 08:46:12 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
case OBJ_STRUCTURE:
|
|
|
|
dealWithLMBStructure((STRUCTURE*)psClickedOn, selection);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OBJ_FEATURE:
|
|
|
|
dealWithLMBFeature((FEATURE*)psClickedOn);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ASSERT(!"unknown object type", "Weirdy selection from LMB?!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void dealWithLMB( void )
|
|
|
|
{
|
|
|
|
BASE_OBJECT *psClickedOn;
|
|
|
|
OBJECT_POSITION *psLocation;
|
|
|
|
|
|
|
|
|
|
|
|
/* Don't process if in game options are on screen */
|
|
|
|
if(InGameOpUp == TRUE || widgGetFromID(psWScreen,INTINGAMEOP))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* What have we clicked on? */
|
|
|
|
if(driveModeActive() && !driveTacticalActive())
|
|
|
|
{
|
|
|
|
psClickedOn = targetGetCurrent();
|
|
|
|
if (psClickedOn)
|
|
|
|
{
|
|
|
|
dealWithLMBObject(psClickedOn);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-17 14:02:57 -07:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
psClickedOn = mouseTarget();
|
|
|
|
if (psClickedOn)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
dealWithLMBObject(psClickedOn);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Check for a Delivery Point or a Proximity Message*/
|
|
|
|
psLocation = checkMouseLoc();
|
|
|
|
if (psLocation == NULL || driveModeActive() || selNumSelected(selectedPlayer))
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
#ifdef TEST_EFFECT
|
|
|
|
// Code to test an effect when left mouse button pressed
|
2007-06-17 14:02:57 -07:00
|
|
|
Vector3i Pos;
|
|
|
|
Pos.x = mouseTileX*TILE_UNITS+TILE_UNITS/2;
|
|
|
|
Pos.z = mouseTileY*TILE_UNITS+TILE_UNITS/2;
|
|
|
|
Pos.y = 100;
|
|
|
|
#if 0
|
|
|
|
addEffect(&Pos,EFFECT_EXPLOSION,EXPLOSION_TYPE_SPECIFIED,TRUE,resGetData("IMD","fxlswave.pie"));
|
2007-06-18 08:46:12 -07:00
|
|
|
debug(LOG_NEVER, "Added test effect %p : %d,%d,%d\n",resGetData("IMD","fxlswave.pie"),Pos.x,Pos.y,Pos.z);
|
2007-06-17 14:02:57 -07:00
|
|
|
addEffect(&Pos,EFFECT_GRAVITON,GRAVITON_TYPE_EMITTING_DR,TRUE,debrisImds[rand()%MAX_DEBRIS]);
|
|
|
|
#endif
|
|
|
|
addEffect(&Pos,EFFECT_EXPLOSION,EXPLOSION_TYPE_MEDIUM,FALSE,NULL,0);
|
2007-06-28 10:47:08 -07:00
|
|
|
#endif
|
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
// now changed to use the multiple order stuff
|
|
|
|
if(ctrlShiftDown()) // shift clicked a destination, add an order
|
|
|
|
{
|
|
|
|
orderSelectedLocAdd(selectedPlayer,
|
|
|
|
mouseTileX*TILE_UNITS+TILE_UNITS/2,
|
|
|
|
mouseTileY*TILE_UNITS+TILE_UNITS/2, TRUE);
|
|
|
|
}
|
|
|
|
else // clicked on a destination.
|
|
|
|
{
|
|
|
|
/* Otherwise send them all */
|
|
|
|
orderSelectedLoc(selectedPlayer, mouseTileX*TILE_UNITS+TILE_UNITS/2,mouseTileY*TILE_UNITS+TILE_UNITS/2);
|
|
|
|
//DBPRINTF(("orderSelectedLoc(%d,%d,%d)\n",selectedPlayer, mouseTileX*TILE_UNITS+TILE_UNITS/2,mouseTileY*TILE_UNITS+TILE_UNITS/2));
|
|
|
|
if(getNumDroidsSelected())
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
assignDestTarget();
|
|
|
|
audio_PlayTrack( ID_SOUND_SELECT );
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-17 14:02:57 -07:00
|
|
|
|
|
|
|
if(godMode && (mouseTileX >= 0) && (mouseTileX < (SDWORD)mapWidth) &&
|
|
|
|
(mouseTileY >= 0) && (mouseTileY < (SDWORD)mapHeight))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-17 14:02:57 -07:00
|
|
|
DBCONPRINTF(ConsoleString,(ConsoleString,"Tile Coords : %d,%d (%d,%d) Zone :%d", mouseTileX,mouseTileY,
|
|
|
|
mouseTileX*TILE_UNITS + TILE_UNITS/2, mouseTileY*TILE_UNITS + TILE_UNITS/2,
|
|
|
|
gwGetZone(mouseTileX, mouseTileY)));
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
//addConsoleMessage("Droid ordered to new location",DEFAULT_JUSTIFY);
|
|
|
|
}
|
2007-06-18 08:46:12 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
driveDisableTactical();
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-17 14:02:57 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (psLocation->type)
|
|
|
|
{
|
|
|
|
case POS_DELIVERY:
|
|
|
|
if(psLocation->player == selectedPlayer)
|
|
|
|
{
|
|
|
|
StartDeliveryPosition( psLocation );
|
|
|
|
#if 0
|
|
|
|
/* We've clicked on one of our own DP */
|
|
|
|
addConsoleMessage("Clicked on your delivery point",DEFAULT_JUSTIFY);
|
|
|
|
|
|
|
|
/* clear the selection */
|
|
|
|
clearSelection();
|
|
|
|
|
|
|
|
//set this object position to be highlighted
|
|
|
|
psLocation->selected = TRUE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-17 14:02:57 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We've clicked on somebody else's DP - remove this sometime?*/
|
|
|
|
addConsoleMessage("Clicked on another player's delivery point",DEFAULT_JUSTIFY);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
case POS_PROX:
|
|
|
|
if(psLocation->player == selectedPlayer)
|
|
|
|
{
|
|
|
|
displayProximityMessage((PROXIMITY_DISPLAY *)psLocation);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
ASSERT(!"unknown object position type", "Unknown type from checkMouseLoc" );
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL getRotActive( void )
|
|
|
|
{
|
|
|
|
return(rotActive);
|
|
|
|
}
|
|
|
|
|
|
|
|
SDWORD getDesiredPitch( void )
|
|
|
|
{
|
|
|
|
return(desiredPitch);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setDesiredPitch(SDWORD pitch)
|
|
|
|
{
|
|
|
|
desiredPitch = pitch;
|
|
|
|
}
|
|
|
|
|
|
|
|
// process LMB double clicks
|
|
|
|
void dealWithLMBDClick(void)
|
|
|
|
{
|
|
|
|
BASE_OBJECT *psClickedOn;
|
|
|
|
DROID *psDroid;
|
|
|
|
|
|
|
|
/* What have we clicked on? */
|
|
|
|
psClickedOn = mouseTarget();
|
|
|
|
/* If not NULL, then it's a droid or a structure */
|
|
|
|
if(psClickedOn != NULL)
|
|
|
|
{
|
|
|
|
/* We've got a droid or a structure */
|
|
|
|
if(psClickedOn->type == OBJ_DROID)
|
|
|
|
{
|
|
|
|
/* We clicked on droid */
|
|
|
|
psDroid = (DROID *) psClickedOn;
|
|
|
|
if(psDroid->player == selectedPlayer)
|
|
|
|
{
|
|
|
|
/* If we've double clicked on a constructor droid, activate build menu */
|
|
|
|
//if (psDroid->droidType == DROID_CONSTRUCT)
|
2007-05-29 19:06:46 -07:00
|
|
|
if (psDroid->droidType == DROID_CONSTRUCT ||
|
|
|
|
psDroid->droidType == DROID_CYBORG_CONSTRUCT)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
intResetScreen(TRUE);
|
|
|
|
intConstructorSelected(psDroid);
|
|
|
|
}
|
|
|
|
else if (psDroid->droidType == DROID_COMMAND)
|
|
|
|
{
|
|
|
|
intResetScreen(TRUE);
|
|
|
|
intCommanderSelected(psDroid);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Otherwise, activate the droid's group (if any) */
|
|
|
|
// activateGroup(selectedPlayer,psDroid->group);
|
|
|
|
// Now selects all of smae type on screen
|
|
|
|
selDroidSelection(selectedPlayer,DS_BY_TYPE,DST_ALL_SAME,TRUE);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*This checks to see if the mouse was over a delivery point or a proximity message
|
2007-05-29 19:06:46 -07:00
|
|
|
when the mouse button was pressed */
|
2007-06-28 10:47:08 -07:00
|
|
|
OBJECT_POSITION * checkMouseLoc(void)
|
|
|
|
{
|
|
|
|
OBJECT_POSITION *psReturn;
|
|
|
|
FLAG_POSITION *psPoint;
|
|
|
|
//PROXIMITY_DISPLAY *psProxDisp;
|
|
|
|
UDWORD i;
|
|
|
|
UDWORD dispX,dispY,dispR;
|
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
// We haven't found anything yet
|
2007-06-28 10:47:08 -07:00
|
|
|
psReturn = NULL;
|
|
|
|
|
|
|
|
// First have a look through the DeliveryPoint lists
|
|
|
|
for (i=0; i<MAX_PLAYERS; i++)
|
|
|
|
{
|
|
|
|
//new way, handles multiple points.
|
|
|
|
for(psPoint = apsFlagPosLists[i];psPoint;psPoint=psPoint->psNext)
|
|
|
|
{
|
|
|
|
dispX = psPoint->screenX;
|
|
|
|
dispY = psPoint->screenY;
|
|
|
|
dispR = psPoint->screenR;
|
2006-05-27 09:37:17 -07:00
|
|
|
if (DrawnInLastFrame(psPoint->frameNumber)==TRUE) // Only check DP's that are on screen
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
if (mouseInBox(dispX-dispR, dispY-dispR, dispX+dispR, dispY+dispR))
|
|
|
|
{
|
|
|
|
// We HAVE clicked on DP!
|
|
|
|
psReturn = (OBJECT_POSITION *)psPoint;
|
2006-05-27 09:37:17 -07:00
|
|
|
//There's no point in checking other object types
|
|
|
|
return(psReturn);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// old way, only one point allowed.
|
|
|
|
//
|
2006-05-27 09:37:17 -07:00
|
|
|
// //look throught the list of structures to see if there is a factory
|
2007-06-28 10:47:08 -07:00
|
|
|
// //and therefore a DP
|
|
|
|
// for (psStructure = apsStructLists[i]; psStructure; psStructure = psStructure->psNext)
|
|
|
|
// {
|
|
|
|
// if (psStructure->pStructureType->type == REF_FACTORY)
|
|
|
|
// {
|
|
|
|
// psPoint = ((FACTORY *)psStructure->pFunctionality)->psAssemblyPoint;
|
|
|
|
// dispX = psPoint->screenX;
|
|
|
|
// dispY = psPoint->screenY;
|
|
|
|
// dispR = psPoint->screenR;
|
2006-05-27 09:37:17 -07:00
|
|
|
// // Only check DP's that are on screen
|
2007-06-28 10:47:08 -07:00
|
|
|
// if (DrawnInLastFrame(psPoint->frameNumber)==TRUE)
|
|
|
|
// {
|
|
|
|
// if (mouseInBox(dispX-dispR, dispY-dispR, dispX+dispR, dispY+dispR))
|
|
|
|
// {
|
|
|
|
// // We HAVE clicked on DP!
|
|
|
|
// psReturn = psPoint;
|
2006-05-27 09:37:17 -07:00
|
|
|
// //There's no point in checking other object types
|
2007-06-28 10:47:08 -07:00
|
|
|
// return(psReturn);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// } // end of checking for droids
|
|
|
|
|
|
|
|
}
|
|
|
|
//now check for Proximity Message
|
2006-05-27 09:37:17 -07:00
|
|
|
/*for(psProxDisp = apsProxDisp[selectedPlayer]; psProxDisp; psProxDisp =
|
2007-06-28 10:47:08 -07:00
|
|
|
psProxDisp->psNext)
|
|
|
|
{
|
|
|
|
dispX = psProxDisp->screenX;
|
|
|
|
dispY = psProxDisp->screenY;
|
|
|
|
dispR = psProxDisp->screenR;
|
2006-05-27 09:37:17 -07:00
|
|
|
// Only check DP's that are on screen
|
2007-06-28 10:47:08 -07:00
|
|
|
if (DrawnInLastFrame(psProxDisp->frameNumber)==TRUE)
|
|
|
|
{
|
|
|
|
if (mouseInBox(dispX-dispR, dispY-dispR, dispX+dispR, dispY+dispR))
|
|
|
|
{
|
|
|
|
// We HAVE clicked on Proximity Message!
|
|
|
|
psReturn = (OBJECT_POSITION *)psProxDisp;
|
2006-05-27 09:37:17 -07:00
|
|
|
//There's no point in checking other object types
|
2007-06-28 10:47:08 -07:00
|
|
|
return(psReturn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void dealWithRMB( void )
|
|
|
|
{
|
|
|
|
BASE_OBJECT *psClickedOn;
|
|
|
|
DROID *psDroid;
|
|
|
|
STRUCTURE *psStructure;
|
|
|
|
STRUCTURE *psSLoop;
|
|
|
|
|
|
|
|
//printf("dealWithRMB %d\n",mouseOverRadar);
|
|
|
|
|
|
|
|
if(driveModeActive()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mouseOverRadar) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
//RMB will always cancel the selection of the Las Sat struct
|
|
|
|
bLasSatStruct = FALSE;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
/* What have we clicked on? */
|
|
|
|
psClickedOn = mouseTarget();
|
|
|
|
/* If not NULL, then it's a droid or a structure */
|
|
|
|
if(psClickedOn != NULL)
|
|
|
|
{
|
|
|
|
/* We've got a droid or a structure */
|
|
|
|
if(psClickedOn->type == OBJ_DROID )
|
|
|
|
{
|
|
|
|
// if(radarCheckForHQ(selectedPlayer)) // removed by Jim, well kind of, he asked 19 oct 98
|
|
|
|
{
|
|
|
|
/* We clicked on droid */
|
|
|
|
psDroid = (DROID *) psClickedOn;
|
|
|
|
if(psDroid->player == selectedPlayer)
|
|
|
|
{
|
|
|
|
//ignore RMB on a Transporter - for now?
|
|
|
|
if ( (psDroid->droidType != DROID_TRANSPORTER) )
|
|
|
|
{
|
|
|
|
/* We've clicked on one of our own droids */
|
|
|
|
// addGameMessage("Right clicked on own droid",1000,TRUE);
|
|
|
|
// addConsoleMessage("Right click detected on own droid",DEFAULT_JUSTIFY);
|
|
|
|
|
|
|
|
if(psDroid->selected==TRUE)
|
|
|
|
{
|
|
|
|
// psDroid->selected = FALSE;
|
|
|
|
// intObjectSelected(NULL);
|
|
|
|
intObjectSelected((BASE_OBJECT *)psDroid);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clearSelection();
|
|
|
|
// psDroid->selected = TRUE;
|
|
|
|
SelectDroid(psDroid);
|
|
|
|
intObjectSelected((BASE_OBJECT *)psDroid);
|
|
|
|
}
|
|
|
|
}
|
2007-05-29 19:06:46 -07:00
|
|
|
//it was only just 'for now'!!!
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (bMultiPlayer)
|
|
|
|
{
|
|
|
|
intResetScreen(FALSE);
|
|
|
|
if(!getWidgetsStatus())
|
|
|
|
{
|
|
|
|
setWidgetsStatus(TRUE);
|
|
|
|
}
|
|
|
|
addTransporterInterface(psDroid, FALSE);
|
|
|
|
}
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(bMultiPlayer)
|
|
|
|
{
|
|
|
|
if(isHumanPlayer(psDroid->player) )
|
|
|
|
{
|
|
|
|
CONPRINTF(ConsoleString, (ConsoleString,"%s",droidGetName(psDroid)));
|
|
|
|
FeedbackClickedOn();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
} // end if its a droid
|
|
|
|
else if (psClickedOn->type == OBJ_STRUCTURE)
|
|
|
|
{
|
|
|
|
psStructure = (STRUCTURE *) psClickedOn;
|
|
|
|
if(psStructure->player == selectedPlayer)
|
|
|
|
{
|
|
|
|
/* We've clicked on our own building */
|
|
|
|
// addGameMessage("Right clicked on own building",1000,TRUE);
|
|
|
|
// addConsoleMessage("Right clicked on own building",DEFAULT_JUSTIFY);
|
|
|
|
|
|
|
|
|
|
|
|
if(psStructure->selected==TRUE) {
|
|
|
|
psStructure->selected = FALSE;
|
|
|
|
intObjectSelected(NULL);
|
|
|
|
} else {
|
|
|
|
// We don't actually wan't to select structures, just inform the interface weve clicked on it,
|
|
|
|
// might wan't to do this on PC as well as it fixes the problem with the interface locking multiple
|
|
|
|
// buttons in the object window.
|
|
|
|
// clearSelection();
|
|
|
|
/* Clear old building selection(s) - should only be one */
|
|
|
|
for(psSLoop = apsStructLists[selectedPlayer]; psSLoop; psSLoop = psSLoop->psNext)
|
|
|
|
{
|
|
|
|
psSLoop->selected = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// psStructure->selected = TRUE;
|
|
|
|
//if a factory go to deliv point rather than setting up the interface
|
|
|
|
if (StructIsFactory(psStructure))
|
|
|
|
{
|
2007-07-08 15:47:13 -07:00
|
|
|
setViewPos(map_coord(psStructure->pFunctionality->factory.psAssemblyPoint->coords.x),
|
|
|
|
map_coord(psStructure->pFunctionality->factory.psAssemblyPoint->coords.y),
|
|
|
|
TRUE);
|
2007-05-29 19:06:46 -07:00
|
|
|
//pop up the order interface for the factory - AB 21/04/99 Patch v1.2->
|
|
|
|
intAddFactoryOrder(psStructure);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
else if (psStructure->pStructureType->type == REF_REPAIR_FACILITY)
|
|
|
|
{
|
2007-07-08 15:47:13 -07:00
|
|
|
setViewPos(map_coord(psStructure->pFunctionality->repairFacility.psDeliveryPoint->coords.x),
|
|
|
|
map_coord(psStructure->pFunctionality->repairFacility.psDeliveryPoint->coords.y),
|
|
|
|
TRUE);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
intObjectSelected((BASE_OBJECT *)psStructure);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // end if its a structure
|
|
|
|
/* And if it's not a feature, then we're in trouble! */
|
|
|
|
else if (psClickedOn->type != OBJ_FEATURE)
|
2006-05-27 09:37:17 -07:00
|
|
|
{
|
2006-08-23 05:58:48 -07:00
|
|
|
ASSERT( FALSE,"Weirdy selection from RMB?!" );
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/*Check for a Delivery Point*/
|
2007-06-14 13:59:04 -07:00
|
|
|
OBJECT_POSITION* psLocation = checkMouseLoc();
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
if (psLocation)
|
|
|
|
{
|
|
|
|
switch (psLocation->type)
|
|
|
|
{
|
2007-06-14 13:59:04 -07:00
|
|
|
case POS_DELIVERY:
|
|
|
|
if(psLocation->player == selectedPlayer)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-14 13:59:04 -07:00
|
|
|
//centre the view on the owning Factory
|
|
|
|
psStructure = findDeliveryFactory((FLAG_POSITION *)psLocation);
|
|
|
|
if (psStructure)
|
|
|
|
{
|
|
|
|
setViewPos(psStructure->x >> TILE_SHIFT,
|
|
|
|
psStructure->y >> TILE_SHIFT,TRUE);
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-14 13:59:04 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ASSERT(!"unknown object position type", "Unknown type from checkMouseLoc");
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
else
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
/* We've just clicked on an area of terrain. A 'send to' operation
|
|
|
|
for Transporter in multiPlay mode*/
|
2007-06-14 13:59:04 -07:00
|
|
|
#if 0
|
|
|
|
if (bMultiPlayer)
|
2007-05-29 19:06:46 -07:00
|
|
|
{
|
|
|
|
//there may be more than one Transporter selected
|
|
|
|
for (psDroid = apsDroidLists[selectedPlayer]; psDroid != NULL;
|
|
|
|
psDroid = psDroid->psNext)
|
|
|
|
{
|
|
|
|
if (psDroid->selected)
|
|
|
|
{
|
|
|
|
if (psDroid->droidType == DROID_TRANSPORTER)
|
|
|
|
{
|
|
|
|
orderDroidLoc(psDroid, DORDER_DISEMBARK, mouseTileX *
|
|
|
|
TILE_UNITS + TILE_UNITS/2, mouseTileY * TILE_UNITS +
|
|
|
|
TILE_UNITS/2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//de-select any other units
|
|
|
|
psDroid->selected = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-06-14 13:59:04 -07:00
|
|
|
else
|
|
|
|
#endif
|
2007-05-29 19:06:46 -07:00
|
|
|
{
|
|
|
|
clearSelection();
|
|
|
|
intObjectSelected(NULL);
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* if there is a valid object under the mouse this routine returns not only the type of the object in the
|
|
|
|
return code, but also a pointer to the BASE_OBJECT) ... well if your going to be "object orientated" you might as well do it right
|
2007-05-29 19:06:46 -07:00
|
|
|
- it sets it to null if we don't find anything
|
2007-06-28 10:47:08 -07:00
|
|
|
*/
|
|
|
|
static MOUSE_TARGET itemUnderMouse( BASE_OBJECT **ppObjectUnderMouse )
|
|
|
|
{
|
|
|
|
UDWORD i;
|
|
|
|
MOUSE_TARGET retVal;
|
|
|
|
BASE_OBJECT *psNotDroid;
|
|
|
|
DROID *psDroid;
|
|
|
|
UDWORD dispX,dispY,dispR;
|
|
|
|
STRUCTURE *psStructure;
|
|
|
|
|
|
|
|
*ppObjectUnderMouse=NULL;
|
|
|
|
|
|
|
|
if(!driveModeActive() || driveTacticalActive()) {
|
2007-02-10 08:39:39 -08:00
|
|
|
if( (mouseTileX < 0) ||
|
|
|
|
(mouseTileY < 0) ||
|
|
|
|
(mouseTileX > (SDWORD)(mapWidth-1)) ||
|
2007-06-28 10:47:08 -07:00
|
|
|
(mouseTileY > (SDWORD)(mapHeight-1)) )
|
|
|
|
{
|
|
|
|
retVal = MT_BLOCKING;
|
|
|
|
return(retVal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//DBPRINTF(("%d %d\n",mouseTileX,mouseTileY);
|
|
|
|
|
|
|
|
/* We haven't found anything yet */
|
|
|
|
retVal = MT_NOTARGET;
|
|
|
|
|
|
|
|
if(driveModeActive() && !driveTacticalActive()) {
|
|
|
|
BASE_OBJECT *psObj = targetGetCurrent();
|
|
|
|
if(psObj != NULL) {
|
|
|
|
|
|
|
|
if(psObj->type == OBJ_DROID) {
|
|
|
|
psDroid = (DROID*)psObj;
|
|
|
|
if(psDroid->player == selectedPlayer)
|
|
|
|
{
|
|
|
|
*ppObjectUnderMouse=psObj;
|
|
|
|
// need to check for command droids here as well
|
|
|
|
if (psDroid->droidType == DROID_SENSOR)
|
|
|
|
{
|
|
|
|
// DBPRINTF(("MT_SENSOR\n");
|
|
|
|
return MT_SENSOR;
|
|
|
|
}
|
|
|
|
else if (psDroid->droidType == DROID_TRANSPORTER)
|
|
|
|
{
|
|
|
|
// DBPRINTF(("MT_TRANDROID\n");
|
2007-05-29 19:06:46 -07:00
|
|
|
//check the transporter is not full
|
|
|
|
if (calcRemainingCapacity(psDroid))
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
return MT_TRANDROID;
|
2007-05-29 19:06:46 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return MT_BLOCKING;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-02-10 08:39:39 -08:00
|
|
|
else if (psDroid->droidType == DROID_CONSTRUCT ||
|
2007-05-29 19:06:46 -07:00
|
|
|
psDroid->droidType == DROID_CYBORG_CONSTRUCT)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return MT_CONSTRUCT;
|
|
|
|
}
|
|
|
|
else if (psDroid->droidType == DROID_COMMAND)
|
|
|
|
{
|
|
|
|
// DBPRINTF(("MT_COMMAND\n");
|
|
|
|
return MT_COMMAND;
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
else
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
if (droidIsDamaged(psDroid))
|
|
|
|
{
|
|
|
|
// DBPRINTF(("MT_OWNDROIDDAM\n");
|
|
|
|
return MT_OWNDROIDDAM;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// return MT_OWNDROID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// DBPRINTF(("MT_ENEMYDROID\n");
|
|
|
|
return MT_ENEMYDROID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if( (psObj->type == OBJ_DROID) && (psObj->player != selectedPlayer) ) {
|
|
|
|
// return MT_ENEMYDROID;
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* First have a look through the droid lists */
|
|
|
|
for (i=0; i<MAX_PLAYERS; i++)
|
|
|
|
{
|
|
|
|
/* Note the !psObject check isn't really necessary as the goto will jump out */
|
2006-05-27 09:37:17 -07:00
|
|
|
for (psDroid = apsDroidLists[i]; psDroid && retVal==MT_NOTARGET;
|
2007-05-29 19:06:46 -07:00
|
|
|
psDroid = psDroid->psNext)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
dispX = psDroid->sDisplay.screenX;
|
|
|
|
dispY = psDroid->sDisplay.screenY;
|
|
|
|
dispR = psDroid->sDisplay.screenR;
|
|
|
|
/* Only check droids that're on screen */
|
2007-05-29 19:06:46 -07:00
|
|
|
if(psDroid->sDisplay.frameNumber+1 == currentFrame && psDroid->visible[selectedPlayer] )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
if (mouseInBox(dispX-dispR, dispY-dispR, dispX+dispR, dispY+dispR))
|
|
|
|
{
|
|
|
|
/* We HAVE clicked on droid! */
|
|
|
|
if(psDroid->player == selectedPlayer)
|
|
|
|
{
|
|
|
|
*ppObjectUnderMouse=(BASE_OBJECT *)psDroid;
|
|
|
|
// need to check for command droids here as well
|
|
|
|
if (psDroid->droidType == DROID_SENSOR)
|
|
|
|
{
|
|
|
|
retVal = MT_SENSOR;
|
|
|
|
}
|
|
|
|
else if (psDroid->droidType == DROID_TRANSPORTER)
|
|
|
|
{
|
2007-05-29 19:06:46 -07:00
|
|
|
//check the transporter is not full
|
|
|
|
if (calcRemainingCapacity(psDroid))
|
|
|
|
{
|
|
|
|
retVal = MT_TRANDROID;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
retVal = MT_BLOCKING;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-02-10 08:39:39 -08:00
|
|
|
else if (psDroid->droidType == DROID_CONSTRUCT ||
|
2007-05-29 19:06:46 -07:00
|
|
|
psDroid->droidType == DROID_CYBORG_CONSTRUCT)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return MT_CONSTRUCT;
|
|
|
|
}
|
|
|
|
else if (psDroid->droidType == DROID_COMMAND)
|
|
|
|
{
|
|
|
|
retVal = MT_COMMAND;
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
else
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
if (droidIsDamaged(psDroid))
|
|
|
|
{
|
|
|
|
retVal = MT_OWNDROIDDAM;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
retVal = MT_OWNDROID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*ppObjectUnderMouse=(BASE_OBJECT *)psDroid;
|
|
|
|
//printf("Enemy Droid %d %d %d\n",dispX,dispY,dispR);
|
|
|
|
retVal = MT_ENEMYDROID;
|
|
|
|
}
|
|
|
|
/* There's no point in checking other object types */
|
|
|
|
return(retVal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // end of checking for droids
|
|
|
|
}
|
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
/* Not a droid, so maybe a structure or feature?
|
2007-06-28 10:47:08 -07:00
|
|
|
If still NULL after this then nothing */
|
|
|
|
if(driveModeActive() && !driveTacticalActive()) {
|
|
|
|
psNotDroid = targetGetCurrent();
|
|
|
|
} else {
|
|
|
|
psNotDroid = getTileOccupier(mouseTileX, mouseTileY);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(psNotDroid!=NULL)
|
|
|
|
{
|
|
|
|
*ppObjectUnderMouse=(BASE_OBJECT *)psNotDroid;
|
|
|
|
|
|
|
|
if(psNotDroid->type == OBJ_FEATURE)
|
|
|
|
{
|
|
|
|
if( (((FEATURE *)psNotDroid)->psStats->subType == FEAT_GEN_ARTE)
|
|
|
|
|| (((FEATURE *)psNotDroid)->psStats->subType == FEAT_OIL_DRUM) )
|
|
|
|
{
|
|
|
|
retVal = MT_ARTIFACT;
|
|
|
|
}
|
|
|
|
else if(((FEATURE *)psNotDroid)->psStats->damageable) //make damageable features return 'target' mouse pointer
|
|
|
|
{
|
|
|
|
//printf("Damagable Feature %d %d\n",mouseTileX,mouseTileY);
|
|
|
|
retVal = MT_DAMFEATURE;
|
|
|
|
}
|
|
|
|
else if(((FEATURE *)psNotDroid)->psStats->subType == FEAT_OIL_RESOURCE)
|
|
|
|
{
|
|
|
|
retVal = MT_RESOURCE;
|
|
|
|
}
|
|
|
|
else if(((FEATURE *)psNotDroid)->psStats->subType == FEAT_BUILD_WRECK)
|
|
|
|
{
|
|
|
|
retVal = MT_WRECKFEATURE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
retVal = MT_BLOCKING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(psNotDroid->type == OBJ_STRUCTURE)
|
|
|
|
{
|
|
|
|
psStructure = (STRUCTURE *)psNotDroid;
|
|
|
|
|
|
|
|
if(psNotDroid->player == selectedPlayer)
|
|
|
|
{
|
|
|
|
if(psStructure->status == SS_BEING_BUILT)
|
|
|
|
{
|
|
|
|
retVal = MT_OWNSTRINCOMP;
|
|
|
|
}
|
|
|
|
// repair center.
|
|
|
|
else if(psStructure->pStructureType->type == REF_REPAIR_FACILITY)
|
|
|
|
{
|
|
|
|
if(buildingDamaged(psStructure))
|
|
|
|
{
|
|
|
|
retVal = MT_REPAIRDAM;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
retVal = MT_REPAIR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//sensor tower
|
2007-02-10 08:39:39 -08:00
|
|
|
else if ((psStructure->pStructureType->pSensor) &&
|
2007-06-28 10:47:08 -07:00
|
|
|
(psStructure->pStructureType->pSensor->location == LOC_TURRET))
|
|
|
|
{
|
|
|
|
if(buildingDamaged(psStructure))
|
|
|
|
{
|
2006-11-11 13:29:27 -08:00
|
|
|
retVal = MT_SENSORSTRUCTDAM;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
else
|
2006-05-27 09:37:17 -07:00
|
|
|
{
|
2006-11-11 13:29:27 -08:00
|
|
|
retVal = MT_SENSORSTRUCT;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
// standard buildings. - check for buildingDamaged BEFORE upgrades
|
|
|
|
else if(buildingDamaged(psStructure))
|
|
|
|
{
|
|
|
|
retVal = MT_OWNSTRDAM;
|
|
|
|
}
|
2007-07-08 15:47:13 -07:00
|
|
|
// If this building is a factory/power generator/research facility
|
|
|
|
// which isn't upgraded. Make the build icon available.
|
|
|
|
else if(((psStructure->pStructureType->type == REF_FACTORY
|
|
|
|
|| psStructure->pStructureType->type == REF_VTOL_FACTORY)
|
|
|
|
&& psStructure->pFunctionality->factory.capacity < NUM_FACTORY_MODULES)
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-07-08 15:47:13 -07:00
|
|
|
|| (psStructure->pStructureType->type == REF_POWER_GEN
|
|
|
|
&& psStructure->pFunctionality->powerGenerator.capacity < NUM_POWER_MODULES)
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-07-08 15:47:13 -07:00
|
|
|
|| (psStructure->pStructureType->type == REF_RESEARCH
|
|
|
|
&& psStructure->pFunctionality->researchFacility.capacity < NUM_RESEARCH_MODULES))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
retVal = MT_OWNSTRINCOMP;
|
|
|
|
}
|
|
|
|
|
|
|
|
// standard buildings.
|
|
|
|
//else if(buildingDamaged(psStructure))
|
|
|
|
//{
|
|
|
|
// retVal = MT_OWNSTRDAM;
|
|
|
|
//}
|
2006-05-27 09:37:17 -07:00
|
|
|
else
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
/* All the different stages of construction */
|
|
|
|
retVal = MT_OWNSTROK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
retVal = MT_ENEMYSTR; // enemy structure
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-05-29 19:06:46 -07:00
|
|
|
/* Send the result back - if it's null then we clicked on an area of terrain */
|
2007-06-28 10:47:08 -07:00
|
|
|
/* make unseen objects just look like terrain. */
|
|
|
|
if(retVal == MT_NOTARGET || !(psNotDroid->visible[selectedPlayer]) )
|
|
|
|
{
|
|
|
|
retVal = MT_TERRAIN;
|
|
|
|
}
|
|
|
|
return(retVal);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Indicates the priority given to any given droid
|
|
|
|
// type in a multiple droid selection, the larger the
|
|
|
|
// number, the lower the priority. The order of entries
|
|
|
|
// corresponds to the order of droid types in the DROID_TYPE
|
|
|
|
// enum in DroidDef.h
|
|
|
|
//
|
|
|
|
//#define NUM_DROID_WEIGHTS (10)
|
|
|
|
#define NUM_DROID_WEIGHTS (13)
|
|
|
|
UBYTE DroidSelectionWeights[NUM_DROID_WEIGHTS] = {
|
2006-05-27 09:37:17 -07:00
|
|
|
3, //DROID_WEAPON,
|
|
|
|
1, //DROID_SENSOR,
|
|
|
|
2, //DROID_ECM,
|
|
|
|
4, //DROID_CONSTRUCT,
|
|
|
|
3, //DROID_PERSON,
|
|
|
|
3, //DROID_CYBORG,
|
|
|
|
9, //DROID_TRANSPORTER,
|
|
|
|
0, //DROID_COMMAND,
|
|
|
|
4, //DROID_REPAIR,
|
|
|
|
5, //DROID_DEFAULT,
|
|
|
|
4, //DROID_CYBORG_CONSTRUCT,
|
|
|
|
4, //DROID_CYBORG_REPAIR,
|
|
|
|
3, //DROID_CYBORG_SUPER,
|
2007-06-28 10:47:08 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* Only deals with one type of droid being selected!!!! */
|
|
|
|
/* We'll have to make it assesss which selection is to be dominant in the case
|
|
|
|
of multiple selections */
|
|
|
|
SELECTION_TYPE establishSelection(UDWORD selectedPlayer)
|
|
|
|
{
|
|
|
|
DROID *psDroid,*psDominant=NULL;
|
|
|
|
UBYTE CurrWeight;
|
|
|
|
//BOOL gotWeapon = FALSE;
|
|
|
|
//DROID *psWeapDroid = NULL;
|
|
|
|
BOOL atLeastOne;
|
|
|
|
SELECTION_TYPE selectionClass;
|
|
|
|
|
|
|
|
atLeastOne = FALSE;
|
|
|
|
selectionClass = SC_INVALID;
|
|
|
|
CurrWeight = UBYTE_MAX;
|
|
|
|
|
|
|
|
for(psDroid = apsDroidLists[selectedPlayer];
|
2007-02-10 08:39:39 -08:00
|
|
|
psDroid /*&& !atLeastOne*/; psDroid = psDroid->psNext)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2006-05-27 09:37:17 -07:00
|
|
|
// This code dos'nt work, what about the case of a selection of DROID_WEAPON types with a
|
2007-06-28 10:47:08 -07:00
|
|
|
// DROID_CONSTRUCT type grouped with them,claims to handle this but dos'nt.
|
|
|
|
//PD if(psDroid->selected)
|
|
|
|
//PD {
|
|
|
|
//PD atLeastOne = TRUE;
|
|
|
|
//PD if(psDroid->type == DROID_WEAPON)
|
|
|
|
//PD {
|
|
|
|
//PD gotWeapon = TRUE;
|
|
|
|
//PD psWeapDroid = psDroid;
|
|
|
|
//PD }
|
|
|
|
//PD if (psDroid->droidType == DROID_COMMAND ||
|
|
|
|
//PD psDominant == NULL)
|
|
|
|
//PD {
|
|
|
|
//PD psDominant = psDroid;
|
|
|
|
//PD }
|
|
|
|
//PD }
|
|
|
|
|
|
|
|
// This works, uses the DroidSelectionWeights[] table to priorities the different
|
|
|
|
// droid types and find the dominant selection.
|
|
|
|
if(psDroid->selected) {
|
2006-08-23 05:58:48 -07:00
|
|
|
ASSERT( psDroid->droidType < NUM_DROID_WEIGHTS,
|
|
|
|
"establishSelection : droidType exceeds NUM_DROID_WEIGHTS" );
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
atLeastOne = TRUE;
|
|
|
|
if(DroidSelectionWeights[psDroid->droidType] < CurrWeight) {
|
|
|
|
CurrWeight = DroidSelectionWeights[psDroid->droidType];
|
|
|
|
psDominant = psDroid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// /* Weapon droids in a selection will override all others */
|
|
|
|
// if(psWeapDroid)
|
|
|
|
// {
|
|
|
|
// psDominant = psWeapDroid;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if(psDominant) {
|
|
|
|
// DBPRINTF(("Dominant selection type == %d\n",psDominant->droidType));
|
|
|
|
// }
|
|
|
|
|
|
|
|
if(atLeastOne)
|
|
|
|
{
|
|
|
|
psDominantSelected = psDominant;
|
|
|
|
switch(psDominant->droidType)
|
|
|
|
{
|
|
|
|
case DROID_WEAPON:
|
|
|
|
if (proj_Direct( asWeaponStats + psDominant->asWeaps[0].nStat ))
|
|
|
|
{
|
|
|
|
selectionClass = SC_DROID_DIRECT;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
selectionClass = SC_DROID_INDIRECT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DROID_PERSON:
|
|
|
|
selectionClass = SC_DROID_DIRECT;
|
|
|
|
break;
|
|
|
|
case DROID_CYBORG:
|
|
|
|
case DROID_CYBORG_SUPER:
|
|
|
|
selectionClass = SC_DROID_DIRECT;
|
|
|
|
break;
|
|
|
|
case DROID_TRANSPORTER:
|
|
|
|
//can remove this is NEVER going to select the Transporter to move
|
2007-05-29 19:06:46 -07:00
|
|
|
//Never say Never!! cos here we go in multiPlayer!!
|
2007-06-28 10:47:08 -07:00
|
|
|
selectionClass = SC_DROID_TRANSPORTER;
|
|
|
|
break;
|
|
|
|
case DROID_SENSOR:
|
|
|
|
selectionClass = SC_DROID_SENSOR;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DROID_ECM:
|
|
|
|
selectionClass = SC_DROID_ECM;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DROID_CONSTRUCT:
|
2007-05-29 19:06:46 -07:00
|
|
|
case DROID_CYBORG_CONSTRUCT:
|
|
|
|
if (intDemolishSelectMode())
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
selectionClass = SC_DROID_DEMOLISH; // demolish mode.
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
selectionClass = SC_DROID_CONSTRUCT; // ordinary mode.
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DROID_COMMAND:
|
|
|
|
selectionClass = SC_DROID_COMMAND;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DROID_REPAIR:
|
2007-05-29 19:06:46 -07:00
|
|
|
case DROID_CYBORG_REPAIR:
|
2007-06-28 10:47:08 -07:00
|
|
|
selectionClass = SC_DROID_REPAIR;
|
|
|
|
break;
|
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
default:
|
2007-06-14 13:59:04 -07:00
|
|
|
ASSERT(!"unknown droid type", "Weirdy droid type on what you've clicked on!!!");
|
2007-06-28 10:47:08 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(selectionClass);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Just returns true if the building's present body points aren't 100 percent */
|
|
|
|
BOOL buildingDamaged(STRUCTURE *psStructure)
|
|
|
|
{
|
|
|
|
//if( PERCENT(psStructure->body , psStructure->baseBodyPoints ) < 100)
|
|
|
|
if( PERCENT(psStructure->body , structureBody(psStructure)) < 100)
|
|
|
|
{
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Looks through the list of selected players droids to see if one is a repair droid*/
|
|
|
|
BOOL repairDroidSelected(UDWORD player)
|
|
|
|
{
|
|
|
|
DROID *psCurr;
|
|
|
|
|
|
|
|
for (psCurr = apsDroidLists[player]; psCurr != NULL; psCurr = psCurr->psNext)
|
|
|
|
{
|
2007-02-10 08:39:39 -08:00
|
|
|
//if (psCurr->selected && psCurr->droidType == DROID_REPAIR)
|
2007-05-29 19:06:46 -07:00
|
|
|
if (psCurr->selected && (
|
|
|
|
psCurr->droidType == DROID_REPAIR ||
|
|
|
|
psCurr->droidType == DROID_CYBORG_REPAIR))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//didn't find one...
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Looks through the list of selected players droids to see if one is a constructor droid*/
|
|
|
|
DROID *constructorDroidSelected(UDWORD player)
|
|
|
|
{
|
|
|
|
DROID *psCurr;
|
|
|
|
|
|
|
|
for (psCurr = apsDroidLists[player]; psCurr != NULL; psCurr = psCurr->psNext)
|
|
|
|
{
|
2007-02-10 08:39:39 -08:00
|
|
|
//if (psCurr->selected && psCurr->droidType == DROID_CONSTRUCT)
|
2007-05-29 19:06:46 -07:00
|
|
|
if (psCurr->selected && (
|
|
|
|
psCurr->droidType == DROID_CONSTRUCT ||
|
|
|
|
psCurr->droidType == DROID_CYBORG_CONSTRUCT))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return psCurr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//didn't find one...
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Looks through the list of selected players droids to see if one is a VTOL droid*/
|
|
|
|
BOOL vtolDroidSelected(UDWORD player)
|
|
|
|
{
|
|
|
|
DROID *psCurr;
|
|
|
|
|
|
|
|
for (psCurr = apsDroidLists[player]; psCurr != NULL; psCurr = psCurr->psNext)
|
|
|
|
{
|
2007-02-10 08:39:39 -08:00
|
|
|
if (psCurr->selected && vtolDroid(psCurr))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
// horrible hack to note one of the selected vtols
|
|
|
|
psSelectedVtol = psCurr;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//didn't find one...
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Looks through the list of selected players droids to see if any is selected*/
|
|
|
|
BOOL anyDroidSelected(UDWORD player)
|
|
|
|
{
|
|
|
|
DROID *psCurr;
|
|
|
|
|
|
|
|
for (psCurr = apsDroidLists[player]; psCurr != NULL; psCurr = psCurr->psNext)
|
|
|
|
{
|
|
|
|
if (psCurr->selected)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//didn't find one...
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Looks through the list of selected players droids to see if one is a cyborg droid*/
|
|
|
|
BOOL cyborgDroidSelected(UDWORD player)
|
|
|
|
{
|
|
|
|
DROID *psCurr;
|
|
|
|
|
|
|
|
for (psCurr = apsDroidLists[player]; psCurr != NULL; psCurr = psCurr->psNext)
|
|
|
|
{
|
2007-02-10 08:39:39 -08:00
|
|
|
if (psCurr->selected && cyborgDroid(psCurr))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//didn't find one...
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Clear the selection flag for a player */
|
|
|
|
void clearSel(void)
|
|
|
|
{
|
|
|
|
DROID *psCurrDroid;
|
|
|
|
STRUCTURE *psStruct;
|
|
|
|
//FEATURE *psFeat;
|
|
|
|
FLAG_POSITION *psFlagPos;
|
|
|
|
|
|
|
|
for(psCurrDroid = apsDroidLists[selectedPlayer]; psCurrDroid;
|
|
|
|
psCurrDroid = psCurrDroid->psNext)
|
|
|
|
{
|
|
|
|
psCurrDroid->selected = FALSE;
|
|
|
|
}
|
|
|
|
for(psStruct = apsStructLists[selectedPlayer]; psStruct;
|
|
|
|
psStruct = psStruct->psNext)
|
|
|
|
{
|
|
|
|
psStruct->selected = FALSE;
|
|
|
|
}
|
|
|
|
//can a feature ever be selected?
|
|
|
|
/*for(psFeat = apsFeatureLists[0]; psFeat;
|
|
|
|
psFeat = psFeat->psNext)
|
|
|
|
{
|
|
|
|
psFeat->selected = FALSE;
|
|
|
|
}*/
|
|
|
|
//clear the Deliv Point if one
|
|
|
|
for (psFlagPos = apsFlagPosLists[selectedPlayer]; psFlagPos;
|
|
|
|
psFlagPos = psFlagPos->psNext)
|
|
|
|
{
|
|
|
|
psFlagPos->selected = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
setSelectedGroup(UBYTE_MAX);
|
|
|
|
setSelectedCommander(UBYTE_MAX);
|
|
|
|
intRefreshScreen();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Clear the selection and stop driver mode.
|
|
|
|
//
|
|
|
|
void clearSelection(void)
|
|
|
|
{
|
|
|
|
StopDriverMode(); // Cancel driver mode ( if active ).
|
|
|
|
clearSel();
|
|
|
|
}
|
|
|
|
|
|
|
|
//access function for bSensorAssigned variable
|
|
|
|
void setSensorAssigned(void)
|
|
|
|
{
|
|
|
|
bSensorAssigned = TRUE;
|
|
|
|
}
|