1 /***************************************************************************
2 * Mechanized Assault and Exploration Reloaded Projectfile *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19
20 #include "ui/graphical/game/control/mousemode/mousemodeattack.h"
21 #include "ui/graphical/game/control/mouseaction/mouseactionattack.h"
22 #include "ui/graphical/game/unitselection.h"
23 #include "game/data/map/map.h"
24 #include "game/data/units/vehicle.h"
25 #include "game/data/units/building.h"
26 #include "input/mouse/mouse.h"
27 #include "input/mouse/cursor/mousecursorsimple.h"
28 #include "input/mouse/cursor/mousecursorattack.h"
29
30 //------------------------------------------------------------------------------
cMouseModeAttack(const cMap * map_,const cUnitSelection & unitSelection_,const cPlayer * player_)31 cMouseModeAttack::cMouseModeAttack (const cMap* map_, const cUnitSelection& unitSelection_, const cPlayer* player_) :
32 cMouseMode (map_, unitSelection_, player_)
33 {
34 establishUnitSelectionConnections();
35 }
36
37 //------------------------------------------------------------------------------
getType() const38 eMouseModeType cMouseModeAttack::getType() const
39 {
40 return eMouseModeType::Attack;
41 }
42
43 //------------------------------------------------------------------------------
setCursor(cMouse & mouse,const cPosition & mapPosition) const44 void cMouseModeAttack::setCursor (cMouse& mouse, const cPosition& mapPosition) const
45 {
46 if (canExecuteAction (mapPosition))
47 {
48 const auto selectedUnit = unitSelection.getSelectedUnit();
49
50 if (selectedUnit != nullptr && map != nullptr)
51 {
52 mouse.setCursor (std::make_unique<cMouseCursorAttack> (*selectedUnit, mapPosition, *map));
53 }
54 else
55 {
56 mouse.setCursor (std::make_unique<cMouseCursorAttack> ());
57 }
58 }
59 else
60 {
61 mouse.setCursor (std::make_unique<cMouseCursorSimple> (eMouseCursorSimpleType::No));
62 }
63 }
64
65 //------------------------------------------------------------------------------
getMouseAction(const cPosition & mapPosition) const66 std::unique_ptr<cMouseAction> cMouseModeAttack::getMouseAction (const cPosition& mapPosition) const
67 {
68 if (canExecuteAction (mapPosition))
69 {
70 return std::make_unique<cMouseActionAttack> ();
71 }
72 else return nullptr;
73 }
74
75 //------------------------------------------------------------------------------
canExecuteAction(const cPosition & mapPosition) const76 bool cMouseModeAttack::canExecuteAction (const cPosition& mapPosition) const
77 {
78 if (!map) return false;
79
80 const auto selectedVehicle = unitSelection.getSelectedVehicle();
81 const auto selectedBuilding = unitSelection.getSelectedBuilding();
82
83 return (selectedVehicle && (selectedVehicle->data.muzzleType != sUnitData::MUZZLE_TYPE_TORPEDO || map->isWaterOrCoast (mapPosition))) ||
84 (selectedBuilding && selectedBuilding->isInRange (mapPosition));
85 }
86
87 //------------------------------------------------------------------------------
establishUnitSelectionConnections()88 void cMouseModeAttack::establishUnitSelectionConnections()
89 {
90 const auto selectedUnit = unitSelection.getSelectedUnit();
91
92 if (selectedUnit)
93 {
94 selectedUnitSignalConnectionManager.connect (selectedUnit->data.rangeChanged, [this]() { needRefresh(); });
95 selectedUnitSignalConnectionManager.connect (selectedUnit->data.damageChanged, [this]() { needRefresh(); });
96 selectedUnitSignalConnectionManager.connect (selectedUnit->disabledChanged, [this]() { needRefresh(); });
97 selectedUnitSignalConnectionManager.connect (selectedUnit->positionChanged, [this]() { needRefresh(); });
98 }
99 }
100
101 //------------------------------------------------------------------------------
establishMapFieldConnections(const cMapField & field)102 void cMouseModeAttack::establishMapFieldConnections (const cMapField& field)
103 {
104 mapFieldSignalConnectionManager.connect (field.unitsChanged, [this, &field]() { updateFieldUnitConnections (field); needRefresh(); });
105
106 updateFieldUnitConnections (field);
107 }
108
109 //------------------------------------------------------------------------------
updateFieldUnitConnections(const cMapField & field)110 void cMouseModeAttack::updateFieldUnitConnections (const cMapField& field)
111 {
112 mapFieldUnitsSignalConnectionManager.disconnectAll();
113
114 auto plane = field.getPlane();
115 if (plane)
116 {
117 mapFieldUnitsSignalConnectionManager.connect (plane->flightHeightChanged, [this]() { needRefresh(); });
118 mapFieldUnitsSignalConnectionManager.connect (plane->data.hitpointsChanged, [this]() { needRefresh(); });
119 }
120 auto vehicle = field.getVehicle();
121 if (vehicle)
122 {
123 mapFieldUnitsSignalConnectionManager.connect (vehicle->data.hitpointsChanged, [this]() { needRefresh(); });
124 }
125 auto building = field.getBuilding();
126 if (building)
127 {
128 mapFieldUnitsSignalConnectionManager.connect (building->data.hitpointsChanged, [this]() { needRefresh(); });
129 }
130 }
131