Total Complexity | 51 |
Total Lines | 248 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like osci.dialog.PlanetsOverviewDlg 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 | from osci.StarMapWidget import StarMapWidget |
||
23 | from osci import gdata, res, client, sequip |
||
24 | import ige.ospace.Const as Const |
||
25 | from ige.ospace import ShipUtils, Rules |
||
26 | from ige import GameException |
||
27 | import math |
||
28 | |||
29 | class PlanetsOverviewDlg: |
||
30 | |||
31 | def __init__(self, app): |
||
32 | self.app = app |
||
33 | self.showMine = 1 |
||
34 | self.showColonizable = 0 |
||
35 | self.showOtherPlayers = 0 |
||
36 | self.showUncolonizable = 0 |
||
37 | self.createUI() |
||
38 | |||
39 | def display(self): |
||
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 _shallShow(self, planet, player): |
||
57 | ok = 0 |
||
58 | if hasattr(planet, 'owner'): |
||
59 | if self.showMine and planet.owner == player.oid: |
||
60 | ok = 1 |
||
61 | elif self.showOtherPlayers and planet.owner != Const.OID_NONE and planet.owner != player.oid: |
||
62 | ok = 1 |
||
63 | elif self.showColonizable and planet.owner == Const.OID_NONE and planet.plType not in ('G', 'A'): |
||
64 | ok = 1 |
||
65 | elif self.showUncolonizable and planet.plType in ('G', 'A'): |
||
66 | ok = 1 |
||
67 | elif hasattr(planet, 'plType'): |
||
68 | if self.showColonizable and planet.plType not in ('G', 'A'): |
||
69 | ok = 1 |
||
70 | if self.showUncolonizable and planet.plType in ('G', 'A'): |
||
71 | ok = 1 |
||
72 | return ok == 1 |
||
73 | |||
74 | def _getTaskProd(self, task, tech, planetID): |
||
75 | anotherPlanet = Rules.buildOnAnotherPlanetMod if task.targetID != planetID else 1 |
||
76 | |||
77 | prodFirst = tech.buildProd * anotherPlanet - task.currProd |
||
78 | prodNext = (task.quantity - 1) * tech.buildProd * anotherPlanet |
||
79 | return prodFirst, prodNext |
||
80 | |||
81 | def _processProdQueue(self, planet): |
||
82 | player = client.getPlayer() |
||
83 | if planet.prodQueue and planet.effProdProd > 0: |
||
84 | index = 0 |
||
85 | totalProd = 0 |
||
86 | for task in planet.prodQueue: |
||
87 | if task.isShip: |
||
88 | tech = player.shipDesigns[task.techID] |
||
89 | else: |
||
90 | tech = client.getFullTechInfo(task.techID) |
||
91 | prodFirst, prodNext = self._getTaskProd(task, tech, planet.oid) |
||
92 | if index == 0: |
||
93 | constrInfo = tech.name |
||
94 | etc = math.ceil(float(prodFirst) / planet.effProdProd) |
||
95 | totalProd += prodFirst + prodNext |
||
96 | index += 1 |
||
97 | etc = res.formatTime(etc) |
||
1 ignored issue
–
show
|
|||
98 | totalEtc = res.formatTime(math.ceil(float(totalProd) / planet.effProdProd)) |
||
99 | elif planet.prodQueue: |
||
100 | task = planet.prodQueue[0] |
||
101 | if task.isShip: |
||
102 | tech = player.shipDesigns[task.techID] |
||
103 | else: |
||
104 | tech = client.getTechInfo(task.techID) |
||
105 | constrInfo = tech.name |
||
106 | etc = _('N/A') |
||
107 | totalEtc = _("N/A") |
||
108 | else: |
||
109 | constrInfo = _("-") |
||
110 | etc = "-" |
||
111 | totalEtc = _("-") |
||
112 | return constrInfo, etc, totalEtc |
||
1 ignored issue
–
show
|
|||
113 | |||
114 | |||
115 | def show(self): |
||
116 | player = client.getPlayer() |
||
117 | |||
118 | items = [] |
||
119 | for planetID in client.db.keys(): |
||
120 | planet = client.get(planetID, noUpdate=1) |
||
121 | # skip non-planets |
||
122 | if not hasattr(planet, "type") or planet.type != Const.T_PLANET: |
||
123 | continue |
||
124 | if not self._shallShow(planet, player): |
||
125 | continue |
||
126 | # fill in data |
||
127 | ownerID = getattr(planet, 'owner', Const.OID_NONE) |
||
128 | if hasattr(planet, 'owner') and planet.owner == player.oid: |
||
129 | constrInfo, etc, totalEtc = self._processProdQueue(planet) |
||
130 | else: |
||
131 | constrInfo = '?' |
||
132 | etc = '?' |
||
133 | totalEtc = '?' |
||
134 | # used slots |
||
135 | try: |
||
136 | freeSlots = planet.plSlots - len(planet.slots) |
||
137 | except AttributeError: |
||
138 | freeSlots = '?' |
||
139 | # morale |
||
140 | try: |
||
141 | morale = int(planet.morale) |
||
142 | except AttributeError: |
||
143 | morale = "?" |
||
144 | |||
145 | plType = gdata.planetTypes[getattr(planet, 'plType', None)] |
||
146 | # list item |
||
147 | item = ui.Item(getattr(planet, 'name', res.getUnknownName()), |
||
148 | tPlType=_(plType), |
||
149 | tPlBio=getattr(planet, 'plBio', '?'), |
||
150 | tPlMin=getattr(planet, 'plMin', '?'), |
||
151 | tPlEn=getattr(planet, 'plEn', '?'), |
||
152 | tChangeBio=getattr(planet, 'changeBio', '?'), |
||
153 | tChangeEn=getattr(planet, 'changeEn', '?'), |
||
154 | tETC=etc, |
||
155 | tTotalETC=totalEtc, |
||
156 | tConstrInfo=constrInfo, |
||
157 | tFree=freeSlots, |
||
158 | tMorale=morale, |
||
159 | tSpace=getattr(planet, 'plSlots', '?'), |
||
160 | tDiam=getattr(planet, 'plDiameter', 0) / 1000, |
||
161 | tProd=getattr(planet, 'effProdProd', '?'), |
||
162 | tSci=getattr(planet, 'effProdSci', '?'), |
||
163 | tPlanetID=planetID, |
||
164 | foreground=res.getPlayerColor(ownerID)) |
||
165 | items.append(item) |
||
166 | self.win.vPlanets.items = items |
||
167 | self.win.vPlanets.itemsChanged() |
||
168 | # buttons |
||
169 | self.win.vMine.pressed = self.showMine |
||
170 | self.win.vOtherPlayers = self.showOtherPlayers |
||
171 | self.win.vColonizable = self.showColonizable |
||
172 | self.win.vUncolonizable = self.showUncolonizable |
||
173 | |||
174 | def onSelectPlanet(self, widget, action, data): |
||
175 | item = self.win.vPlanets.selection[0] |
||
176 | planet = client.get(item.tPlanetID, noUpdate=1) |
||
177 | if hasattr(planet, "owner") and planet.owner == client.getPlayerID(): |
||
178 | # show dialog |
||
179 | gdata.mainGameDlg.onSelectMapObj(None, None, item.tPlanetID) |
||
180 | else: |
||
181 | # center on map |
||
182 | if hasattr(planet, "x"): |
||
183 | gdata.mainGameDlg.win.vStarMap.highlightPos = (planet.x, planet.y) |
||
184 | gdata.mainGameDlg.win.vStarMap.setPos(planet.x, planet.y) |
||
185 | self.hide() |
||
186 | return |
||
187 | self.win.setStatus(_("Cannot show location")) |
||
188 | |||
189 | def onShowLocation(self, widget, action, data): |
||
190 | item = self.win.vPlanets.selection[0] |
||
191 | planet = client.get(item.tPlanetID, noUpdate=1) |
||
192 | # center on map |
||
193 | if hasattr(planet, "x"): |
||
194 | gdata.mainGameDlg.win.vStarMap.highlightPos = (planet.x, planet.y) |
||
195 | gdata.mainGameDlg.win.vStarMap.setPos(planet.x, planet.y) |
||
196 | self.hide() |
||
197 | return |
||
198 | self.win.setStatus(_("Cannot show location")) |
||
199 | |||
200 | def onToggleCondition(self, widget, action, data): |
||
201 | setattr(self, widget.data, not getattr(self, widget.data)) |
||
202 | self.update() |
||
203 | |||
204 | def onClose(self, widget, action, data): |
||
205 | self.hide() |
||
206 | |||
207 | def createUI(self): |
||
208 | w, h = gdata.scrnSize |
||
209 | self.win = ui.Window(self.app, |
||
210 | modal=1, |
||
211 | escKeyClose=1, |
||
212 | titleOnly=w == 800 and h == 600, |
||
213 | movable=0, |
||
214 | title=_('Planets Overview'), |
||
215 | rect=ui.Rect((w - 800 - 4 * (w != 800)) / 2, (h - 600 - 4 * (h != 600)) / 2, 800 + 4 * (w != 800), 580 + 4 * (h != 600)), |
||
216 | layoutManager=ui.SimpleGridLM()) |
||
217 | self.win.subscribeAction('*', self) |
||
218 | # playets listbox |
||
219 | ui.Listbox(self.win, layout=(0, 0, 40, 26), id='vPlanets', |
||
220 | columns=[(_('Planet'), 'text', 6, ui.ALIGN_W), |
||
221 | (_('Type'), 'tPlType', 3.5, ui.ALIGN_W), |
||
222 | (_('Env'), 'tPlBio', 1.5, ui.ALIGN_E), |
||
223 | (_('Min'), 'tPlMin', 1.5, ui.ALIGN_E), |
||
224 | (_('En'), 'tPlEn', 1.5, ui.ALIGN_E), |
||
225 | (_('Bio+-'), 'tChangeBio', 2.0, ui.ALIGN_E), |
||
226 | (_('En+-'), 'tChangeEn', 2.0, ui.ALIGN_E), |
||
227 | (_('Free'), 'tFree', 2.0, ui.ALIGN_E), |
||
228 | (_('Sl.'), 'tSpace', 1.5, ui.ALIGN_E), |
||
229 | (_('D.'), 'tDiam', 1.5, ui.ALIGN_E), |
||
230 | (_('Mrl'), 'tMorale', 2, ui.ALIGN_E), |
||
231 | (_('CP'), 'tProd', 2, ui.ALIGN_E), |
||
232 | (_('RP'), 'tSci', 2, ui.ALIGN_E), |
||
233 | (_('ETC'), 'tETC', 2.5, ui.ALIGN_E), |
||
234 | (_('Tot.ETC'), 'tTotalETC', 2.5, ui.ALIGN_E), |
||
235 | (_('Constructing'), 'tConstrInfo', 7.0, ui.ALIGN_W)], |
||
236 | columnLabels=1, action='onSelectPlanet', rmbAction="onShowLocation") |
||
237 | ui.Button(self.win, layout=(0, 26, 5, 1), text=_('My planets'), id="vMine", |
||
238 | toggle=1, action="onToggleCondition", data="showMine") |
||
239 | ui.Button(self.win, layout=(5, 26, 5, 1), text=_('Other cmdrs'), id="vOtherPlayers", |
||
240 | toggle=1, action="onToggleCondition", data="showOtherPlayers") |
||
241 | ui.Button(self.win, layout=(10, 26, 5, 1), text=_('Colonizable'), id="vColonizable", |
||
242 | toggle=1, action="onToggleCondition", data="showColonizable") |
||
243 | ui.Button(self.win, layout=(15, 26, 5, 1), text=_('Uncolonizable'), id="vUncolonizable", |
||
244 | toggle=1, action="onToggleCondition", data="showUncolonizable") |
||
245 | # status bar + submit/cancel |
||
246 | ui.TitleButton(self.win, layout=(35, 27, 5, 1), text=_('Close'), action='onClose') |
||
247 | ui.Title(self.win, id='vStatusBar', layout=(0, 27, 35, 1), align=ui.ALIGN_W) |
||
248 |