2010-03-12 08:42:55 +01:00
|
|
|
|
// ==============================================================
|
|
|
|
|
// ==============================================================
|
|
|
|
|
// This file is part of Glest (www.glest.org)
|
|
|
|
|
//
|
2010-03-27 04:09:11 +01:00
|
|
|
|
// Copyright (C) 2001-2008 Marti<74>o Figueroa
|
2010-03-12 08:42:55 +01: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 22:26:40 +01:00
|
|
|
|
#include "network_types.h"
|
|
|
|
|
#include "network_manager.h"
|
|
|
|
|
|
|
|
|
|
|
2010-03-12 08:42:55 +01: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 21:28:52 +02:00
|
|
|
|
static const int queueCommandKey = vkShift;
|
|
|
|
|
|
2010-03-12 08:42:55 +01: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(){
|
2010-03-20 00:26:00 +01:00
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
posObjWorld= Vec2i(54, 14);
|
|
|
|
|
validPosObjWorld= false;
|
|
|
|
|
activeCommandType= NULL;
|
|
|
|
|
activeCommandClass= ccStop;
|
|
|
|
|
selectingBuilding= false;
|
2010-03-25 13:15:10 +01:00
|
|
|
|
selectedBuildingFacing = CardinalDir::NORTH;
|
2010-03-12 08:42:55 +01:00
|
|
|
|
selectingPos= false;
|
|
|
|
|
selectingMeetingPoint= false;
|
|
|
|
|
activePos= invalidPos;
|
2010-09-10 14:15:21 +02:00
|
|
|
|
lastQuadCalcFrame=0;
|
|
|
|
|
selectionCalculationFrameSkip=10;
|
|
|
|
|
minQuadSize=20;
|
2011-02-13 22:04:30 +01:00
|
|
|
|
selectedResourceObject=NULL;
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2010-03-20 00:26:00 +01:00
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01: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 14:15:21 +02:00
|
|
|
|
this->game=game;
|
2010-03-12 08:42:55 +01: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 13:15:10 +01:00
|
|
|
|
selectedBuildingFacing = CardinalDir::NORTH;
|
2010-03-12 08:42:55 +01:00
|
|
|
|
selectingPos= false;
|
|
|
|
|
selectingMeetingPoint= false;
|
|
|
|
|
activePos= invalidPos;
|
|
|
|
|
activeCommandClass= ccStop;
|
|
|
|
|
activeCommandType= NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ==================== events ====================
|
|
|
|
|
|
|
|
|
|
void Gui::update(){
|
2011-01-08 22:53:05 +01:00
|
|
|
|
|
2010-09-10 14:15:21 +02:00
|
|
|
|
if(selectionQuad.isEnabled() && selectionQuad.getPosUp().dist(selectionQuad.getPosDown())>minQuadSize){
|
|
|
|
|
computeSelected(false,false);
|
|
|
|
|
}
|
2010-03-12 08:42:55 +01:00
|
|
|
|
mouse3d.update();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Gui::tick(){
|
|
|
|
|
computeDisplay();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//in display coords
|
|
|
|
|
bool Gui::mouseValid(int x, int y){
|
|
|
|
|
return computePosDisplay(x, y) != invalidPos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Gui::mouseDownLeftDisplay(int x, int y){
|
|
|
|
|
if(!selectingPos && !selectingMeetingPoint){
|
|
|
|
|
int posDisplay= computePosDisplay(x, y);
|
|
|
|
|
if(posDisplay!= invalidPos){
|
2011-01-09 21:52:00 +01:00
|
|
|
|
if(selection.isCommandable()){
|
2010-03-12 08:42:55 +01:00
|
|
|
|
if(selectingBuilding){
|
|
|
|
|
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] selectingBuilding == true\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
mouseDownDisplayUnitBuild(posDisplay);
|
|
|
|
|
}
|
|
|
|
|
else{
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] selectingBuilding == false\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
mouseDownDisplayUnitSkills(posDisplay);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
resetState();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
computeDisplay();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Gui::mouseMoveDisplay(int x, int y){
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
computeInfoString(computePosDisplay(x, y));
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-18 18:18:36 +01:00
|
|
|
|
void Gui::mouseDownLeftGraphics(int x, int y, bool prepared){
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
if(selectingPos){
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] selectingPos == true\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
//give standard orders
|
2010-12-18 18:18:36 +01:00
|
|
|
|
giveTwoClickOrders(x, y, prepared);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
resetState();
|
|
|
|
|
}
|
|
|
|
|
//set meeting point
|
|
|
|
|
else if(selectingMeetingPoint){
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] selectingMeetingPoint == true\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2011-01-09 21:52:00 +01:00
|
|
|
|
if(selection.isCommandable()){
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] selection.isComandable() == true\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
Vec2i targetPos;
|
|
|
|
|
if(Renderer::getInstance().computePosition(Vec2i(x, y), targetPos)){
|
|
|
|
|
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] computePosition() == true\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
commander->trySetMeetingPoint(selection.getFrontUnit(), targetPos);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
resetState();
|
|
|
|
|
}
|
|
|
|
|
else{
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] selectionQuad()\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
selectionQuad.setPosDown(Vec2i(x, y));
|
2010-09-10 14:15:21 +02:00
|
|
|
|
computeSelected(false,false);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
computeDisplay();
|
|
|
|
|
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2010-12-18 18:18:36 +01:00
|
|
|
|
void Gui::mouseDownRightGraphics(int x, int y , bool prepared){
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
if(selectingPos || selectingMeetingPoint){
|
|
|
|
|
resetState();
|
|
|
|
|
}
|
2011-01-09 21:52:00 +01:00
|
|
|
|
else if(selection.isCommandable()){
|
2010-12-18 18:18:36 +01:00
|
|
|
|
if(prepared){
|
|
|
|
|
givePreparedDefaultOrders(x, y);
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
giveDefaultOrders(x, y);
|
|
|
|
|
}
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
computeDisplay();
|
|
|
|
|
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Gui::mouseUpLeftGraphics(int x, int y){
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
if(!selectingPos && !selectingMeetingPoint){
|
|
|
|
|
if(selectionQuad.isEnabled()){
|
|
|
|
|
selectionQuad.setPosUp(Vec2i(x, y));
|
2010-09-10 14:15:21 +02:00
|
|
|
|
if(selectionQuad.getPosUp().dist(selectionQuad.getPosDown())>minQuadSize)
|
|
|
|
|
{
|
|
|
|
|
computeSelected(false,true);
|
|
|
|
|
}
|
2011-01-09 21:52:00 +01:00
|
|
|
|
if(selection.isCommandable() && random.randRange(0, 1)==0){
|
2010-03-12 08:42:55 +01:00
|
|
|
|
SoundRenderer::getInstance().playFx(
|
|
|
|
|
selection.getFrontUnit()->getType()->getSelectionSound(),
|
|
|
|
|
selection.getFrontUnit()->getCurrVector(),
|
|
|
|
|
gameCamera->getPos());
|
|
|
|
|
}
|
|
|
|
|
selectionQuad.disable();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Gui::mouseMoveGraphics(int x, int y){
|
|
|
|
|
|
|
|
|
|
//compute selection
|
|
|
|
|
if(selectionQuad.isEnabled()){
|
|
|
|
|
selectionQuad.setPosUp(Vec2i(x, y));
|
2010-09-10 14:15:21 +02:00
|
|
|
|
computeSelected(false,false);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//compute position for building
|
|
|
|
|
if(isPlacingBuilding()){
|
2010-03-20 00:26:00 +01:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] isPlacingBuilding() == true\n",__FILE__,__FUNCTION__);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
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 14:15:21 +02:00
|
|
|
|
computeSelected(true,true);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
computeDisplay();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Gui::groupKey(int groupIndex){
|
2010-04-11 03:25:06 +02:00
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] groupIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,groupIndex);
|
2010-04-06 16:25:00 +02:00
|
|
|
|
|
2010-03-12 08:42:55 +01:00
|
|
|
|
if(isKeyDown(vkControl)){
|
2010-04-06 16:25:00 +02:00
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] groupIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,groupIndex);
|
|
|
|
|
|
2010-03-12 08:42:55 +01:00
|
|
|
|
selection.assignGroup(groupIndex);
|
|
|
|
|
}
|
|
|
|
|
else{
|
2010-04-06 16:25:00 +02:00
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] groupIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,groupIndex);
|
|
|
|
|
|
2010-03-12 08:42:55 +01:00
|
|
|
|
selection.recallGroup(groupIndex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-12 20:27:39 +02:00
|
|
|
|
void Gui::hotKey(char key) {
|
2010-04-06 16:25:00 +02:00
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] key = [%c][%d]\n",__FILE__,__FUNCTION__,key,key);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2010-06-12 20:27:39 +02:00
|
|
|
|
Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
|
|
|
|
|
|
|
|
|
|
if(key == configKeys.getCharKey("HotKeyCenterCameraOnSelection")) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
centerCameraOnSelection();
|
|
|
|
|
}
|
2010-06-12 20:27:39 +02:00
|
|
|
|
else if(key == configKeys.getCharKey("HotKeySelectIdleHarvesterUnit")) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
selectInterestingUnit(iutIdleHarvester);
|
|
|
|
|
}
|
2010-06-12 20:27:39 +02:00
|
|
|
|
else if(key == configKeys.getCharKey("HotKeySelectBuiltBuilding")) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
selectInterestingUnit(iutBuiltBuilding);
|
|
|
|
|
}
|
2010-06-12 20:27:39 +02:00
|
|
|
|
else if(key == configKeys.getCharKey("HotKeyDumpWorldToLog")) {
|
2010-05-18 05:53:57 +02:00
|
|
|
|
std::string worldLog = world->DumpWorldToLog();
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] worldLog dumped to [%s]\n",__FILE__,__FUNCTION__,__LINE__,worldLog.c_str());
|
|
|
|
|
}
|
2010-06-12 20:27:39 +02:00
|
|
|
|
else if(key == configKeys.getCharKey("HotKeyRotateUnitDuringPlacement")){
|
2010-03-18 22:26:40 +01:00
|
|
|
|
// Here the user triggers a unit rotation while placing a unit
|
2010-06-17 02:08:27 +02:00
|
|
|
|
if(isPlacingBuilding()) {
|
2010-03-27 04:09:11 +01:00
|
|
|
|
if(getBuilding()->getRotationAllowed()){
|
|
|
|
|
++selectedBuildingFacing;
|
|
|
|
|
}
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2010-06-12 20:27:39 +02:00
|
|
|
|
else if(key == configKeys.getCharKey("HotKeySelectDamagedUnit")) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
selectInterestingUnit(iutDamaged);
|
|
|
|
|
}
|
2010-06-12 20:27:39 +02:00
|
|
|
|
else if(key == configKeys.getCharKey("HotKeySelectStoreUnit")) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
selectInterestingUnit(iutStore);
|
|
|
|
|
}
|
2010-06-12 20:27:39 +02:00
|
|
|
|
else if(key == configKeys.getCharKey("HotKeySelectedUnitsAttack")) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
clickCommonCommand(ccAttack);
|
|
|
|
|
}
|
2010-06-12 20:27:39 +02:00
|
|
|
|
else if(key == configKeys.getCharKey("HotKeySelectedUnitsStop")) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
clickCommonCommand(ccStop);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-04-08 22:19:25 +02:00
|
|
|
|
void Gui::switchToNextDisplayColor(){
|
|
|
|
|
display.switchColor();
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-12 08:42:55 +01:00
|
|
|
|
void Gui::onSelectionChanged(){
|
|
|
|
|
resetState();
|
|
|
|
|
computeDisplay();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ================= PRIVATE =================
|
|
|
|
|
|
|
|
|
|
void Gui::giveOneClickOrders(){
|
|
|
|
|
CommandResult result;
|
2010-04-18 21:28:52 +02:00
|
|
|
|
bool queueKeyDown = isKeyDown(queueCommandKey);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
if(selection.isUniform()){
|
2010-04-18 21:28:52 +02:00
|
|
|
|
result= commander->tryGiveCommand(&selection, activeCommandType, Vec2i(0), (Unit*)NULL, queueKeyDown);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
else{
|
2010-04-18 21:28:52 +02:00
|
|
|
|
result= commander->tryGiveCommand(&selection, activeCommandClass, Vec2i(0), (Unit*)NULL, queueKeyDown);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
addOrdersResultToConsole(activeCommandClass, result);
|
|
|
|
|
activeCommandType= NULL;
|
|
|
|
|
activeCommandClass= ccStop;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-08 22:53:05 +01:00
|
|
|
|
void Gui::giveDefaultOrders(int x, int y) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
//compute target
|
|
|
|
|
const Unit *targetUnit= NULL;
|
|
|
|
|
Vec2i targetPos;
|
2011-01-08 22:53:05 +01:00
|
|
|
|
if(computeTarget(Vec2i(x, y), targetPos, targetUnit) == false) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
console->addStdMessage("InvalidPosition");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-12-20 04:12:00 +01:00
|
|
|
|
giveDefaultOrders(targetPos.x,targetPos.y,targetUnit,true);
|
2010-12-18 18:18:36 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Gui::givePreparedDefaultOrders(int x, int y){
|
2010-12-20 04:12:00 +01:00
|
|
|
|
giveDefaultOrders(x, y, NULL,false);
|
2010-12-18 18:18:36 +01:00
|
|
|
|
}
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2011-01-08 22:53:05 +01:00
|
|
|
|
void Gui::giveDefaultOrders(int x, int y,const Unit *targetUnit, bool paintMouse3d) {
|
2010-04-18 21:28:52 +02:00
|
|
|
|
bool queueKeyDown = isKeyDown(queueCommandKey);
|
2010-12-18 18:18:36 +01:00
|
|
|
|
Vec2i targetPos=Vec2i(x, y);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
//give order
|
2010-04-18 21:28:52 +02:00
|
|
|
|
CommandResult result= commander->tryGiveCommand(&selection, targetPos, targetUnit, queueKeyDown);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
//graphical result
|
|
|
|
|
addOrdersResultToConsole(activeCommandClass, result);
|
2011-01-08 22:53:05 +01:00
|
|
|
|
if(result == crSuccess || result == crSomeFailed) {
|
2010-12-20 04:12:00 +01:00
|
|
|
|
if(paintMouse3d)
|
|
|
|
|
mouse3d.enable();
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
if(random.randRange(0, 1)==0){
|
|
|
|
|
SoundRenderer::getInstance().playFx(
|
|
|
|
|
selection.getFrontUnit()->getType()->getCommandSound(),
|
|
|
|
|
selection.getFrontUnit()->getCurrVector(),
|
|
|
|
|
gameCamera->getPos());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//reset
|
|
|
|
|
resetState();
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-08 22:53:05 +01:00
|
|
|
|
void Gui::giveTwoClickOrders(int x, int y , bool prepared) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
|
|
|
|
CommandResult result;
|
|
|
|
|
|
|
|
|
|
//compute target
|
|
|
|
|
const Unit *targetUnit= NULL;
|
|
|
|
|
Vec2i targetPos;
|
2010-12-18 18:18:36 +01:00
|
|
|
|
if(prepared){
|
|
|
|
|
targetPos=Vec2i(x, y);
|
|
|
|
|
}
|
2011-01-08 22:53:05 +01:00
|
|
|
|
else {
|
|
|
|
|
if(computeTarget(Vec2i(x, y), targetPos, targetUnit) == false) {
|
2010-12-18 18:18:36 +01:00
|
|
|
|
console->addStdMessage("InvalidPosition");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2010-04-18 21:28:52 +02:00
|
|
|
|
bool queueKeyDown = isKeyDown(queueCommandKey);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
//give orders to the units of this faction
|
2011-01-08 22:53:05 +01:00
|
|
|
|
if(selectingBuilding == false) {
|
|
|
|
|
if(selection.isUniform()) {
|
2010-08-28 03:46:26 +02:00
|
|
|
|
result= commander->tryGiveCommand(&selection, activeCommandType,
|
|
|
|
|
targetPos, targetUnit,queueKeyDown);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
2011-01-08 22:53:05 +01:00
|
|
|
|
else {
|
2010-08-28 03:46:26 +02:00
|
|
|
|
result= commander->tryGiveCommand(&selection, activeCommandClass,
|
|
|
|
|
targetPos, targetUnit,queueKeyDown);
|
2010-04-18 09:35:48 +02:00
|
|
|
|
}
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
2011-01-08 22:53:05 +01:00
|
|
|
|
else {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
//selecting building
|
2010-08-28 03:46:26 +02:00
|
|
|
|
result= commander->tryGiveCommand(&selection,
|
|
|
|
|
activeCommandType, posObjWorld, choosenBuildingType,
|
|
|
|
|
selectedBuildingFacing,queueKeyDown);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//graphical result
|
|
|
|
|
addOrdersResultToConsole(activeCommandClass, result);
|
2011-01-08 22:53:05 +01:00
|
|
|
|
if(result == crSuccess || result == crSomeFailed) {
|
|
|
|
|
if(prepared == false) {
|
2010-12-20 04:12:00 +01:00
|
|
|
|
mouse3d.enable();
|
|
|
|
|
}
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2011-01-08 22:53:05 +01:00
|
|
|
|
if(random.randRange(0, 1) == 0) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
SoundRenderer::getInstance().playFx(
|
|
|
|
|
selection.getFrontUnit()->getType()->getCommandSound(),
|
|
|
|
|
selection.getFrontUnit()->getCurrVector(),
|
|
|
|
|
gameCamera->getPos());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-08 22:53:05 +01:00
|
|
|
|
void Gui::centerCameraOnSelection() {
|
|
|
|
|
if(selection.isEmpty() == false) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
Vec3f refPos= selection.getRefPos();
|
|
|
|
|
gameCamera->centerXZ(refPos.x, refPos.z);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-08 22:53:05 +01:00
|
|
|
|
void Gui::selectInterestingUnit(InterestingUnitType iut) {
|
2010-03-12 08:42:55 +01: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 07:43:47 +01:00
|
|
|
|
void Gui::mouseDownDisplayUnitSkills(int posDisplay) {
|
|
|
|
|
if(!selection.isEmpty()) {
|
|
|
|
|
if(posDisplay != cancelPos) {
|
|
|
|
|
if(posDisplay!=meetingPointPos) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
const Unit *unit= selection.getFrontUnit();
|
|
|
|
|
|
|
|
|
|
//uniform selection
|
2011-01-10 07:43:47 +01:00
|
|
|
|
if(selection.isUniform()) {
|
|
|
|
|
const CommandType *ct = display.getCommandType(posDisplay);
|
|
|
|
|
if(ct != NULL && unit->getFaction()->reqsOk(ct)) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
activeCommandType= display.getCommandType(posDisplay);
|
|
|
|
|
activeCommandClass= activeCommandType->getClass();
|
|
|
|
|
}
|
2011-01-10 07:43:47 +01:00
|
|
|
|
else {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
posDisplay= invalidPos;
|
|
|
|
|
activeCommandType= NULL;
|
|
|
|
|
activeCommandClass= ccStop;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//non uniform selection
|
2011-01-10 07:43:47 +01:00
|
|
|
|
else {
|
2010-03-12 08:42:55 +01: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 13:15:10 +01:00
|
|
|
|
selectingPos= true;
|
|
|
|
|
selectedBuildingFacing = CardinalDir::NORTH;
|
2010-03-12 08:42:55 +01:00
|
|
|
|
activePos= posDisplay;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Gui::computeInfoString(int posDisplay){
|
|
|
|
|
|
|
|
|
|
Lang &lang= Lang::getInstance();
|
|
|
|
|
|
|
|
|
|
display.setInfoText("");
|
2011-01-09 21:52:00 +01:00
|
|
|
|
if(posDisplay!=invalidPos && selection.isCommandable()){
|
2010-03-12 08:42:55 +01: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-24 00:57:46 +01:00
|
|
|
|
string text="";
|
2010-03-12 08:42:55 +01:00
|
|
|
|
const UpgradeCommandType *uct= static_cast<const UpgradeCommandType*>(ct);
|
|
|
|
|
if(unit->getFaction()->getUpgradeManager()->isUpgrading(uct->getProducedUpgrade())){
|
2011-01-24 00:57:46 +01:00
|
|
|
|
text=lang.get("Upgrading")+"\n\n";
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
else if(unit->getFaction()->getUpgradeManager()->isUpgraded(uct->getProducedUpgrade())){
|
2011-01-24 00:57:46 +01:00
|
|
|
|
text=lang.get("AlreadyUpgraded")+"\n\n";
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
2011-01-24 00:57:46 +01:00
|
|
|
|
display.setInfoText(text+ct->getReqDesc());
|
2010-03-12 08:42:55 +01: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 22:04:30 +01:00
|
|
|
|
void Gui::computeDisplay(){
|
2010-10-28 20:31:12 +02:00
|
|
|
|
|
|
|
|
|
//printf("Start ===> computeDisplay()\n");
|
2011-02-13 22:04:30 +01:00
|
|
|
|
Lang &lang= Lang::getInstance();
|
2010-03-12 08:42:55 +01:00
|
|
|
|
//init
|
|
|
|
|
display.clear();
|
|
|
|
|
|
2011-02-13 22:04:30 +01:00
|
|
|
|
// ================ PART 1 ================
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2011-02-13 22:04:30 +01: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 08:42:55 +01:00
|
|
|
|
}
|
2011-02-13 22:04:30 +01: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 08:42:55 +01:00
|
|
|
|
|
2011-02-13 22:04:30 +01:00
|
|
|
|
//portraits
|
|
|
|
|
for(int i= 0; i < selection.getCount(); ++i){
|
|
|
|
|
display.setUpImage(i, selection.getUnit(i)->getType()->getImage());
|
|
|
|
|
}
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2011-02-13 22:04:30 +01:00
|
|
|
|
// ================ PART 2 ================
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2011-02-13 22:04:30 +01:00
|
|
|
|
if(selectingPos || selectingMeetingPoint){
|
|
|
|
|
//printf("selectingPos || selectingMeetingPoint\n");
|
|
|
|
|
display.setDownSelectedPos(activePos);
|
|
|
|
|
}
|
2010-10-28 20:31:12 +02:00
|
|
|
|
|
2011-02-13 22:04:30 +01:00
|
|
|
|
if(selection.isCommandable()){
|
|
|
|
|
//printf("selection.isComandable()\n");
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2011-02-13 22:04:30 +01:00
|
|
|
|
if(selectingBuilding == false){
|
2010-10-28 20:31:12 +02:00
|
|
|
|
|
2011-02-13 22:04:30 +01: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 08:42:55 +01:00
|
|
|
|
|
2011-02-13 22:04:30 +01:00
|
|
|
|
display.setDownImage(cancelPos, ut->getCancelImage());
|
|
|
|
|
display.setDownLighted(cancelPos, true);
|
|
|
|
|
}
|
2010-10-28 20:31:12 +02:00
|
|
|
|
|
2011-02-13 22:04:30 +01:00
|
|
|
|
//meeting point
|
|
|
|
|
if(selection.isMeetable()){
|
|
|
|
|
//printf("selection.isMeetable()\n");
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2011-02-13 22:04:30 +01:00
|
|
|
|
display.setDownImage(meetingPointPos, ut->getMeetingPointImage());
|
|
|
|
|
display.setDownLighted(meetingPointPos, true);
|
|
|
|
|
}
|
2010-10-28 20:31:12 +02:00
|
|
|
|
|
2011-02-13 22:04:30 +01: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 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-02-13 22:04:30 +01: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 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-02-13 22:04:30 +01:00
|
|
|
|
else{
|
2010-03-12 08:42:55 +01:00
|
|
|
|
|
2011-02-13 22:04:30 +01: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 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-02-13 22:04:30 +01:00
|
|
|
|
}
|
2010-03-12 08:42:55 +01: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 21:52:00 +01:00
|
|
|
|
else if(selection.isCommandable()){
|
2010-03-12 08:42:55 +01: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 14:15:21 +02:00
|
|
|
|
void Gui::computeSelected(bool doubleClick, bool force){
|
2010-03-12 08:42:55 +01:00
|
|
|
|
Selection::UnitContainer units;
|
|
|
|
|
|
2010-09-10 14:15:21 +02:00
|
|
|
|
if( force || ( lastQuadCalcFrame+selectionCalculationFrameSkip < game->getTotalRenderFps() ) ){
|
|
|
|
|
lastQuadCalcFrame=game->getTotalRenderFps();
|
2011-02-13 22:04:30 +01:00
|
|
|
|
selectedResourceObject=NULL;
|
2010-09-10 14:15:21 +02:00
|
|
|
|
if(selectionQuad.isEnabled() && selectionQuad.getPosUp().dist(selectionQuad.getPosDown())<minQuadSize){
|
2011-02-13 22:04:30 +01:00
|
|
|
|
Renderer::getInstance().computeSelected(units, selectedResourceObject, true, selectionQuad.getPosDown(), selectionQuad.getPosDown());
|
2010-09-10 14:15:21 +02:00
|
|
|
|
}
|
|
|
|
|
else{
|
2011-02-15 01:24:31 +01:00
|
|
|
|
Renderer::getInstance().computeSelected(units, selectedResourceObject, false, selectionQuad.getPosDown(), selectionQuad.getPosUp());
|
2010-09-10 14:15:21 +02:00
|
|
|
|
}
|
|
|
|
|
selectingBuilding= false;
|
|
|
|
|
activeCommandType= NULL;
|
2011-01-08 22:53:05 +01:00
|
|
|
|
|
2010-09-10 14:15:21 +02:00
|
|
|
|
//select all units of the same type if double click
|
2011-03-08 21:19:19 +01:00
|
|
|
|
if(doubleClick && units.size()>0){
|
|
|
|
|
const Unit *refUnit= getRelevantObjectFromSelection(&units);
|
2010-09-10 14:15:21 +02: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 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2011-01-08 22:53:05 +01:00
|
|
|
|
|
2010-09-10 14:15:21 +02:00
|
|
|
|
bool shiftDown= isKeyDown(vkShift);
|
|
|
|
|
bool controlDown= isKeyDown(vkControl);
|
2011-01-08 22:53:05 +01:00
|
|
|
|
|
2010-09-10 14:15:21 +02:00
|
|
|
|
if(!shiftDown && !controlDown){
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] about to call selection.clear()\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
|
selection.clear();
|
|
|
|
|
}
|
2011-01-08 22:53:05 +01:00
|
|
|
|
|
2010-09-10 14:15:21 +02:00
|
|
|
|
if(!controlDown){
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] about to call selection.select(units)\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
|
selection.select(units);
|
2011-02-13 22:04:30 +01:00
|
|
|
|
if(!selection.isEmpty()){
|
|
|
|
|
selectedResourceObject=NULL;
|
|
|
|
|
}
|
2010-09-10 14:15:21 +02:00
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] selection.unSelect(units)\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
|
selection.unSelect(units);
|
|
|
|
|
}
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-08 22:53:05 +01:00
|
|
|
|
bool Gui::computeTarget(const Vec2i &screenPos, Vec2i &targetPos, const Unit *&targetUnit) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
Selection::UnitContainer uc;
|
|
|
|
|
Renderer &renderer= Renderer::getInstance();
|
2011-02-13 15:35:17 +01:00
|
|
|
|
const Object* obj=NULL;
|
|
|
|
|
renderer.computeSelected(uc, obj, true, screenPos, screenPos);
|
2010-03-12 08:42:55 +01:00
|
|
|
|
validPosObjWorld= false;
|
|
|
|
|
|
2011-01-08 22:53:05 +01:00
|
|
|
|
if(uc.empty() == false) {
|
2011-03-08 21:19:19 +01:00
|
|
|
|
targetUnit=getRelevantObjectFromSelection(&uc);
|
|
|
|
|
targetPos= targetUnit->getPos();
|
2010-03-12 08:42:55 +01:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2011-02-13 15:35:17 +01:00
|
|
|
|
else if(obj!=NULL) {
|
|
|
|
|
targetUnit= NULL;
|
|
|
|
|
targetPos= obj->getMapPos();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2011-01-08 22:53:05 +01:00
|
|
|
|
else {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
targetUnit= NULL;
|
2011-01-08 22:53:05 +01:00
|
|
|
|
if(renderer.computePosition(screenPos, targetPos)) {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
validPosObjWorld= true;
|
|
|
|
|
posObjWorld= targetPos;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2011-01-08 22:53:05 +01:00
|
|
|
|
else {
|
2010-03-12 08:42:55 +01:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-08 21:19:19 +01: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 05:34:19 +01:00
|
|
|
|
void Gui::removingObjectEvent(Object* o){
|
2011-02-13 22:04:30 +01:00
|
|
|
|
if(getSelectedResourceObject()==o){
|
|
|
|
|
selectedResourceObject=NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-12 08:42:55 +01:00
|
|
|
|
}}//end namespace
|