osci.dialog.EmpireOverviewDlg   B
last analyzed

Complexity

Total Complexity 46

Size/Duplication

Total Lines 290
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 211
dl 0
loc 290
rs 8.72
c 0
b 0
f 0
wmc 46

11 Methods

Rating   Name   Duplication   Size   Complexity  
A EmpireOverviewDlg.hide() 0 3 1
A EmpireOverviewDlg.onClose() 0 2 1
A EmpireOverviewDlg.onMenu() 0 3 1
A EmpireOverviewDlg.onFleetsAnalysis() 0 2 1
A EmpireOverviewDlg.update() 0 3 2
A EmpireOverviewDlg.onOK() 0 2 1
A EmpireOverviewDlg.onPlanetsAnalysis() 0 2 1
F EmpireOverviewDlg.show() 0 175 34
A EmpireOverviewDlg.__init__() 0 6 1
A EmpireOverviewDlg.createUI() 0 40 1
A EmpireOverviewDlg.display() 0 5 2

How to fix   Complexity   

Complexity

Complex classes like osci.dialog.EmpireOverviewDlg often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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
21
import pygameui as ui
22
import re
23
from osci import gdata, client
24
import ige.ospace.Const as Const
25
from ige.ospace import Rules
26
import string, math
27
from PlanetsAnalysisDlg import PlanetsAnalysisDlg
28
from FleetsAnalysisDlg import FleetsAnalysisDlg
29
30
class EmpireOverviewDlg:
31
    """Displays Empire overview dialog.
32
33
    Dialog displays curent users statistics
34
    and amount of each strategic resource.
35
    """
36
    def __init__(self, app):
37
        self._textRows = 0
38
        self.app = app
39
        self.planetsAnalysisDlg = PlanetsAnalysisDlg(app)
40
        self.fleetsAnalysisDlg = FleetsAnalysisDlg(app)
41
        self.createUI()
42
43
    def display(self):
44
        self.show()
45
        # show window
46
        if not self.win.visible:
47
            self.win.show()
48
49
    def hide(self):
50
        self.win.setStatus(_("Ready."))
51
        self.win.hide()
52
53
    def update(self):
54
        if self.win.visible:
55
            self.show()
56
57
    def show(self):
58
        player = client.getPlayer()
59
        if not hasattr(player.stats, "prodProd"):
60
            self.win.vText.text = [_("No data available")]
61
            self.win.vText.offsetRow = 0
62
            self.win.vText.vertScrollbar.slider.position = 0
63
            self.win.vText.vertScrollbar.slider.max = 1
64
            return
65
66
        text = []
67
        # imperator or leader
68
        if player.imperator == 1:
69
            text.append(_("You are LEADER of the galaxy."))
70
            text.append("")
71
        elif player.imperator == 2:
72
            text.append(_("You are IMPERATOR of the galaxy."))
73
            text.append("")
74
        elif player.imperator >= 3:
75
            text.append(_("You are IMPERATOR of the galaxy."))
76
            text.append(_("You have the right to end this galaxy."))
77
            text.append("")
78
79
        # strategic resources
80
        # check ownership of the strat. resources
81
        srChange = {}
82
        for planetID in player.planets:
83
            planet = client.get(planetID)
84
            if planet.plStratRes:
85
                sr = planet.plStratRes
86
                srChange[sr] = srChange.get(sr, 0) + Rules.stratResAmountBig
87
88
        if player.stratRes or srChange:
89
            text.append(_("Strategic resources:"))
90
            # merge owned and change
91
            srList = player.stratRes.keys()
92
            for sr in srChange:
93
                if sr not in srList:
94
                    srList.append(sr)
95
            srList.sort()
96
            for sr in srList:
97
                # srChange is printed as integer - assumption is there are only
98
                # full generators of special resources (i.e. planets)
99
                text.append(u'    %s: %s (+%d)' % (
100
                    gdata.stratRes[sr],
101
                    player.stratRes.get(sr, 0) / float(Rules.stratResAmountBig),
102
                    srChange.get(sr, 0) / float(Rules.stratResAmountBig),
103
                ))
104
            text.append('')
105
        # statistics
106
        # compute some stats
107
        realProd = 0
108
        realSci = 0
109
        for planetID in player.planets:
110
            planet = client.get(planetID)
111
            realProd += planet.effProdProd
112
            realSci += planet.effProdSci
113
        for fleetID in player.fleets:
114
            fleet = client.get(fleetID)
115
        # display data
116
        text.append(_("Statistics:"))
117
        text.append(u'    %s: %s' % (_("Population"), getattr(player.stats, "storPop", "?")))
118
        if hasattr(player.stats, "storPop") and player.govPwr > player.stats.storPop and player.stats.storPop > 0:
119
            text.append(u'    %s: %s (%d %% %s)' % (_("Gov. power"), player.govPwr, 100 * (player.govPwr - player.stats.storPop) / player.govPwr, _("unused")))
120
        else:
121
            text.append(u'    %s: %s' % (_("Gov. power"), player.govPwr))
122
        text.append(u'    %s: %s' % (_("Planets"), getattr(player.stats, "planets", "?")))
123
        text.append(u'    %s: %s' % (_("Structures"), getattr(player.stats, "structs", "?")))
124
        text.append(u'    %s: %s' % (_("Raw production"), getattr(player.stats, "prodProd", "?")))
125
        text.append(u'    %s: %d' % (_("Total production"), realProd))
126
        text.append(u'    %s: %s' % (_("Raw research"), getattr(player.stats, "prodSci", "?")))
127
        text.append(u'    %s: %s' % (_("Total reseach"), player.effSciPoints))
128
        text.append(u'    %s: %s' % (_("Military power"), getattr(player.stats, "fleetPwr", "?")))
129
        if hasattr(player, "pirateFame"):
130
            text.append(u'    %s: %s (%+d %% %s)' % (
131
                _("Fame"),
132
                player.pirateFame,
133
                player.pirateFame,
134
                _("production eff.")
135
            ))
136
            text.append(u'    %s: %s fame' % (
137
                _("New colony on planet with TL3 resouce cost"),
138
                int(Rules.pirateTL3StratResColonyCostMod * Rules.pirateColonyCostMod * len(player.planets)),
139
            ))
140
            text.append(u'    %s: %s fame' % (
141
                _("New colony cost multiplier"),
142
                int(Rules.pirateColonyCostMod * len(player.planets)),
143
            ))
144
            text.append(u'        %s' % (
145
                _("(hover over system/planet to view actual cost)"),
146
            ))
147
        text.append("")
148
        # Production
149
        text.append(_("Production:"))
150
        text.append(u'    %s: %s' % (_("Raw production"), getattr(player.stats, "prodProd", "?")))
151
        if player.prodIncreasePool > 0:
152
            ratio = (Rules.unusedProdMod * player.prodIncreasePool) / player.stats.prodProd
153
            text.append(u'    %s: %d (%+d %% %s)' % (
154
                _("Unused production"), player.prodIncreasePool, min(ratio * 100, math.sqrt(ratio) * 100), _("effectivity")
155
            ))
156
        # fleet support
157
        total = getattr(player.stats, 'fleetSupportProd', 0) + player.fleetUpgradePool * Rules.operProdRatio
158
        if total > player.stats.prodProd / 10:
159
            effectivity = - 100 * (total - player.stats.prodProd / 10) / max(player.stats.prodProd, 1)
160
        else:
161
            effectivity = 0
162
        text.append(u'    %s: %+d (%s %d %s, %+d %% %s)' % (
163
            _("Fleet support"),
164
            - total,
165
            _("first"),
166
            player.stats.prodProd / 10,
167
            _("CP is free"),
168
            effectivity,
169
            _("effectivity")
170
        ))
171
        text.append(u"    %s: %d %%" % (_("Empire effectivity"), int(100 * player.prodEff)))
172
        text.append(u'    %s: %d' % (_("Total production"), realProd))
173
        text.append("")
174
        # Research
175
        text.append(_("Research:"))
176
        text.append(u"    %s: %d %%" % (_("Empire effectivity"), int(100 * player.sciEff)))
177
        if hasattr(player.stats, "prodSci"):
178
            text.append(u"    %s: %s" % (_("Raw production"), getattr(player.stats, "prodSci", "?")))
179
        text.append(u'    %s: %s' % (_("Real production"), realSci))
180
        if player.techLevel < 7:
181
            popSupp = int(player.stats.storPop * Rules.sciPtsPerCitizen[player.techLevel])
182
        else:
183
            popSupp = 0
184
        text.append(u'    %s: %+d' % (_("Population support"), -popSupp))
185
        text.append(u'    %s: %+d' % (_("From pacts"), player.effSciPoints + popSupp - player.sciPoints))
186
        text.append(u'    %s: %d' % (_("Total research"), player.effSciPoints))
187
        text.append("")
188
        # Fleet
189
        civ = [0, 0, 0, 0]
190
        mil = [0, 0, 0, 0]
191
        mp = [0, 0, 0, 0]
192
        for fleetID in player.fleets:
193
            fleet = client.get(fleetID)
194
            for designID, hp, shield, exp in fleet.ships:
195
                tech = player.shipDesigns[designID]
196
                if tech.isMilitary:
197
                    mil[tech.combatClass] += 1
198
                else:
199
                    civ[tech.combatClass] += 1
200
                mp[tech.combatClass] += int(tech.combatPwr * float(hp + shield) / (tech.maxHP + tech.shieldHP))
201
        text.append(_("Fleet:"))
202
        text.append(u'    %s: %d (%d %s)' % (_("Upgrade Pool"), player.fleetUpgradePool, - player.fleetUpgradePool * Rules.operProdRatio,_("CP to support")))
203
        text.append(u'    %s: %d %s + %d %s, %d %s' % (_("Small ships"), civ[0], _("civ"), mil[0], _("mil"), mp[0],_("MP")))
204
        text.append(u'    %s: %d %s + %d %s, %d %s' % (_("Medium ships"), civ[1], _("civ"), mil[1], _("mil"), mp[1],_("MP")))
205
        text.append(u'    %s: %d %s + %d %s, %d %s' % (_("Large ships"), civ[2], _("civ"), mil[2], _("mil"), mp[2],_("MP")))
206
207
        # Planetary Weapons
208
        weapons = player.planetWeapons
209
        if weapons[0] or weapons[1] or weapons[2]:
210
            text.append("")
211
            text.append(u'Planetary Weapons:')
212
            if weapons[0] != None:
213
                if weapons[0] in player.techs.keys():
214
                    tech = client.getTechInfo(weapons[0])
215
                    sweapon = tech.name
216
                    text.append(u'    Anti-small: %s' % sweapon)
217
            if weapons[1] != None:
218
                if weapons[1] in player.techs.keys():
219
                    tech = client.getTechInfo(weapons[1])
220
                    mweapon = tech.name
221
                    text.append(u'    Anti-medium: %s' % mweapon)
222
            if weapons[2] != None:
223
                if weapons[2] in player.techs.keys():
224
                    tech = client.getTechInfo(weapons[2])
225
                    lweapon = tech.name
226
                    text.append(u'    Anti-large: %s' % lweapon)
227
228
        self.win.vText.text = text
229
        self.win.vText.offsetRow = 0
230
        self.win.vText.vertScrollbar.slider.position = 0
231
        self.win.vText.vertScrollbar.slider.max = len(text)
232
233
234
    def onClose(self, widget, action, data):
235
        self.hide()
236
237
    def onOK(self, widget, action, data):
238
        self.hide()
239
240
    def onPlanetsAnalysis(self, widget, action, data):
241
        self.planetsAnalysisDlg.display()
242
243
    def onFleetsAnalysis(self, widget, action, data):
244
        self.fleetsAnalysisDlg.display()
245
246
    def onMenu(self, widget, action, data):
247
        r = widget.rect
248
        self.analysisMenu.show((self.win.rect.left + r.left, self.win.rect.bottom - 4 * r.height))
249
250
    def createUI(self):
251
        screenWidth, screenHeight = gdata.scrnSize
252
        # size of dialog in layout metrics (for SimpleGridLM)
253
        cols = 23
254
        rows = 27
255
        # dialog width and height in pixels
256
        width = cols * 20 + 5
257
        height = rows * 20 + 4
258
        #creating dialog window
259
        self.win = ui.Window(self.app,
260
            modal = 1,
261
            escKeyClose = 1,
262
            movable = 0,
263
            title = _("Empire Overview"),
264
            rect = ui.Rect((screenWidth - width) / 2, (screenHeight - height) / 2, width, height),
265
            layoutManager = ui.SimpleGridLM(),
266
        )
267
        self.win.subscribeAction('*', self)
268
        # first row is window title
269
        rows -= 1
270
271
        s = ui.Scrollbar(self.win, layout = (cols - 1, 0, 1, rows - 1))
272
        t = ui.Text(self.win, layout = (0, 0, cols - 1, rows - 1), id = "vText", editable = 0)
273
        self._textRows = rows - 1
274
        t.attachVScrollbar(s)
275
276
        # dialog bottom line
277
        ui.Title(self.win, layout = (0, rows - 1, cols - 10, 1))
278
        ui.TitleButton(self.win, layout = (cols - 10, rows - 1, 5, 1), text = _("Analysis"), action = "onMenu")
279
        ui.TitleButton(self.win, layout = (cols - 5, rows - 1, 5, 1), text = _("Close"), action = "onClose")
280
281
        # analysis menu
282
        self.analysisMenu = ui.Menu(self.app, title = _("Field of analysis"),
283
            width = 5,
284
            items = [
285
                ui.Item(_("Planets"), action = "onPlanetsAnalysis"),
286
                ui.Item(_("Fleets"), action = "onFleetsAnalysis"),
287
            ]
288
        )
289
        self.analysisMenu.subscribeAction("*", self)
290