Passed
Pull Request — master (#291)
by Marek
12:50
created

FleetsOverviewDlg._populatePopup()   A

Complexity

Conditions 3

Size

Total Lines 11
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nop 3
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
1
#
2
#  Copyright 2001 - 2016 Ludek Smid [http://www.ospace.net/]
3
#
4
#  This file is part of Outer Space.
5
#
6
#  Outer Space is free software; you can redistribute it and/or modify
7
#  it under the terms of the GNU General Public License as published by
8
#  the Free Software Foundation; either version 2 of the License, or
9
#  (at your option) any later version.
10
#
11
#  Outer Space is distributed in the hope that it will be useful,
12
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
#  GNU General Public License for more details.
15
#
16
#  You should have received a copy of the GNU General Public License
17
#  along with Outer Space; if not, write to the Free Software
18
#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
#
20
import bisect
21
import math
22
23
import pygameui as ui
24
from osci.StarMapWidget import StarMapWidget
25
from osci import gdata, res, client
26
import ige.ospace.Const as Const
27
from ige.ospace import Rules
28
29
class FleetsOverviewDlg:
30
31
    def __init__(self, app):
32
        self.app = app
33
        self.createUI()
34
35
    def display(self):
36
        if gdata.config.defaults.showredirects != None:
37
            val = gdata.config.defaults.showredirects
38
            self.win.vRedirects.checked = val == 'yes'
39
40
        self.show()
41
        self.win.show()
42
        # register for updates
43
        if self not in gdata.updateDlgs:
44
            gdata.updateDlgs.append(self)
45
46
    def hide(self):
47
        self.win.setStatus(_("Ready."))
48
        self.win.hide()
49
        # unregister updates
50
        if self in gdata.updateDlgs:
51
            gdata.updateDlgs.remove(self)
52
53
    def update(self):
54
        self.show()
55
56
    def _analyzeRelations(self, playerID, fleet):
57
        # this evaluates color, and if it should be shown at all
58
        # get check box selections
59
        checkBoxes = [self.win.vEnemy.checked,
60
                      self.win.vUnfriendy.checked,
61
                      self.win.vNeutral.checked,
62
                      self.win.vFriendly.checked,
63
                      self.win.vAllied.checked]
64
65
        # check fleet color and decide if display the fleet
66
        if hasattr(fleet, 'owner'):
67
            plRelation = client.getRelationTo(fleet.owner)
68
            fgColor = res.getPlayerColor(fleet.owner)
69
            if fleet.owner == playerID and self.win.vMine.checked:
70
                return fgColor
71
            return fgColor if checkBoxes[bisect.bisect(Const.REL_BOUNDARIES, plRelation)] else None
72
        else:
73
            # with no owner assume enemy
74
            return res.getFFColorCode(Const.REL_ENEMY_LO) if checkBoxes[0] else None
75
76
    def _populateName(self, fleet):
77
        return fleet.customname if hasattr(fleet, 'customname') and fleet.customname \
78
                                else getattr(fleet, 'name', res.getUnknownName())
79
80
    def _populatePopup(self, playerID, fleet):
81
        if hasattr(fleet, 'owner') and playerID != fleet.owner:
82
            owner = getattr(client.get(fleet.owner, noUpdate=1), "name", res.getUnknownName())
83
            ownerName = " (%s)" % owner
84
            ownerNameTip = owner
85
            ownerTipTitle = _("Owner")
86
        else:
87
            ownerName = ""
88
            ownerNameTip = ""
89
            ownerTipTitle = ""
90
        return ownerName, ownerNameTip, ownerTipTitle
91
92
    def _populateLocation(self, playerID, fleet):
93
        systemName = "-"
94
        if hasattr(fleet, 'orbiting') and fleet.orbiting:
95
            system = client.get(fleet.orbiting, noUpdate=1)
96
            systemName = getattr(system, "name", res.getUnknownName())
97
        elif hasattr(fleet, 'closeSystem'):
98
            system = client.get(fleet.closeSystem, noUpdate=1)
99
            systemName = _("%s (dst)") % getattr(system, "name", res.getUnknownName())
100
        return systemName
101
102
    def _populateOrder(self, fleet):
103
        # get fleet current action and target of action
104
        order = "-"
105
        targetName = "-"
106
        if hasattr(fleet, 'actions') and fleet.actionIndex < len(fleet.actions):
107
            action, target, data = fleet.actions[fleet.actionIndex]
108
            if action == Const.FLACTION_REDIRECT and not self.win.vRedirects.checked:
109
                # ok, not interested then
110
                return None
111
            order = gdata.fleetActions[action]
112
            if target != Const.OID_NONE:
113
                targetName = getattr(client.get(target, noUpdate=1), 'name', res.getUnknownName())
114
                order = "%s %s" % (order, targetName)
115
        return order
116
117
    def _populateEta(self, fleet):
118
        return res.formatTime(fleet.eta) if hasattr(fleet, "eta") else "?"
119
120
    def _populateFuel(self, fleet):
121
        if hasattr(fleet, "storEn"):
122
            fuel = 100 * fleet.storEn / fleet.maxEn if fleet.maxEn > 0 else 0
123
        else:
124
            fuel = "?"
125
        return fuel
126
127
    def _populateOpTime(self, fleet):
128
        if hasattr(fleet, 'storEn') and hasattr(fleet, 'operEn'):
129
            turns = fleet.storEn / fleet.operEn if fleet.operEn > 0 else 100000
130
            rawRange = turns * fleet.speed / Rules.turnsPerDay
131
            _range = "%.2f" % rawRange
132
            opTime = res.formatTime(turns)
133
        else:
134
            _range = "?"
135
            opTime = "?"
136
        return opTime, _range
137
138
    def _populateLastUpgrade(self, fleet):
139
        return res.formatTime(fleet.lastUpgrade) if hasattr(fleet, "lastUpgrade") else "?"
140
141
    def show(self):
142
        player = client.getPlayer()
143
        items = []
144
        for fleetID in client.db.keys():
145
            fleet = client.get(fleetID, noUpdate=1)
146
            # skip non-fleets
147
            if not hasattr(fleet, "type") or fleet.type != Const.T_FLEET:
148
                continue
149
150
            fgColor = self._analyzeRelations(player.oid, fleet)
151
            if fgColor is None:
152
                # nothing to show
153
                continue
154
155
            order = self._populateOrder(fleet)
156
            if order is None:
157
                # nothing to show - redirect, which is not ticked
158
                continue
159
160
            ownerName, ownerNameTip, ownerTipTitle = self._populatePopup(player.oid, fleet)
161
            opTime, _range = self._populateOpTime(fleet)
162
163
            # create ListBox Item for fleet
164
            item = ui.Item(
165
                "%s %s" % (self._populateName(fleet), ownerName),
166
                tooltipTitle=ownerTipTitle,
167
                tooltip=ownerNameTip,
168
                tLocation=self._populateLocation(player.oid, fleet),
169
                tOrder=self._populateOrder(fleet),
170
                tMP=getattr(fleet, "combatPwr", "?"),
171
                tETA=self._populateEta(fleet),
172
                tSignature=getattr(fleet, "signature", "?"),
173
                tFuel=self._populateFuel(fleet),
174
                tOpTime=opTime,
175
                tRange=_range,
176
                tLastUpgrade=self._populateLastUpgrade(fleet),
177
                tFleetID=fleetID,
178
                foreground=fgColor)
179
            items.append(item)
180
181
        self.win.vFleets.items = items
182
        self.win.vFleets.itemsChanged()
183
184
    def onSelectFleet(self, widget, action, data):
185
        item = self.win.vFleets.selection[0]
186
        fleet = client.get(item.tFleetID, noUpdate=1)
187
        if hasattr(fleet, "owner") and fleet.owner == client.getPlayerID():
188
            # show dialog
189
            gdata.mainGameDlg.onSelectMapObj(None, None, item.tFleetID)
190
        else:
191
            # center fleet on map
192
            if hasattr(fleet, "x"):
193
                gdata.mainGameDlg.win.vStarMap.highlightPos = (fleet.x, fleet.y)
194
                gdata.mainGameDlg.win.vStarMap.setPos(fleet.x, fleet.y)
195
                self.hide()
196
                return
197
            self.win.setStatus(_("Cannot show location"))
198
199
    def onShowLocation(self, widget, action, data):
200
        item = self.win.vFleets.selection[0]
201
        fleet = client.get(item.tFleetID, noUpdate=1)
202
        # center on map
203
        if hasattr(fleet, "x"):
204
            gdata.mainGameDlg.win.vStarMap.highlightPos = (fleet.x, fleet.y)
205
            gdata.mainGameDlg.win.vStarMap.setPos(fleet.x, fleet.y)
206
            self.hide()
207
            return
208
        self.win.setStatus(_("Cannot show location"))
209
210
    def onToggleCondition(self, widget, action, data):
211
        self.update()
212
213
    def onClose(self, widget, action, data):
214
        self.hide()
215
216
    def createUI(self):
217
        w, h = gdata.scrnSize
218
        self.win = ui.Window(self.app,
219
            modal = 1,
220
            escKeyClose = 1,
221
            titleOnly = w == 800 and h == 600,
222
            movable = 0,
223
            title = _('Fleets Overview'),
224
            rect = ui.Rect((w - 800 - 4 * (w != 800)) / 2, (h - 600 - 4 * (h != 600)) / 2, 800 + 4 * (w != 800), 580 + 4 * (h != 600)),
225
            layoutManager = ui.SimpleGridLM(),
226
        )
227
        self.win.subscribeAction('*', self)
228
        # playets listbox
229
        ui.Listbox(self.win, layout = (0, 0, 40, 26), id = 'vFleets',
230
            columns = [
231
                (_('Fleet'), 'text', 5, ui.ALIGN_W),
232
                (_('Location'), 'tLocation', 6.5, ui.ALIGN_W),
233
                (_('Current order'), 'tOrder', 7, ui.ALIGN_W),
234
                (_('ETA'), 'tETA', 3, ui.ALIGN_E),
235
                (_('Fuel %'), 'tFuel', 3, ui.ALIGN_E),
236
                (_('Op. time'), 'tOpTime', 3, ui.ALIGN_E),
237
                (_('Range'), 'tRange', 3, ui.ALIGN_E),
238
                (_('MP'), 'tMP', 3, ui.ALIGN_E),
239
                (_('Sign'), 'tSignature', 2, ui.ALIGN_E),
240
                (_("Last upgr."), "tLastUpgrade", 3.5, ui.ALIGN_E),
241
            ],
242
            columnLabels = 1, action = 'onSelectFleet', rmbAction = "onShowLocation")
243
244
        ui.Check(self.win, layout = (0, 26, 5, 1), text = _('Mine'), id = "vMine",
245
            checked = 1, action = "onToggleCondition")
246
        ui.Check(self.win, layout = (5, 26, 5, 1), text = _('Enemy'), id = "vEnemy",
247
            checked = 0, action = "onToggleCondition")
248
        ui.Check(self.win, layout = (10, 26, 5, 1), text = _('Unfriendly'), id = "vUnfriendy",
249
            checked = 0, action = "onToggleCondition")
250
        ui.Check(self.win, layout = (15, 26, 5, 1), text = _('Neutral'), id = "vNeutral",
251
            checked = 0, action = "onToggleCondition")
252
        ui.Check(self.win, layout = (20, 26, 5, 1), text = _('Friendly'), id = "vFriendly",
253
            checked = 0, action = "onToggleCondition")
254
        ui.Check(self.win, layout = (25, 26, 5, 1), text = _('Allied'), id = "vAllied",
255
            checked = 0, action = "onToggleCondition")
256
        ui.Check(self.win, layout = (34, 26, 6, 1), text = _('Show redirects'), id = "vRedirects",
257
            checked = 0, action = "onToggleCondition")
258
        # status bar + submit/cancel
259
        ui.TitleButton(self.win, layout = (35, 27, 5, 1), text = _('Close'), action = 'onClose')
260
        ui.Title(self.win, id = 'vStatusBar', layout = (0, 27, 35, 1), align = ui.ALIGN_W)
261
        #self.win.statusBar = self.win.vStatusBar
262