2010-03-12 07:42:55 +00:00
// ==============================================================
// ==============================================================
// This file is part of Glest (www.glest.org)
//
2010-03-27 03:09:11 +00:00
// Copyright (C) 2001-2008 Marti<74> o Figueroa
2010-03-12 07:42:55 +00:00
//
// You can redistribute this code 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
// ==============================================================
# include "gui.h"
# include <cassert>
# include <algorithm>
# include "world.h"
# include "renderer.h"
# include "game.h"
# include "upgrade.h"
# include "unit.h"
# include "metrics.h"
# include "display.h"
# include "platform_util.h"
# include "sound_renderer.h"
# include "util.h"
# include "faction.h"
# include "leak_dumper.h"
2010-03-18 21:26:40 +00:00
# include "network_types.h"
# include "network_manager.h"
2010-03-12 07:42:55 +00:00
using namespace Shared : : Graphics ;
using namespace Shared : : Util ;
namespace Glest { namespace Game {
// =====================================================
// class Mouse3d
// =====================================================
const float Mouse3d : : fadeSpeed = 1.f / 50.f ;
2010-04-18 19:28:52 +00:00
static const int queueCommandKey = vkShift ;
2010-03-12 07:42:55 +00:00
Mouse3d : : Mouse3d ( ) {
enabled = false ;
rot = 0 ;
fade = 0.f ;
}
void Mouse3d : : enable ( ) {
enabled = true ;
fade = 0.f ;
}
void Mouse3d : : update ( ) {
if ( enabled ) {
rot = ( rot + 3 ) % 360 ;
fade + = fadeSpeed ;
if ( fade > 1.f ) fade = 1.f ;
}
}
// ===============================
// class SelectionQuad
// ===============================
SelectionQuad : : SelectionQuad ( ) {
enabled = false ;
posDown = Vec2i ( 0 ) ;
posUp = Vec2i ( 0 ) ;
}
void SelectionQuad : : setPosDown ( const Vec2i & posDown ) {
enabled = true ;
this - > posDown = posDown ;
this - > posUp = posDown ;
}
void SelectionQuad : : setPosUp ( const Vec2i & posUp ) {
this - > posUp = posUp ;
}
void SelectionQuad : : disable ( ) {
enabled = false ;
}
// =====================================================
// class Gui
// =====================================================
//constructor
Gui : : Gui ( ) {
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s] START \n " , __FILE__ , __FUNCTION__ ) ;
2010-03-12 07:42:55 +00:00
posObjWorld = Vec2i ( 54 , 14 ) ;
validPosObjWorld = false ;
activeCommandType = NULL ;
activeCommandClass = ccStop ;
selectingBuilding = false ;
2010-03-25 12:15:10 +00:00
selectedBuildingFacing = CardinalDir : : NORTH ;
2010-03-12 07:42:55 +00:00
selectingPos = false ;
selectingMeetingPoint = false ;
activePos = invalidPos ;
2010-09-10 12:15:21 +00:00
lastQuadCalcFrame = 0 ;
selectionCalculationFrameSkip = 10 ;
minQuadSize = 20 ;
2011-02-13 21:04:30 +00:00
selectedResourceObject = NULL ;
2010-03-12 07:42:55 +00:00
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s] END \n " , __FILE__ , __FUNCTION__ ) ;
2010-03-12 07:42:55 +00:00
}
void Gui : : init ( Game * game ) {
this - > commander = game - > getCommander ( ) ;
this - > gameCamera = game - > getGameCamera ( ) ;
this - > console = game - > getConsole ( ) ;
this - > world = game - > getWorld ( ) ;
2010-09-10 12:15:21 +00:00
this - > game = game ;
2010-03-12 07:42:55 +00:00
selection . init ( this , world - > getThisFactionIndex ( ) ) ;
}
void Gui : : end ( ) {
selection . clear ( ) ;
}
// ==================== get ====================
const UnitType * Gui : : getBuilding ( ) const {
assert ( selectingBuilding ) ;
return choosenBuildingType ;
}
// ==================== is ====================
bool Gui : : isPlacingBuilding ( ) const {
return isSelectingPos ( ) & & activeCommandType ! = NULL & & activeCommandType - > getClass ( ) = = ccBuild ;
}
// ==================== set ====================
void Gui : : invalidatePosObjWorld ( ) {
validPosObjWorld = false ;
}
// ==================== reset state ====================
void Gui : : resetState ( ) {
selectingBuilding = false ;
2010-03-25 12:15:10 +00:00
selectedBuildingFacing = CardinalDir : : NORTH ;
2010-03-12 07:42:55 +00:00
selectingPos = false ;
selectingMeetingPoint = false ;
activePos = invalidPos ;
activeCommandClass = ccStop ;
activeCommandType = NULL ;
}
// ==================== events ====================
void Gui : : update ( ) {
2011-01-08 21:53:05 +00:00
2010-09-10 12:15:21 +00:00
if ( selectionQuad . isEnabled ( ) & & selectionQuad . getPosUp ( ) . dist ( selectionQuad . getPosDown ( ) ) > minQuadSize ) {
computeSelected ( false , false ) ;
}
2010-03-12 07:42:55 +00:00
mouse3d . update ( ) ;
}
void Gui : : tick ( ) {
computeDisplay ( ) ;
}
//in display coords
2011-03-28 03:54:23 +00:00
bool Gui : : mouseValid ( int x , int y ) {
2010-03-12 07:42:55 +00:00
return computePosDisplay ( x , y ) ! = invalidPos ;
}
2011-03-28 03:54:23 +00:00
void Gui : : mouseDownLeftDisplay ( int x , int y ) {
if ( ! selectingPos & & ! selectingMeetingPoint ) {
2010-03-12 07:42:55 +00:00
int posDisplay = computePosDisplay ( x , y ) ;
2011-03-28 03:54:23 +00:00
if ( posDisplay ! = invalidPos ) {
if ( selection . isCommandable ( ) ) {
if ( selectingBuilding ) {
2010-03-12 07:42:55 +00:00
mouseDownDisplayUnitBuild ( posDisplay ) ;
}
2011-03-28 03:54:23 +00:00
else {
2010-03-12 07:42:55 +00:00
mouseDownDisplayUnitSkills ( posDisplay ) ;
}
}
2011-03-28 03:54:23 +00:00
else {
2010-03-12 07:42:55 +00:00
resetState ( ) ;
}
}
computeDisplay ( ) ;
}
}
2011-03-28 03:54:23 +00:00
void Gui : : mouseMoveDisplay ( int x , int y ) {
2010-03-12 07:42:55 +00:00
computeInfoString ( computePosDisplay ( x , y ) ) ;
}
2011-03-28 03:54:23 +00:00
void Gui : : mouseDownLeftGraphics ( int x , int y , bool prepared ) {
if ( selectingPos ) {
2010-03-12 07:42:55 +00:00
//give standard orders
2010-12-18 17:18:36 +00:00
giveTwoClickOrders ( x , y , prepared ) ;
2010-03-12 07:42:55 +00:00
resetState ( ) ;
}
//set meeting point
2011-03-28 03:54:23 +00:00
else if ( selectingMeetingPoint ) {
if ( selection . isCommandable ( ) ) {
2010-03-12 07:42:55 +00:00
Vec2i targetPos ;
2011-03-28 03:54:23 +00:00
if ( Renderer : : getInstance ( ) . computePosition ( Vec2i ( x , y ) , targetPos ) ) {
2010-03-12 07:42:55 +00:00
commander - > trySetMeetingPoint ( selection . getFrontUnit ( ) , targetPos ) ;
}
}
resetState ( ) ;
}
2011-03-28 03:54:23 +00:00
else {
2010-03-12 07:42:55 +00:00
selectionQuad . setPosDown ( Vec2i ( x , y ) ) ;
2010-09-10 12:15:21 +00:00
computeSelected ( false , false ) ;
2010-03-12 07:42:55 +00:00
}
computeDisplay ( ) ;
}
2011-03-28 03:54:23 +00:00
void Gui : : mouseDownRightGraphics ( int x , int y , bool prepared ) {
if ( selectingPos | | selectingMeetingPoint ) {
2010-03-12 07:42:55 +00:00
resetState ( ) ;
}
2011-03-28 03:54:23 +00:00
else if ( selection . isCommandable ( ) ) {
if ( prepared ) {
2010-12-18 17:18:36 +00:00
givePreparedDefaultOrders ( x , y ) ;
}
2011-03-28 03:54:23 +00:00
else {
2010-12-18 17:18:36 +00:00
giveDefaultOrders ( x , y ) ;
}
2010-03-12 07:42:55 +00:00
}
computeDisplay ( ) ;
}
2011-03-28 03:54:23 +00:00
void Gui : : mouseUpLeftGraphics ( int x , int y ) {
if ( ! selectingPos & & ! selectingMeetingPoint ) {
2010-03-12 07:42:55 +00:00
if ( selectionQuad . isEnabled ( ) ) {
selectionQuad . setPosUp ( Vec2i ( x , y ) ) ;
2010-09-10 12:15:21 +00:00
if ( selectionQuad . getPosUp ( ) . dist ( selectionQuad . getPosDown ( ) ) > minQuadSize )
{
computeSelected ( false , true ) ;
}
2011-01-09 20:52:00 +00:00
if ( selection . isCommandable ( ) & & random . randRange ( 0 , 1 ) = = 0 ) {
2010-03-12 07:42:55 +00:00
SoundRenderer : : getInstance ( ) . playFx (
selection . getFrontUnit ( ) - > getType ( ) - > getSelectionSound ( ) ,
selection . getFrontUnit ( ) - > getCurrVector ( ) ,
gameCamera - > getPos ( ) ) ;
}
selectionQuad . disable ( ) ;
}
}
}
2011-03-28 03:54:23 +00:00
void Gui : : mouseMoveGraphics ( int x , int y ) {
2010-03-12 07:42:55 +00:00
//compute selection
if ( selectionQuad . isEnabled ( ) ) {
selectionQuad . setPosUp ( Vec2i ( x , y ) ) ;
2010-09-10 12:15:21 +00:00
computeSelected ( false , false ) ;
2010-03-12 07:42:55 +00:00
}
//compute position for building
if ( isPlacingBuilding ( ) ) {
validPosObjWorld = Renderer : : getInstance ( ) . computePosition ( Vec2i ( x , y ) , posObjWorld ) ;
}
display . setInfoText ( " " ) ;
}
void Gui : : mouseDoubleClickLeftGraphics ( int x , int y ) {
if ( ! selectingPos & & ! selectingMeetingPoint ) {
selectionQuad . setPosDown ( Vec2i ( x , y ) ) ;
2010-09-10 12:15:21 +00:00
computeSelected ( true , true ) ;
2010-03-12 07:42:55 +00:00
computeDisplay ( ) ;
}
}
2011-03-28 03:54:23 +00:00
void Gui : : groupKey ( int groupIndex ) {
2010-03-12 07:42:55 +00:00
if ( isKeyDown ( vkControl ) ) {
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] groupIndex = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , groupIndex ) ;
2010-04-06 14:25:00 +00:00
2010-03-12 07:42:55 +00:00
selection . assignGroup ( groupIndex ) ;
}
else {
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] groupIndex = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , groupIndex ) ;
2010-04-06 14:25:00 +00:00
2010-03-12 07:42:55 +00:00
selection . recallGroup ( groupIndex ) ;
}
}
2010-06-12 18:27:39 +00:00
void Gui : : hotKey ( char key ) {
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s] key = [%c][%d] \n " , __FILE__ , __FUNCTION__ , key , key ) ;
2010-03-12 07:42:55 +00:00
2010-06-12 18:27:39 +00:00
Config & configKeys = Config : : getInstance ( std : : pair < ConfigType , ConfigType > ( cfgMainKeys , cfgUserKeys ) ) ;
if ( key = = configKeys . getCharKey ( " HotKeyCenterCameraOnSelection " ) ) {
2010-03-12 07:42:55 +00:00
centerCameraOnSelection ( ) ;
}
2010-06-12 18:27:39 +00:00
else if ( key = = configKeys . getCharKey ( " HotKeySelectIdleHarvesterUnit " ) ) {
2010-03-12 07:42:55 +00:00
selectInterestingUnit ( iutIdleHarvester ) ;
}
2010-06-12 18:27:39 +00:00
else if ( key = = configKeys . getCharKey ( " HotKeySelectBuiltBuilding " ) ) {
2010-03-12 07:42:55 +00:00
selectInterestingUnit ( iutBuiltBuilding ) ;
}
2010-06-12 18:27:39 +00:00
else if ( key = = configKeys . getCharKey ( " HotKeyDumpWorldToLog " ) ) {
2010-05-18 03:53:57 +00:00
std : : string worldLog = world - > DumpWorldToLog ( ) ;
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] worldLog dumped to [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , worldLog . c_str ( ) ) ;
2010-05-18 03:53:57 +00:00
}
2010-06-12 18:27:39 +00:00
else if ( key = = configKeys . getCharKey ( " HotKeyRotateUnitDuringPlacement " ) ) {
2010-03-18 21:26:40 +00:00
// Here the user triggers a unit rotation while placing a unit
2010-06-17 00:08:27 +00:00
if ( isPlacingBuilding ( ) ) {
2010-03-27 03:09:11 +00:00
if ( getBuilding ( ) - > getRotationAllowed ( ) ) {
+ + selectedBuildingFacing ;
}
2010-03-12 07:42:55 +00:00
}
}
2010-06-12 18:27:39 +00:00
else if ( key = = configKeys . getCharKey ( " HotKeySelectDamagedUnit " ) ) {
2010-03-12 07:42:55 +00:00
selectInterestingUnit ( iutDamaged ) ;
}
2010-06-12 18:27:39 +00:00
else if ( key = = configKeys . getCharKey ( " HotKeySelectStoreUnit " ) ) {
2010-03-12 07:42:55 +00:00
selectInterestingUnit ( iutStore ) ;
}
2010-06-12 18:27:39 +00:00
else if ( key = = configKeys . getCharKey ( " HotKeySelectedUnitsAttack " ) ) {
2010-03-12 07:42:55 +00:00
clickCommonCommand ( ccAttack ) ;
}
2010-06-12 18:27:39 +00:00
else if ( key = = configKeys . getCharKey ( " HotKeySelectedUnitsStop " ) ) {
2010-03-12 07:42:55 +00:00
clickCommonCommand ( ccStop ) ;
}
}
2010-04-08 20:19:25 +00:00
void Gui : : switchToNextDisplayColor ( ) {
display . switchColor ( ) ;
}
2010-03-12 07:42:55 +00:00
void Gui : : onSelectionChanged ( ) {
resetState ( ) ;
computeDisplay ( ) ;
}
// ================= PRIVATE =================
void Gui : : giveOneClickOrders ( ) {
CommandResult result ;
2010-04-18 19:28:52 +00:00
bool queueKeyDown = isKeyDown ( queueCommandKey ) ;
2010-03-12 07:42:55 +00:00
if ( selection . isUniform ( ) ) {
2010-04-18 19:28:52 +00:00
result = commander - > tryGiveCommand ( & selection , activeCommandType , Vec2i ( 0 ) , ( Unit * ) NULL , queueKeyDown ) ;
2010-03-12 07:42:55 +00:00
}
else {
2010-04-18 19:28:52 +00:00
result = commander - > tryGiveCommand ( & selection , activeCommandClass , Vec2i ( 0 ) , ( Unit * ) NULL , queueKeyDown ) ;
2010-03-12 07:42:55 +00:00
}
addOrdersResultToConsole ( activeCommandClass , result ) ;
activeCommandType = NULL ;
activeCommandClass = ccStop ;
}
2011-01-08 21:53:05 +00:00
void Gui : : giveDefaultOrders ( int x , int y ) {
2010-03-12 07:42:55 +00:00
//compute target
const Unit * targetUnit = NULL ;
Vec2i targetPos ;
2011-01-08 21:53:05 +00:00
if ( computeTarget ( Vec2i ( x , y ) , targetPos , targetUnit ) = = false ) {
2010-03-12 07:42:55 +00:00
console - > addStdMessage ( " InvalidPosition " ) ;
return ;
}
2010-12-20 03:12:00 +00:00
giveDefaultOrders ( targetPos . x , targetPos . y , targetUnit , true ) ;
2010-12-18 17:18:36 +00:00
}
void Gui : : givePreparedDefaultOrders ( int x , int y ) {
2010-12-20 03:12:00 +00:00
giveDefaultOrders ( x , y , NULL , false ) ;
2010-12-18 17:18:36 +00:00
}
2010-03-12 07:42:55 +00:00
2011-01-08 21:53:05 +00:00
void Gui : : giveDefaultOrders ( int x , int y , const Unit * targetUnit , bool paintMouse3d ) {
2010-04-18 19:28:52 +00:00
bool queueKeyDown = isKeyDown ( queueCommandKey ) ;
2010-12-18 17:18:36 +00:00
Vec2i targetPos = Vec2i ( x , y ) ;
2010-03-12 07:42:55 +00:00
//give order
2010-04-18 19:28:52 +00:00
CommandResult result = commander - > tryGiveCommand ( & selection , targetPos , targetUnit , queueKeyDown ) ;
2010-03-12 07:42:55 +00:00
//graphical result
addOrdersResultToConsole ( activeCommandClass , result ) ;
2011-01-08 21:53:05 +00:00
if ( result = = crSuccess | | result = = crSomeFailed ) {
2010-12-20 03:12:00 +00:00
if ( paintMouse3d )
mouse3d . enable ( ) ;
2010-03-12 07:42:55 +00:00
if ( random . randRange ( 0 , 1 ) = = 0 ) {
SoundRenderer : : getInstance ( ) . playFx (
selection . getFrontUnit ( ) - > getType ( ) - > getCommandSound ( ) ,
selection . getFrontUnit ( ) - > getCurrVector ( ) ,
gameCamera - > getPos ( ) ) ;
}
}
//reset
resetState ( ) ;
}
2011-01-08 21:53:05 +00:00
void Gui : : giveTwoClickOrders ( int x , int y , bool prepared ) {
2010-03-12 07:42:55 +00:00
CommandResult result ;
//compute target
const Unit * targetUnit = NULL ;
Vec2i targetPos ;
2010-12-18 17:18:36 +00:00
if ( prepared ) {
targetPos = Vec2i ( x , y ) ;
}
2011-01-08 21:53:05 +00:00
else {
if ( computeTarget ( Vec2i ( x , y ) , targetPos , targetUnit ) = = false ) {
2010-12-18 17:18:36 +00:00
console - > addStdMessage ( " InvalidPosition " ) ;
return ;
}
2010-03-12 07:42:55 +00:00
}
2010-04-18 19:28:52 +00:00
bool queueKeyDown = isKeyDown ( queueCommandKey ) ;
2010-03-12 07:42:55 +00:00
//give orders to the units of this faction
2011-01-08 21:53:05 +00:00
if ( selectingBuilding = = false ) {
if ( selection . isUniform ( ) ) {
2010-08-28 01:46:26 +00:00
result = commander - > tryGiveCommand ( & selection , activeCommandType ,
targetPos , targetUnit , queueKeyDown ) ;
2010-03-12 07:42:55 +00:00
}
2011-01-08 21:53:05 +00:00
else {
2010-08-28 01:46:26 +00:00
result = commander - > tryGiveCommand ( & selection , activeCommandClass ,
targetPos , targetUnit , queueKeyDown ) ;
2010-04-18 07:35:48 +00:00
}
2010-03-12 07:42:55 +00:00
}
2011-01-08 21:53:05 +00:00
else {
2010-03-12 07:42:55 +00:00
//selecting building
2010-08-28 01:46:26 +00:00
result = commander - > tryGiveCommand ( & selection ,
activeCommandType , posObjWorld , choosenBuildingType ,
selectedBuildingFacing , queueKeyDown ) ;
2010-03-12 07:42:55 +00:00
}
//graphical result
addOrdersResultToConsole ( activeCommandClass , result ) ;
2011-01-08 21:53:05 +00:00
if ( result = = crSuccess | | result = = crSomeFailed ) {
if ( prepared = = false ) {
2010-12-20 03:12:00 +00:00
mouse3d . enable ( ) ;
}
2010-03-12 07:42:55 +00:00
2011-01-08 21:53:05 +00:00
if ( random . randRange ( 0 , 1 ) = = 0 ) {
2010-03-12 07:42:55 +00:00
SoundRenderer : : getInstance ( ) . playFx (
selection . getFrontUnit ( ) - > getType ( ) - > getCommandSound ( ) ,
selection . getFrontUnit ( ) - > getCurrVector ( ) ,
gameCamera - > getPos ( ) ) ;
}
}
}
2011-01-08 21:53:05 +00:00
void Gui : : centerCameraOnSelection ( ) {
if ( selection . isEmpty ( ) = = false ) {
2010-03-12 07:42:55 +00:00
Vec3f refPos = selection . getRefPos ( ) ;
gameCamera - > centerXZ ( refPos . x , refPos . z ) ;
}
}
2011-01-08 21:53:05 +00:00
void Gui : : selectInterestingUnit ( InterestingUnitType iut ) {
2010-03-12 07:42:55 +00:00
const Faction * thisFaction = world - > getThisFaction ( ) ;
const Unit * previousUnit = NULL ;
bool previousFound = true ;
//start at the next harvester
if ( selection . getCount ( ) = = 1 ) {
const Unit * refUnit = selection . getFrontUnit ( ) ;
if ( refUnit - > isInteresting ( iut ) ) {
previousUnit = refUnit ;
previousFound = false ;
}
}
//clear selection
selection . clear ( ) ;
//search
for ( int i = 0 ; i < thisFaction - > getUnitCount ( ) ; + + i ) {
Unit * unit = thisFaction - > getUnit ( i ) ;
if ( previousFound ) {
if ( unit - > isInteresting ( iut ) ) {
selection . select ( unit ) ;
break ;
}
}
else {
if ( unit = = previousUnit ) {
previousFound = true ;
}
}
}
//search again if we have a previous
if ( selection . isEmpty ( ) & & previousUnit ! = NULL & & previousFound = = true ) {
for ( int i = 0 ; i < thisFaction - > getUnitCount ( ) ; + + i ) {
Unit * unit = thisFaction - > getUnit ( i ) ;
if ( unit - > isInteresting ( iut ) ) {
selection . select ( unit ) ;
break ;
}
}
}
}
void Gui : : clickCommonCommand ( CommandClass commandClass ) {
for ( int i = 0 ; i < Display : : downCellCount ; + + i ) {
const CommandType * ct = display . getCommandType ( i ) ;
if ( ( ct ! = NULL & & ct - > getClass ( ) = = commandClass ) | | display . getCommandClass ( i ) = = commandClass ) {
mouseDownDisplayUnitSkills ( i ) ;
break ;
}
}
}
2011-01-10 06:43:47 +00:00
void Gui : : mouseDownDisplayUnitSkills ( int posDisplay ) {
if ( ! selection . isEmpty ( ) ) {
if ( posDisplay ! = cancelPos ) {
if ( posDisplay ! = meetingPointPos ) {
2010-03-12 07:42:55 +00:00
const Unit * unit = selection . getFrontUnit ( ) ;
//uniform selection
2011-01-10 06:43:47 +00:00
if ( selection . isUniform ( ) ) {
const CommandType * ct = display . getCommandType ( posDisplay ) ;
if ( ct ! = NULL & & unit - > getFaction ( ) - > reqsOk ( ct ) ) {
2010-03-12 07:42:55 +00:00
activeCommandType = display . getCommandType ( posDisplay ) ;
activeCommandClass = activeCommandType - > getClass ( ) ;
}
2011-01-10 06:43:47 +00:00
else {
2010-03-12 07:42:55 +00:00
posDisplay = invalidPos ;
activeCommandType = NULL ;
activeCommandClass = ccStop ;
return ;
}
}
//non uniform selection
2011-01-10 06:43:47 +00:00
else {
2010-03-12 07:42:55 +00:00
activeCommandType = NULL ;
activeCommandClass = display . getCommandClass ( posDisplay ) ;
}
//give orders depending on command type
if ( ! selection . isEmpty ( ) ) {
const CommandType * ct = selection . getUnit ( 0 ) - > getType ( ) - > getFirstCtOfClass ( activeCommandClass ) ;
if ( activeCommandType ! = NULL & & activeCommandType - > getClass ( ) = = ccBuild ) {
assert ( selection . isUniform ( ) ) ;
selectingBuilding = true ;
}
else if ( ct - > getClicks ( ) = = cOne ) {
invalidatePosObjWorld ( ) ;
giveOneClickOrders ( ) ;
}
else {
selectingPos = true ;
activePos = posDisplay ;
}
}
}
else {
activePos = posDisplay ;
selectingMeetingPoint = true ;
}
}
else {
commander - > tryCancelCommand ( & selection ) ;
}
}
}
void Gui : : mouseDownDisplayUnitBuild ( int posDisplay ) {
int factionIndex = world - > getThisFactionIndex ( ) ;
if ( posDisplay = = cancelPos ) {
resetState ( ) ;
}
else {
if ( activeCommandType ! = NULL & & activeCommandType - > getClass ( ) = = ccBuild ) {
const BuildCommandType * bct = static_cast < const BuildCommandType * > ( activeCommandType ) ;
const UnitType * ut = bct - > getBuilding ( posDisplay ) ;
if ( world - > getFaction ( factionIndex ) - > reqsOk ( ut ) ) {
choosenBuildingType = ut ;
assert ( choosenBuildingType ! = NULL ) ;
2010-03-25 12:15:10 +00:00
selectingPos = true ;
selectedBuildingFacing = CardinalDir : : NORTH ;
2010-03-12 07:42:55 +00:00
activePos = posDisplay ;
}
}
}
}
void Gui : : computeInfoString ( int posDisplay ) {
Lang & lang = Lang : : getInstance ( ) ;
display . setInfoText ( " " ) ;
2011-01-09 20:52:00 +00:00
if ( posDisplay ! = invalidPos & & selection . isCommandable ( ) ) {
2010-03-12 07:42:55 +00:00
if ( ! selectingBuilding ) {
if ( posDisplay = = cancelPos ) {
display . setInfoText ( lang . get ( " Cancel " ) ) ;
}
else if ( posDisplay = = meetingPointPos ) {
display . setInfoText ( lang . get ( " MeetingPoint " ) ) ;
}
else {
//uniform selection
if ( selection . isUniform ( ) ) {
const Unit * unit = selection . getFrontUnit ( ) ;
const CommandType * ct = display . getCommandType ( posDisplay ) ;
if ( ct ! = NULL ) {
if ( unit - > getFaction ( ) - > reqsOk ( ct ) ) {
display . setInfoText ( ct - > getDesc ( unit - > getTotalUpgrade ( ) ) ) ;
}
else {
if ( ct - > getClass ( ) = = ccUpgrade ) {
2011-01-23 23:57:46 +00:00
string text = " " ;
2010-03-12 07:42:55 +00:00
const UpgradeCommandType * uct = static_cast < const UpgradeCommandType * > ( ct ) ;
if ( unit - > getFaction ( ) - > getUpgradeManager ( ) - > isUpgrading ( uct - > getProducedUpgrade ( ) ) ) {
2011-01-23 23:57:46 +00:00
text = lang . get ( " Upgrading " ) + " \n \n " ;
2010-03-12 07:42:55 +00:00
}
else if ( unit - > getFaction ( ) - > getUpgradeManager ( ) - > isUpgraded ( uct - > getProducedUpgrade ( ) ) ) {
2011-01-23 23:57:46 +00:00
text = lang . get ( " AlreadyUpgraded " ) + " \n \n " ;
2010-03-12 07:42:55 +00:00
}
2011-01-23 23:57:46 +00:00
display . setInfoText ( text + ct - > getReqDesc ( ) ) ;
2010-03-12 07:42:55 +00:00
}
else {
display . setInfoText ( ct - > getReqDesc ( ) ) ;
}
}
}
}
//non uniform selection
else {
const UnitType * ut = selection . getFrontUnit ( ) - > getType ( ) ;
CommandClass cc = display . getCommandClass ( posDisplay ) ;
if ( cc ! = ccNull ) {
display . setInfoText ( lang . get ( " CommonCommand " ) + " : " + ut - > getFirstCtOfClass ( cc ) - > toString ( ) ) ;
}
}
}
}
else {
if ( posDisplay = = cancelPos ) {
display . setInfoText ( lang . get ( " Return " ) ) ;
}
else {
if ( activeCommandType ! = NULL & & activeCommandType - > getClass ( ) = = ccBuild ) {
const BuildCommandType * bct = static_cast < const BuildCommandType * > ( activeCommandType ) ;
display . setInfoText ( bct - > getBuilding ( posDisplay ) - > getReqDesc ( ) ) ;
}
}
}
}
}
2011-02-13 21:04:30 +00:00
void Gui : : computeDisplay ( ) {
2010-10-28 18:31:12 +00:00
//printf("Start ===> computeDisplay()\n");
2011-02-13 21:04:30 +00:00
Lang & lang = Lang : : getInstance ( ) ;
2010-03-12 07:42:55 +00:00
//init
display . clear ( ) ;
2011-02-13 21:04:30 +00:00
// ================ PART 1 ================
2010-03-12 07:42:55 +00:00
2011-02-13 21:04:30 +00:00
if ( selection . isEmpty ( ) & & selectedResourceObject ! = NULL ) {
Resource * r = selectedResourceObject - > getResource ( ) ;
display . setTitle ( r - > getType ( ) - > getName ( ) ) ;
display . setText ( lang . get ( " Amount " ) + " : " + intToStr ( r - > getAmount ( ) ) + " / " + intToStr ( r - > getType ( ) - > getDefResPerPatch ( ) ) ) ;
//display.setProgressBar(r->);
display . setUpImage ( 0 , r - > getType ( ) - > getImage ( ) ) ;
2010-03-12 07:42:55 +00:00
}
2011-02-13 21:04:30 +00:00
else {
//title, text and progress bar
if ( selection . getCount ( ) = = 1 ) {
display . setTitle ( selection . getFrontUnit ( ) - > getFullName ( ) ) ;
display . setText ( selection . getFrontUnit ( ) - > getDesc ( ) ) ;
display . setProgressBar ( selection . getFrontUnit ( ) - > getProductionPercent ( ) ) ;
}
2010-03-12 07:42:55 +00:00
2011-02-13 21:04:30 +00:00
//portraits
for ( int i = 0 ; i < selection . getCount ( ) ; + + i ) {
display . setUpImage ( i , selection . getUnit ( i ) - > getType ( ) - > getImage ( ) ) ;
}
2010-03-12 07:42:55 +00:00
2011-02-13 21:04:30 +00:00
// ================ PART 2 ================
2010-03-12 07:42:55 +00:00
2011-02-13 21:04:30 +00:00
if ( selectingPos | | selectingMeetingPoint ) {
//printf("selectingPos || selectingMeetingPoint\n");
display . setDownSelectedPos ( activePos ) ;
}
2010-10-28 18:31:12 +00:00
2011-02-13 21:04:30 +00:00
if ( selection . isCommandable ( ) ) {
//printf("selection.isComandable()\n");
2010-03-12 07:42:55 +00:00
2011-02-13 21:04:30 +00:00
if ( selectingBuilding = = false ) {
2010-10-28 18:31:12 +00:00
2011-02-13 21:04:30 +00:00
//cancel button
const Unit * u = selection . getFrontUnit ( ) ;
const UnitType * ut = u - > getType ( ) ;
if ( selection . isCancelable ( ) ) {
//printf("selection.isCancelable() commandcount = %d\n",selection.getUnit(0)->getCommandSize());
if ( selection . getUnit ( 0 ) - > getCommandSize ( ) > 0 ) {
//printf("Current Command [%s]\n",selection.getUnit(0)->getCurrCommand()->toString().c_str());
}
2010-03-12 07:42:55 +00:00
2011-02-13 21:04:30 +00:00
display . setDownImage ( cancelPos , ut - > getCancelImage ( ) ) ;
display . setDownLighted ( cancelPos , true ) ;
}
2010-10-28 18:31:12 +00:00
2011-02-13 21:04:30 +00:00
//meeting point
if ( selection . isMeetable ( ) ) {
//printf("selection.isMeetable()\n");
2010-03-12 07:42:55 +00:00
2011-02-13 21:04:30 +00:00
display . setDownImage ( meetingPointPos , ut - > getMeetingPointImage ( ) ) ;
display . setDownLighted ( meetingPointPos , true ) ;
}
2010-10-28 18:31:12 +00:00
2011-02-13 21:04:30 +00:00
if ( selection . isUniform ( ) ) {
//printf("selection.isUniform()\n");
//uniform selection
if ( u - > isBuilt ( ) ) {
//printf("u->isBuilt()\n");
int morphPos = 8 ;
for ( int i = 0 ; i < ut - > getCommandTypeCount ( ) ; + + i ) {
int displayPos = i ;
const CommandType * ct = ut - > getCommandType ( i ) ;
if ( ct - > getClass ( ) = = ccMorph ) {
displayPos = morphPos + + ;
}
display . setDownImage ( displayPos , ct - > getImage ( ) ) ;
display . setCommandType ( displayPos , ct ) ;
display . setDownLighted ( displayPos , u - > getFaction ( ) - > reqsOk ( ct ) ) ;
2010-03-12 07:42:55 +00:00
}
}
}
2011-02-13 21:04:30 +00:00
else {
//printf("selection.isUniform() == FALSE\n");
//non uniform selection
int lastCommand = 0 ;
for ( int i = 0 ; i < ccCount ; + + i ) {
CommandClass cc = static_cast < CommandClass > ( i ) ;
if ( isSharedCommandClass ( cc ) & & cc ! = ccBuild ) {
display . setDownLighted ( lastCommand , true ) ;
display . setDownImage ( lastCommand , ut - > getFirstCtOfClass ( cc ) - > getImage ( ) ) ;
display . setCommandClass ( lastCommand , cc ) ;
lastCommand + + ;
}
2010-03-12 07:42:55 +00:00
}
}
}
2011-02-13 21:04:30 +00:00
else {
2010-03-12 07:42:55 +00:00
2011-02-13 21:04:30 +00:00
//selecting building
const Unit * unit = selection . getFrontUnit ( ) ;
if ( activeCommandType ! = NULL & & activeCommandType - > getClass ( ) = = ccBuild ) {
const BuildCommandType * bct = static_cast < const BuildCommandType * > ( activeCommandType ) ;
for ( int i = 0 ; i < bct - > getBuildingCount ( ) ; + + i ) {
display . setDownImage ( i , bct - > getBuilding ( i ) - > getImage ( ) ) ;
display . setDownLighted ( i , unit - > getFaction ( ) - > reqsOk ( bct - > getBuilding ( i ) ) ) ;
}
display . setDownImage ( cancelPos , selection . getFrontUnit ( ) - > getType ( ) - > getCancelImage ( ) ) ;
display . setDownLighted ( cancelPos , true ) ;
2010-03-12 07:42:55 +00:00
}
}
}
2011-02-13 21:04:30 +00:00
}
2010-03-12 07:42:55 +00:00
}
int Gui : : computePosDisplay ( int x , int y ) {
int posDisplay = display . computeDownIndex ( x , y ) ;
if ( posDisplay < 0 | | posDisplay > = Display : : downCellCount ) {
posDisplay = invalidPos ;
}
2011-01-09 20:52:00 +00:00
else if ( selection . isCommandable ( ) ) {
2010-03-12 07:42:55 +00:00
if ( posDisplay ! = cancelPos ) {
if ( posDisplay ! = meetingPointPos ) {
if ( ! selectingBuilding ) {
//standard selection
if ( display . getCommandClass ( posDisplay ) = = ccNull & & display . getCommandType ( posDisplay ) = = NULL ) {
posDisplay = invalidPos ;
}
}
else {
//building selection
if ( activeCommandType ! = NULL & & activeCommandType - > getClass ( ) = = ccBuild ) {
const BuildCommandType * bct = static_cast < const BuildCommandType * > ( activeCommandType ) ;
if ( posDisplay > = bct - > getBuildingCount ( ) ) {
posDisplay = invalidPos ;
}
}
}
}
else {
//check meeting point
if ( ! selection . isMeetable ( ) ) {
posDisplay = invalidPos ;
}
}
}
else {
//check cancel button
if ( ! selection . isCancelable ( ) ) {
posDisplay = invalidPos ;
}
}
}
else {
posDisplay = invalidPos ;
}
return posDisplay ;
}
void Gui : : addOrdersResultToConsole ( CommandClass cc , CommandResult result ) {
switch ( result ) {
case crSuccess :
break ;
case crFailReqs :
switch ( cc ) {
case ccBuild :
console - > addStdMessage ( " BuildingNoReqs " ) ;
break ;
case ccProduce :
console - > addStdMessage ( " UnitNoReqs " ) ;
break ;
case ccUpgrade :
console - > addStdMessage ( " UpgradeNoReqs " ) ;
break ;
default :
break ;
}
break ;
case crFailRes :
switch ( cc ) {
case ccBuild :
console - > addStdMessage ( " BuildingNoRes " ) ;
break ;
case ccProduce :
console - > addStdMessage ( " UnitNoRes " ) ;
break ;
case ccUpgrade :
console - > addStdMessage ( " UpgradeNoRes " ) ;
break ;
default :
break ;
}
break ;
case crFailUndefined :
console - > addStdMessage ( " InvalidOrder " ) ;
break ;
case crSomeFailed :
console - > addStdMessage ( " SomeOrdersFailed " ) ;
break ;
}
}
bool Gui : : isSharedCommandClass ( CommandClass commandClass ) {
for ( int i = 0 ; i < selection . getCount ( ) ; + + i ) {
const Unit * unit = selection . getUnit ( i ) ;
const CommandType * ct = unit - > getType ( ) - > getFirstCtOfClass ( commandClass ) ;
if ( ct = = NULL | | ! unit - > getFaction ( ) - > reqsOk ( ct ) )
return false ;
}
return true ;
}
2010-09-10 12:15:21 +00:00
void Gui : : computeSelected ( bool doubleClick , bool force ) {
2010-03-12 07:42:55 +00:00
Selection : : UnitContainer units ;
2010-09-10 12:15:21 +00:00
if ( force | | ( lastQuadCalcFrame + selectionCalculationFrameSkip < game - > getTotalRenderFps ( ) ) ) {
lastQuadCalcFrame = game - > getTotalRenderFps ( ) ;
2011-02-13 21:04:30 +00:00
selectedResourceObject = NULL ;
2010-09-10 12:15:21 +00:00
if ( selectionQuad . isEnabled ( ) & & selectionQuad . getPosUp ( ) . dist ( selectionQuad . getPosDown ( ) ) < minQuadSize ) {
2011-02-13 21:04:30 +00:00
Renderer : : getInstance ( ) . computeSelected ( units , selectedResourceObject , true , selectionQuad . getPosDown ( ) , selectionQuad . getPosDown ( ) ) ;
2010-09-10 12:15:21 +00:00
}
else {
2011-02-15 00:24:31 +00:00
Renderer : : getInstance ( ) . computeSelected ( units , selectedResourceObject , false , selectionQuad . getPosDown ( ) , selectionQuad . getPosUp ( ) ) ;
2010-09-10 12:15:21 +00:00
}
selectingBuilding = false ;
activeCommandType = NULL ;
2011-01-08 21:53:05 +00:00
2010-09-10 12:15:21 +00:00
//select all units of the same type if double click
2011-03-08 20:19:19 +00:00
if ( doubleClick & & units . size ( ) > 0 ) {
const Unit * refUnit = getRelevantObjectFromSelection ( & units ) ;
2010-09-10 12:15:21 +00:00
int factionIndex = refUnit - > getFactionIndex ( ) ;
for ( int i = 0 ; i < world - > getFaction ( factionIndex ) - > getUnitCount ( ) ; + + i ) {
Unit * unit = world - > getFaction ( factionIndex ) - > getUnit ( i ) ;
if ( unit - > getPos ( ) . dist ( refUnit - > getPos ( ) ) < doubleClickSelectionRadius & &
unit - > getType ( ) = = refUnit - > getType ( ) )
{
units . push_back ( unit ) ;
}
2010-03-12 07:42:55 +00:00
}
}
2011-01-08 21:53:05 +00:00
2010-09-10 12:15:21 +00:00
bool shiftDown = isKeyDown ( vkShift ) ;
bool controlDown = isKeyDown ( vkControl ) ;
2011-01-08 21:53:05 +00:00
2010-09-10 12:15:21 +00:00
if ( ! shiftDown & & ! controlDown ) {
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] about to call selection.clear() \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-09-10 12:15:21 +00:00
selection . clear ( ) ;
}
2011-01-08 21:53:05 +00:00
2010-09-10 12:15:21 +00:00
if ( ! controlDown ) {
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] about to call selection.select(units) \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-09-10 12:15:21 +00:00
selection . select ( units ) ;
2011-02-13 21:04:30 +00:00
if ( ! selection . isEmpty ( ) ) {
selectedResourceObject = NULL ;
}
2010-09-10 12:15:21 +00:00
}
else {
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] selection.unSelect(units) \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-09-10 12:15:21 +00:00
selection . unSelect ( units ) ;
}
2010-03-12 07:42:55 +00:00
}
}
2011-03-29 21:44:36 +00:00
bool Gui : : computeTarget ( const Vec2i & screenPos , Vec2i & targetPos , const Unit * & targetUnit ) {
2010-03-12 07:42:55 +00:00
Selection : : UnitContainer uc ;
Renderer & renderer = Renderer : : getInstance ( ) ;
2011-03-29 21:44:36 +00:00
const Object * obj = NULL ;
2011-02-13 14:35:17 +00:00
renderer . computeSelected ( uc , obj , true , screenPos , screenPos ) ;
2010-03-12 07:42:55 +00:00
validPosObjWorld = false ;
2011-03-29 21:44:36 +00:00
if ( uc . empty ( ) = = false ) {
targetUnit = getRelevantObjectFromSelection ( & uc ) ;
2011-03-08 20:19:19 +00:00
targetPos = targetUnit - > getPos ( ) ;
2010-03-12 07:42:55 +00:00
return true ;
}
2011-03-29 21:44:36 +00:00
else if ( obj ! = NULL ) {
2011-02-13 14:35:17 +00:00
targetUnit = NULL ;
2011-03-29 21:44:36 +00:00
// get real click pos
renderer . computePosition ( screenPos , targetPos ) ;
2011-03-29 23:19:19 +00:00
//validPosObjWorld= true;
2011-03-29 21:44:36 +00:00
//posObjWorld = targetPos;
int tx = targetPos . x ;
int ty = targetPos . y ;
int ox = obj - > getMapPos ( ) . x ;
int oy = obj - > getMapPos ( ) . y ;
Resource * clickedRecource = world - > getMap ( ) - > getSurfaceCell ( Map : : toSurfCoords ( obj - > getMapPos ( ) ) ) - > getResource ( ) ;
// lets see if the click had the same Resource
if ( clickedRecource = = world - > getMap ( ) - > getSurfaceCell ( Map : : toSurfCoords ( targetPos ) ) - > getResource ( ) ) {
// same ressource is meant, so use the user selected position
return true ;
}
else { // calculate a valid resource position which is as near as possible to the selected position
Vec2i testIt = Vec2i ( obj - > getMapPos ( ) ) ;
///////////////
// test both //
///////////////
if ( ty < oy ) {
testIt . y - - ;
}
else if ( ty > oy ) {
testIt . y + + ;
}
if ( tx < ox ) {
testIt . x - - ;
}
else if ( tx > ox ) {
testIt . x + + ;
}
if ( clickedRecource = = world - > getMap ( ) - > getSurfaceCell ( Map : : toSurfCoords ( testIt ) ) - > getResource ( ) ) {
// same ressource is meant, so use this position
targetPos = testIt ;
//posObjWorld= targetPos;
return true ;
}
else {
testIt = Vec2i ( obj - > getMapPos ( ) ) ;
}
/////////////////
// test y-only //
/////////////////
if ( ty < oy ) {
testIt . y - - ;
}
else if ( ty > oy ) {
testIt . y + + ;
}
if ( clickedRecource = = world - > getMap ( ) - > getSurfaceCell ( Map : : toSurfCoords ( testIt ) ) - > getResource ( ) ) {
// same ressource is meant, so use this position
targetPos = testIt ;
//posObjWorld= targetPos;
return true ;
}
else {
testIt = Vec2i ( obj - > getMapPos ( ) ) ;
}
/////////////////
// test x-only //
/////////////////
if ( tx < ox ) {
testIt . x - - ;
}
else if ( tx > ox ) {
testIt . x + + ;
}
if ( clickedRecource = = world - > getMap ( ) - > getSurfaceCell ( Map : : toSurfCoords ( testIt ) ) - > getResource ( ) ) {
// same ressource is meant, so use this position
targetPos = testIt ;
//posObjWorld= targetPos;
return true ;
}
}
// give up and use the object position;
2011-02-13 14:35:17 +00:00
targetPos = obj - > getMapPos ( ) ;
2011-03-29 21:44:36 +00:00
posObjWorld = targetPos ;
2011-02-13 14:35:17 +00:00
return true ;
2011-03-29 21:44:36 +00:00
2011-02-13 14:35:17 +00:00
}
2011-03-29 21:44:36 +00:00
else {
2010-03-12 07:42:55 +00:00
targetUnit = NULL ;
2011-03-29 21:44:36 +00:00
if ( renderer . computePosition ( screenPos , targetPos ) ) {
2010-03-12 07:42:55 +00:00
validPosObjWorld = true ;
posObjWorld = targetPos ;
return true ;
}
2011-03-29 21:44:36 +00:00
else {
2010-03-12 07:42:55 +00:00
return false ;
}
}
}
2011-03-08 20:19:19 +00:00
Unit * Gui : : getRelevantObjectFromSelection ( Selection : : UnitContainer * uc ) {
Unit * resultUnit = NULL ;
for ( int i = 0 ; i < uc - > size ( ) ; + + i ) {
resultUnit = uc - > at ( i ) ;
if ( resultUnit - > getType ( ) - > hasSkillClass ( scMove ) ) { // moving units are more relevant than non moving ones
break ;
}
}
return resultUnit ;
}
2011-02-15 04:34:19 +00:00
void Gui : : removingObjectEvent ( Object * o ) {
2011-02-13 21:04:30 +00:00
if ( getSelectedResourceObject ( ) = = o ) {
selectedResourceObject = NULL ;
}
}
2010-03-12 07:42:55 +00:00
} } //end namespace