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 pygame |
||
22 | |||
23 | import pygameui as ui |
||
24 | |||
25 | from ige import GameException |
||
26 | from ige.ospace import ShipUtils, Rules |
||
27 | import ige.ospace.Const as Const |
||
28 | |||
29 | from osci import gdata, res, client, sequip |
||
30 | from osci.StarMapWidget import StarMapWidget |
||
31 | |||
32 | from ConstrSelTechDlg import ConstrSelTechDlg |
||
33 | from ConstrUpgradeDlg import ConstrUpgradeDlg |
||
34 | from ConfirmDlg import ConfirmDlg |
||
35 | |||
36 | class ConstructionDlg: |
||
37 | |||
38 | def __init__(self, app): |
||
39 | self.app = app |
||
40 | self.createUI() |
||
41 | self.selTechDlg = ConstrSelTechDlg(app) |
||
42 | self.upgradeDlg = ConstrUpgradeDlg(app) |
||
43 | self.confirmDlg = ConfirmDlg(app) |
||
44 | self.selectedDesignID = None |
||
45 | self.highlightedDesignID = None |
||
46 | self.editMode = False |
||
47 | |||
48 | def display(self): |
||
49 | self.itemCache = {} |
||
50 | self.hullID = Const.OID_NONE |
||
51 | self.ctrlID = Const.OID_NONE |
||
52 | self.eqIDs = {} |
||
53 | self.selectedEqID = None |
||
54 | self.update() |
||
55 | self.win.show() |
||
56 | # register for updates |
||
57 | if self not in gdata.updateDlgs: |
||
58 | gdata.updateDlgs.append(self) |
||
59 | |||
60 | def hide(self): |
||
61 | self.win.setStatus(_("Ready.")) |
||
62 | self.win.hide() |
||
63 | # unregister updates |
||
64 | if self in gdata.updateDlgs: |
||
65 | gdata.updateDlgs.remove(self) |
||
66 | |||
67 | def update(self): |
||
68 | self.showDesigns() |
||
69 | self.showDetails() |
||
70 | |||
71 | def _getNumberInFleets(self, designID): |
||
72 | count = 0 |
||
73 | for fleetID in client.getPlayer().fleets: |
||
74 | fleet = client.get(fleetID) |
||
75 | count += len([designID for tmpDesignID, hp, shieldHP, exp in fleet.ships if tmpDesignID == designID]) |
||
76 | return count |
||
77 | |||
78 | def _getNumberInBuild(self, designID): |
||
79 | count = 0 |
||
80 | # planet queues |
||
81 | for planetID in client.db.keys(): |
||
82 | planet = client.get(planetID, noUpdate=1) |
||
83 | # skip non-planets |
||
84 | try: |
||
85 | count += sum((task.quantity for task in planet.prodQueue if (task.isShip and task.techID == designID))) |
||
86 | except AttributeError: |
||
87 | # this is either not a planet, or it's not planet with prodqueue useful for us |
||
88 | continue |
||
89 | # global queues |
||
90 | for globalQueue in client.getPlayer().prodQueues: |
||
91 | count += sum((task.quantity for task in globalQueue if (task.isShip and task.techID == designID))) |
||
92 | return count |
||
93 | |||
94 | def showDesigns(self): |
||
95 | player = client.getPlayer() |
||
96 | # check if highlighted ship design exists |
||
97 | if self.highlightedDesignID not in player.shipDesigns: |
||
98 | self.highlightedDesignID = None |
||
99 | # designs |
||
100 | highlighted = None |
||
101 | items = [] |
||
102 | for designID in player.shipDesigns: |
||
103 | spec = player.shipDesigns[designID] |
||
104 | |||
105 | countInService = self._getNumberInFleets(designID) |
||
106 | countInBuild = self._getNumberInBuild(designID) |
||
107 | |||
108 | # ui list item |
||
109 | hullTech = client.getFullTechInfo(spec.hullID) |
||
110 | item = ui.Item(spec.name, tDesignID=designID, |
||
111 | tClass="%s/%s%d" % (_(gdata.shipClasses[spec.combatClass][:1].upper()), |
||
112 | _("TL"), |
||
113 | hullTech.level), |
||
114 | tNumber=countInService, |
||
115 | tInBuild=countInBuild) |
||
116 | if spec.upgradeTo: |
||
117 | item.foreground = gdata.sevColors[gdata.NONE] |
||
118 | if designID == self.highlightedDesignID: |
||
119 | highlighted = item |
||
120 | items.append(item) |
||
121 | self.win.vDesigns.items = items |
||
122 | self.win.vDesigns.itemsChanged() |
||
123 | self.win.vDesigns.highlightItem(highlighted, 0) |
||
124 | |||
125 | def _setDetailButtons(self, player): |
||
126 | if self.selectedDesignID: |
||
127 | self.win.vScrap.enabled = 1 |
||
128 | if player.shipDesigns[self.selectedDesignID].upgradeTo == 0: |
||
129 | self.win.vUpgrade.enabled = 1 |
||
130 | self.win.vUpgrade.text = _("Upgrade") |
||
131 | else: |
||
132 | self.win.vUpgrade.enabled = 1 |
||
133 | self.win.vUpgrade.text = _("Cancel Upgrd") |
||
134 | |||
135 | if self.editMode: |
||
136 | self.win.vName.enabled = 1 |
||
137 | self.win.vEnginesButton.enabled = 1 |
||
138 | self.win.vWeaponsButton.enabled = 1 |
||
139 | self.win.vEquipmentButton.enabled = 1 |
||
140 | self.win.vUpgrade.enabled = 0 |
||
141 | self.win.vUpgrade.text = _("Upgrade") |
||
142 | self.win.vScrap.enabled = 0 |
||
143 | else: |
||
144 | # view only mode? |
||
145 | # let's reset highlights in design listboxes |
||
146 | self.selectedEqID = None |
||
147 | self.win.vName.enabled = 0 |
||
148 | self.win.vEngines.unselectAll() |
||
149 | self.win.vWeapons.unselectAll() |
||
150 | self.win.vEquipment.unselectAll() |
||
151 | |||
152 | self.win.vDuplDesign.enabled = 1 |
||
153 | self.win.vConstruct.enabled = 0 |
||
154 | self.win.vEnginesButton.enabled = 0 |
||
155 | self.win.vWeaponsButton.enabled = 0 |
||
156 | self.win.vEquipmentButton.enabled = 0 |
||
157 | if not self.selectedDesignID: |
||
158 | self.win.vScrap.enabled = 0 |
||
159 | self.win.vUpgrade.enabled = 0 |
||
160 | |||
161 | def _designRepresentation(self, player): |
||
162 | if self.highlightedDesignID is None: |
||
163 | if self.editMode: |
||
164 | if self.ctrlID: |
||
165 | eqIDs = {self.ctrlID: 1} |
||
166 | else: |
||
167 | eqIDs = {} |
||
168 | for eqID in self.eqIDs: |
||
169 | eqIDs[eqID] = self.eqIDs[eqID] |
||
170 | improvements = [] |
||
171 | else: |
||
172 | self.hullID = self.ctrlID = None |
||
173 | self.win.vName.text = "" |
||
174 | self.eqIDs = {} |
||
175 | eqIDs = {} |
||
176 | improvements = [] |
||
177 | else: |
||
178 | spec = player.shipDesigns[self.highlightedDesignID] |
||
179 | self.hullID = spec.hullID |
||
180 | eqIDs = spec.eqIDs |
||
181 | improvements = spec.improvements |
||
182 | self.win.vName.text = spec.name |
||
183 | self.win.vHull.text = client.getTechInfo(self.hullID).name |
||
184 | self.eqIDs = {} |
||
185 | for eqID in eqIDs: |
||
186 | tech = client.getTechInfo(eqID) |
||
187 | if tech.subtype == "seq_ctrl": |
||
188 | self.ctrlID = eqID |
||
189 | self.win.vCtrl.text = tech.name |
||
190 | else: |
||
191 | self.eqIDs[eqID] = eqIDs[eqID] |
||
192 | try: |
||
193 | result = ShipUtils.makeShipFullSpec(player, None, self.hullID, eqIDs, improvements) |
||
194 | if self.editMode: |
||
195 | self.win.vConstruct.enabled = 1 |
||
196 | except GameException, e: |
||
197 | self.win.setStatus(e.args[0]) |
||
198 | self.win.vConstruct.enabled = 0 |
||
199 | try: |
||
200 | result = ShipUtils.makeShipFullSpec(player, None, self.hullID, eqIDs, |
||
201 | improvements, raiseExs=False) |
||
202 | except GameException: |
||
203 | result = None |
||
204 | else: |
||
205 | self.win.setStatus(_("Ready.")) |
||
206 | return result |
||
207 | |||
208 | def _detailEquipmentLists(self): |
||
209 | # design info |
||
210 | if self.hullID: |
||
211 | tech = client.getTechInfo(self.hullID) |
||
212 | self.win.vHull.text = tech.name # TODO _(tech.name) |
||
213 | elif self.editMode: |
||
214 | self.win.vHull.text = _("[Click to select]") |
||
215 | else: |
||
216 | self.win.vHull.text = "" |
||
217 | if self.ctrlID: |
||
218 | tech = client.getTechInfo(self.ctrlID) |
||
219 | self.win.vCtrl.text = tech.name # TODO _(tech.name) |
||
220 | elif self.editMode: |
||
221 | self.win.vCtrl.text = _("[Click to select]") |
||
222 | else: |
||
223 | self.win.vCtrl.text = "" |
||
224 | # equipments |
||
225 | engines = [] |
||
226 | weapons = [] |
||
227 | equipment = [] |
||
228 | selected = None |
||
229 | selected_type = None |
||
230 | for eqID in self.eqIDs: |
||
231 | tech = client.getTechInfo(eqID) |
||
232 | short = sequip.getShortDescr(eqID) |
||
233 | _long = sequip.getLongDescr(eqID) |
||
234 | # cache has been introduced to let items preserve highlight information |
||
235 | if eqID in self.itemCache: |
||
236 | item = self.itemCache[eqID] |
||
237 | item.tNumber = self.eqIDs[eqID] |
||
238 | else: |
||
239 | item = ui.Item(tech.name, |
||
240 | techID=eqID, |
||
241 | tNumber=self.eqIDs[eqID], |
||
242 | tData=short, |
||
243 | tooltipTitle=_("Details"), |
||
244 | tooltip=_long, |
||
245 | statustip=_long) |
||
246 | self.itemCache[eqID] = item |
||
247 | if eqID == self.selectedEqID: |
||
248 | selected = item |
||
249 | selected_type = tech.subtype |
||
250 | if tech.subtype == "seq_eng": |
||
251 | engines.append(item) |
||
252 | elif tech.subtype == "seq_wpn": |
||
253 | weapons.append(item) |
||
254 | elif tech.subtype in ["seq_mod", "seq_struct"]: |
||
255 | equipment.append(item) |
||
256 | self.win.vEngines.items = engines |
||
257 | self.win.vEngines.itemsChanged() |
||
258 | if selected_type == "seq_eng": |
||
259 | self.win.vEngines.selectItem(selected) |
||
260 | else: |
||
261 | self.win.vEngines.selectItem(None) |
||
262 | self.win.vWeapons.items = weapons |
||
263 | self.win.vWeapons.itemsChanged() |
||
264 | if selected_type == "seq_wpn": |
||
265 | self.win.vWeapons.selectItem(selected) |
||
266 | else: |
||
267 | self.win.vWeapons.selectItem(None) |
||
268 | self.win.vEquipment.items = equipment |
||
269 | self.win.vEquipment.itemsChanged() |
||
270 | if selected_type == "seq_mod": |
||
271 | self.win.vEquipment.selectItem(selected) |
||
272 | else: |
||
273 | self.win.vEquipment.selectItem(None) |
||
274 | |||
275 | def _detailComputedAttributes(self, player, result): |
||
276 | if result: |
||
277 | hull = client.getTechInfo(result.hullID) |
||
278 | self.win.vAClass.text = _(gdata.shipClasses[result.combatClass]) |
||
279 | self.win.vASignature.text = _("%d") % result.signature |
||
280 | if result.speed == result.battleSpeed: |
||
281 | self.win.vSpeed.text = _("Speed") |
||
282 | self.win.vASpeed.text = _("%.2f") % result.speed |
||
283 | else: |
||
284 | self.win.vSpeed.text = _("Spd FTL (STL)") |
||
285 | self.win.vASpeed.text = _("%.2f (%.2f)") % (result.speed, result.battleSpeed) |
||
286 | self.win.vAHP.text = _("%d - %d") % (result.maxHP, result.shieldHP) if result.shieldHP > 0 else _("%d") % result.maxHP |
||
287 | self.win.vAAttack.text = _("%d") % result.combatAtt |
||
288 | self.win.vADefence.text = _("%d / %d") % (result.combatDef, result.missileDef) |
||
289 | self.win.vAPayload.text = _("%d") % (hull.maxWeight - result.weight) if getattr(hull, "maxWeight", None) else _("N/A") |
||
290 | self.win.vASlots.text = _("%d") % (hull.slots - result.slots) if hasattr(hull, "slots") else _("N/A") |
||
291 | self.win.vATanks.text = _("%d") % result.storEn |
||
292 | if result.speed > 0 and result.operEn > 0: |
||
293 | support = result.storEn / result.operEn |
||
294 | self.win.vARange.text = _("%.2f") % (support * result.speed / Rules.turnsPerDay) |
||
295 | else: |
||
296 | self.win.vARange.text = _("None") |
||
297 | self.win.vACCPts.text = _("%d") % result.buildProd |
||
298 | self.win.vACombatPwr.text = _("%d") % result.combatPwr |
||
299 | if self.highlightedDesignID and player.shipDesigns[self.highlightedDesignID].upgradeTo: |
||
300 | self.win.vAUpgrade.text = player.shipDesigns[player.shipDesigns[self.highlightedDesignID].upgradeTo].name |
||
301 | self.win.vAUpgrade.font = "normal-italic" |
||
302 | else: |
||
303 | self.win.vAUpgrade.text = _("N/A") |
||
304 | self.win.vAUpgrade.font = "normal" |
||
305 | else: |
||
306 | self.win.vAClass.text = _("N/A") |
||
307 | self.win.vASignature.text = _("N/A") |
||
308 | self.win.vASpeed.text = _("N/A") |
||
309 | self.win.vAHP.text = _("N/A") |
||
310 | self.win.vAAttack.text = _("N/A") |
||
311 | self.win.vADefence.text = _("N/A") |
||
312 | self.win.vAPayload.text = _("N/A") |
||
313 | self.win.vASlots.text = _("N/A") |
||
314 | self.win.vATanks.text = _("N/A") |
||
315 | self.win.vARange.text = _("N/A") |
||
316 | self.win.vACCPts.text = _("N/A") |
||
317 | self.win.vACombatPwr.text = _("N/A") |
||
318 | self.win.vAUpgrade.text = _("N/A") |
||
319 | |||
320 | def showDetails(self): |
||
321 | player = client.getPlayer() |
||
322 | self._setDetailButtons(player) |
||
323 | result = self._designRepresentation(player) |
||
324 | self._detailEquipmentLists() |
||
325 | self._detailComputedAttributes(player, result) |
||
326 | |||
327 | def onConstruct(self, widget, action, data): |
||
328 | name = self.win.vName.text |
||
329 | if not name: |
||
330 | self.win.setStatus(_("Enter name of the design.")) |
||
331 | return |
||
332 | # compute |
||
333 | player = client.getPlayer() |
||
334 | if self.ctrlID: |
||
335 | eqIDs = {self.ctrlID: 1} |
||
336 | else: |
||
337 | eqIDs = {} |
||
338 | for eqID in self.eqIDs: |
||
339 | if self.eqIDs[eqID]: |
||
340 | eqIDs[eqID] = self.eqIDs[eqID] |
||
341 | try: |
||
342 | self.win.setStatus(_("Executing ADD SHIP DESIGN command...")) |
||
343 | player = client.getPlayer() |
||
344 | player.shipDesigns, self.selectedDesignID = \ |
||
345 | client.cmdProxy.addShipDesign(player.oid, name, self.hullID, eqIDs) |
||
346 | self.win.vDuplDesign.enabled = 1 |
||
347 | self.win.setStatus(_('Command has been executed.')) |
||
348 | except GameException, e: |
||
349 | self.win.setStatus(_(e.args[0])) |
||
350 | return |
||
351 | self.editMode = False |
||
352 | self.update() |
||
353 | |||
354 | def onClose(self, widget, action, data): |
||
355 | self.editMode = False |
||
356 | self.hide() |
||
357 | |||
358 | def onSelectHull(self, widget, action, data): |
||
359 | if self.editMode: |
||
360 | self.selTechDlg.display('isShipHull', [], self.onHullSelected, self.hullID, self.hullID) |
||
361 | |||
362 | def onHullSelected(self, hullID): |
||
363 | self.hullID = hullID |
||
364 | self.showDetails() |
||
365 | |||
366 | def onSelectCtrl(self, widget, action, data): |
||
367 | if self.editMode: |
||
368 | self.selTechDlg.display('isShipEquip', ["seq_ctrl"], self.onCtrlSelected, self.ctrlID, self.hullID) |
||
369 | |||
370 | def onCtrlSelected(self, ctrlID): |
||
371 | self.ctrlID = ctrlID |
||
372 | self.showDetails() |
||
373 | |||
374 | def onAddEngine(self, widget, action, data): |
||
375 | self.selTechDlg.display('isShipEquip', ["seq_eng"], self.onEqSelected, hullID=self.hullID) |
||
376 | |||
377 | def onAddWeapon(self, widget, action, data): |
||
378 | self.selTechDlg.display('isShipEquip', ["seq_wpn"], self.onEqSelected, hullID=self.hullID) |
||
379 | |||
380 | def onAddEquipment(self, widget, action, data): |
||
381 | self.selTechDlg.display('isShipEquip', ["seq_mod", "seq_struct"], self.onEqSelected, hullID=self.hullID) |
||
382 | |||
383 | def onEqSelected(self, eqID): |
||
384 | self.eqIDs[eqID] = self.eqIDs.get(eqID, 0) + 1 |
||
385 | self.showDetails() |
||
386 | |||
387 | def onSelectDesign(self, widget, action, data): |
||
388 | item = self.win.vDesigns.selection[0] |
||
389 | self.editMode = False |
||
390 | self.selectedDesignID = self.highlightedDesignID = item.tDesignID |
||
391 | self.showDetails() |
||
392 | |||
393 | def onHighlightDesign(self, widget, action, data): |
||
394 | if self.editMode: |
||
395 | return |
||
396 | if data is None and not self.win.vDesigns.selection: |
||
397 | # unhighlight into non-selection |
||
398 | self.highlightedDesignID = None |
||
399 | self.win.vDuplDesign.enabled = 0 |
||
400 | self.showDetails() |
||
401 | return |
||
402 | if data is not None: |
||
403 | item = self.win.vDesigns.highlight |
||
404 | elif self.win.vDesigns.selection: |
||
405 | item = self.win.vDesigns.selection[0] |
||
406 | self.highlightedDesignID = item.tDesignID |
||
0 ignored issues
–
show
introduced
by
![]() |
|||
407 | self.showDetails() |
||
408 | |||
409 | def onNewDesign(self, widget, action, data): |
||
410 | self.selectedDesignID = self.highlightedDesignID = None |
||
411 | self.editMode = True |
||
412 | self.win.vDesigns.selectItem(None) |
||
413 | self.hullID = Const.OID_NONE |
||
414 | self.ctrlID = Const.OID_NONE |
||
415 | self.eqIDs = {} |
||
416 | self.win.vName.text = _(" ") |
||
417 | self.win.vDuplDesign.enabled = 0 |
||
418 | self.update() |
||
419 | |||
420 | def onDuplDesign(self, widget, action, data): |
||
421 | self.selectedDesignID = None |
||
422 | self.highlightedDesignID = None |
||
423 | self.editMode = True |
||
424 | self.win.vDesigns.selectItem(None) |
||
425 | self.win.vName.text = _(" ") |
||
426 | self.win.vDuplDesign.enabled = 0 |
||
427 | self.update() |
||
428 | |||
429 | def _getSelectedWidget(self): |
||
430 | widgets = [] |
||
431 | if self.win.vEngines.selection: |
||
432 | widgets.append(self.win.vEngines) |
||
433 | if self.win.vWeapons.selection: |
||
434 | widgets.append(self.win.vWeapons) |
||
435 | if self.win.vEquipment.selection: |
||
436 | widgets.append(self.win.vEquipment) |
||
437 | return widgets |
||
438 | |||
439 | def onEqSelectedInListInc(self, widget, action, data): |
||
440 | if self.editMode: |
||
441 | self._onEqSelectedInList(widget) |
||
442 | if not pygame.key.get_mods() & pygame.KMOD_SHIFT: |
||
443 | self._onChangeEquipmentQty(1) |
||
444 | else: |
||
445 | self._onChangeEquipmentQty(5) |
||
446 | |||
447 | def onEqSelectedInListDec(self, widget, action, data): |
||
448 | if self.editMode: |
||
449 | self._onEqSelectedInList(widget) |
||
450 | if not pygame.key.get_mods() & pygame.KMOD_SHIFT: |
||
451 | self._onChangeEquipmentQty(-1) |
||
452 | else: |
||
453 | self._onChangeEquipmentQty(-5) |
||
454 | |||
455 | def _onEqSelectedInList(self, widget): |
||
456 | for old_select_widget in self._getSelectedWidget(): |
||
457 | if old_select_widget is not widget: |
||
458 | old_select_widget.unselectAll() |
||
459 | self.selectedEqID = widget.selection[0].techID |
||
460 | |||
461 | def _onChangeEquipmentQty(self, delta): |
||
462 | for widget in self._getSelectedWidget(): |
||
463 | item = widget.selection[0] |
||
464 | eqID = item.techID |
||
465 | self.eqIDs[eqID] = max(self.eqIDs.get(eqID, 0) + delta, 0) |
||
466 | self.showDetails() |
||
467 | |||
468 | def onRemoveEquipment(self, widget, action, data): |
||
469 | if self.win.vEquipment.selection: |
||
470 | item = self.win.vEquipment.selection[0] |
||
471 | eqID = item.techID |
||
472 | del self.eqIDs[eqID] |
||
473 | self.showDetails() |
||
474 | |||
475 | def onScrap(self, widget, action, data): |
||
476 | # count number of ships using this design |
||
477 | count = 0 |
||
478 | for fleetID in client.getPlayer().fleets: |
||
479 | fleet = client.get(fleetID) |
||
480 | for designID, hp, shieldHP, exp in fleet.ships: |
||
481 | if designID == self.selectedDesignID: |
||
482 | count += 1 |
||
483 | self.confirmDlg.display(_('Deletion of this design dismantle %d ship(s). Are you sure to scrap it?') % count, |
||
484 | _('Yes'), |
||
485 | _('No'), |
||
486 | confirmAction=self.onScrapConfirmed, |
||
487 | agreementNeeded=count != 0) |
||
488 | |||
489 | def onScrapConfirmed(self): |
||
490 | self.win.vDuplDesign.enabled = 0 |
||
491 | try: |
||
492 | self.win.setStatus(_("Executing SCRAP SHIP DESIGN command...")) |
||
493 | player = client.getPlayer() |
||
494 | oldFleets = player.fleets |
||
495 | player.shipDesigns, player.fleets, player.stratRes, player.prodQueues = \ |
||
496 | client.cmdProxy.scrapShipDesign(player.oid, self.selectedDesignID) |
||
497 | self.selectedDesignID = None |
||
498 | self.win.setStatus(_('Command has been executed.')) |
||
499 | except GameException, e: |
||
500 | self.win.setStatus(_(e.args[0])) |
||
501 | return |
||
502 | # reread information about fleets and planets |
||
503 | oldFleets.extend(player.planets) |
||
504 | client.updateIDs(oldFleets) |
||
505 | |||
506 | gdata.mainGameDlg.update() |
||
507 | self.update() |
||
508 | |||
509 | def onUpgrade(self, widget, action, data): |
||
510 | player = client.getPlayer() |
||
511 | if player.shipDesigns[self.selectedDesignID].upgradeTo == 0: |
||
512 | # upgrade |
||
513 | self.upgradeDlg.display(self.selectedDesignID, self) |
||
514 | else: |
||
515 | # cancel upgrade |
||
516 | try: |
||
517 | self.win.setStatus(_("Executing CANCEL UPGRADE SHIP DESIGN command...")) |
||
518 | player.shipDesigns = \ |
||
519 | client.cmdProxy.cancelUpgradeShipDesign(player.oid, self.selectedDesignID) |
||
520 | self.win.setStatus(_('Command has been executed.')) |
||
521 | except GameException, e: |
||
522 | self.win.setStatus(_(e.args[0])) |
||
523 | return |
||
524 | self.update() |
||
525 | |||
526 | def createUI(self): |
||
527 | w, h = gdata.scrnSize |
||
528 | self.win = ui.Window(self.app, |
||
529 | modal=1, |
||
530 | escKeyClose=1, |
||
531 | titleOnly=w == 800 and h == 600, |
||
532 | movable=0, |
||
533 | title=_('Construction Centre'), |
||
534 | rect=ui.Rect((w - 800 - 4 * (w != 800)) / 2, |
||
535 | (h - 600 - 4 * (h != 600)) / 2, |
||
536 | 800 + 4 * (w != 800), |
||
537 | 580 + 4 * (h != 600)), |
||
538 | layoutManager=ui.SimpleGridLM()) |
||
539 | self.win.subscribeAction('*', self) |
||
540 | # player listing |
||
541 | ui.Title(self.win, layout=(0, 0, 15, 1), text=_('Ship Designs'), |
||
542 | font='normal-bold', align=ui.ALIGN_W) |
||
543 | ui.Listbox(self.win, layout=(0, 1, 15, 25), id='vDesigns', |
||
544 | columns=((_('#'), 'tNumber', 2, ui.ALIGN_E), |
||
545 | (_('B'), 'tInBuild', 2, ui.ALIGN_E), |
||
546 | (_('Name'), 'text', 8, ui.ALIGN_W), |
||
547 | (_('Class'), 'tClass', 2, ui.ALIGN_W)), |
||
548 | columnLabels=1, |
||
549 | action="onSelectDesign", |
||
550 | hoverAction="onHighlightDesign") |
||
551 | ui.Button(self.win, layout=(0, 26, 7, 1), text=_("New design"), |
||
552 | action="onNewDesign") |
||
553 | ui.Button(self.win, layout=(7, 26, 7, 1), text=_("Dupl. design"), |
||
554 | action="onDuplDesign", enabled=0, id="vDuplDesign") |
||
555 | # current design |
||
556 | ui.Title(self.win, layout=(15, 0, 25, 1), text=_('Design'), |
||
557 | font='normal-bold', align=ui.ALIGN_W) |
||
558 | # info |
||
559 | ui.Label(self.win, layout=(15, 1, 5, 1), text=_("Name"), |
||
560 | align=ui.ALIGN_W) |
||
561 | ui.Entry(self.win, layout=(20, 1, 10, 1), id="vName", |
||
562 | align=ui.ALIGN_E) |
||
563 | ui.Label(self.win, layout=(15, 2, 5, 1), text=_("Hull type"), |
||
564 | align=ui.ALIGN_W) |
||
565 | ui.ActiveLabel(self.win, layout=(20, 2, 10, 1), id="vHull", |
||
566 | align=ui.ALIGN_E, action="onSelectHull") |
||
567 | ui.Label(self.win, layout=(15, 3, 5, 1), text=_("Control unit"), |
||
568 | align=ui.ALIGN_W) |
||
569 | ui.ActiveLabel(self.win, layout=(20, 3, 10, 1), id="vCtrl", |
||
570 | align=ui.ALIGN_E, action="onSelectCtrl") |
||
571 | ui.Button(self.win, layout=(15, 4, 6, 1), text=_('Engines'), |
||
572 | id="vEnginesButton", font='normal-bold', action="onAddEngine") |
||
573 | ui.Title(self.win, layout=(21, 4, 19, 1),) |
||
574 | ui.Listbox(self.win, layout=(15, 5, 25, 3), id='vEngines', |
||
575 | columns=((_('#'), 'tNumber', 2, ui.ALIGN_E), |
||
576 | (_('Name'), 'text', 8, ui.ALIGN_W), |
||
577 | (_('Data'), 'tData', 14, ui.ALIGN_W)), |
||
578 | columnLabels=0, |
||
579 | action="onEqSelectedInListInc", |
||
580 | rmbAction="onEqSelectedInListDec") |
||
581 | ui.Button(self.win, layout=(15, 8, 6, 1), text=_('Weapons'), |
||
582 | id="vWeaponsButton", font='normal-bold', action="onAddWeapon") |
||
583 | ui.Title(self.win, layout=(21, 8, 19, 1),) |
||
584 | ui.Listbox(self.win, layout=(15, 9, 25, 4), id='vWeapons', |
||
585 | columns=((_('#'), 'tNumber', 2, ui.ALIGN_E), |
||
586 | (_('Name'), 'text', 8, ui.ALIGN_W), |
||
587 | (_('Data'), 'tData', 14, ui.ALIGN_W)), |
||
588 | columnLabels=0, |
||
589 | action="onEqSelectedInListInc", |
||
590 | rmbAction="onEqSelectedInListDec") |
||
591 | ui.Button(self.win, layout=(15, 13, 6, 1), text=_('Equipment'), |
||
592 | id="vEquipmentButton", font='normal-bold', action="onAddEquipment") |
||
593 | ui.Title(self.win, layout=(21, 13, 19, 1),) |
||
594 | ui.Listbox(self.win, layout=(15, 14, 25, 5), id='vEquipment', |
||
595 | columns=((_('#'), 'tNumber', 2, ui.ALIGN_E), |
||
596 | (_('Name'), 'text', 8, ui.ALIGN_W), |
||
597 | (_('Data'), 'tData', 14, ui.ALIGN_W)), |
||
598 | columnLabels=0, |
||
599 | action="onEqSelectedInListInc", |
||
600 | rmbAction="onEqSelectedInListDec") |
||
601 | |||
602 | ui.Button(self.win, layout=(15, 19, 6, 1), text=_("Upgrade to"), |
||
603 | id="vUpgrade", font='normal-bold', action="onUpgrade") |
||
604 | ui.Label(self.win, layout=(21, 19, 6, 1), id="vAUpgrade", align=ui.ALIGN_E) |
||
605 | ui.Title(self.win, layout=(27.5, 19, 12.5, 1)) |
||
606 | |||
607 | # ship's attrs |
||
608 | ui.Label(self.win, layout=(30.5, 1, 4.5, 1), text=_("Class"), align=ui.ALIGN_W) |
||
609 | ui.Label(self.win, layout=(35, 1, 4.75, 1), id="vAClass", align=ui.ALIGN_E) |
||
610 | ui.Label(self.win, layout=(30.5, 2, 6.5, 1), text=_("Free slots"), align=ui.ALIGN_W) |
||
611 | ui.Label(self.win, layout=(37, 2, 2.75, 1), id="vASlots", align=ui.ALIGN_E) |
||
612 | ui.Label(self.win, layout=(30.5, 3, 6.5, 1), text=_("Unused payload"), align=ui.ALIGN_W) |
||
613 | ui.Label(self.win, layout=(37, 3, 2.75, 1), id="vAPayload", align=ui.ALIGN_E) |
||
614 | |||
615 | ui.Label(self.win, layout=(17, 21, 4, 1), text=_("HP"), align=ui.ALIGN_W) |
||
616 | ui.Label(self.win, layout=(21, 21, 5, 1), id="vAHP", align=ui.ALIGN_E) |
||
617 | ui.Label(self.win, layout=(17, 22, 4, 1), text=_("Base attack"), align=ui.ALIGN_W) |
||
618 | ui.Label(self.win, layout=(21, 22, 5, 1), id="vAAttack", align=ui.ALIGN_E) |
||
619 | ui.Label(self.win, layout=(17, 23, 3, 1), text=_("Base defence"), align=ui.ALIGN_W) |
||
620 | ui.Label(self.win, layout=(20, 23, 6, 1), id="vADefence", align=ui.ALIGN_E) |
||
621 | ui.Label(self.win, layout=(17, 24, 5, 1), text=_("Military power"), align=ui.ALIGN_W) |
||
622 | ui.Label(self.win, layout=(22, 24, 4, 1), id="vACombatPwr", align=ui.ALIGN_E) |
||
623 | |||
624 | ui.Label(self.win, layout=(28, 20, 5, 1), text=_("Signature"), align=ui.ALIGN_W) |
||
625 | ui.Label(self.win, layout=(33, 20, 5, 1), id="vASignature", align=ui.ALIGN_E) |
||
626 | ui.Label(self.win, layout=(28, 21, 5, 1), id="vSpeed", text=_("Speed"), align=ui.ALIGN_W) |
||
627 | ui.Label(self.win, layout=(34, 21, 5, 1), id="vASpeed", align=ui.ALIGN_E) |
||
628 | ui.Label(self.win, layout=(28, 22, 5, 1), text=_("Tanks"), align=ui.ALIGN_W) |
||
629 | ui.Label(self.win, layout=(33, 22, 5, 1), id="vATanks", align=ui.ALIGN_E) |
||
630 | ui.Label(self.win, layout=(28, 23, 5, 1), text=_("Max. range"), align=ui.ALIGN_W) |
||
631 | ui.Label(self.win, layout=(33, 23, 5, 1), id="vARange", align=ui.ALIGN_E) |
||
632 | ui.Label(self.win, layout=(28, 24, 5, 1), text=_("Constr. pts"), align=ui.ALIGN_W) |
||
633 | ui.Label(self.win, layout=(33, 24, 5, 1), font='normal-bold', id="vACCPts", align=ui.ALIGN_E) |
||
634 | |||
635 | # actions |
||
636 | ui.Title(self.win, layout=(15, 25, 25, 1)) |
||
637 | ui.Button(self.win, layout=(15, 26, 5, 1), text=_("Scrap"), |
||
638 | id="vScrap", action="onScrap") |
||
639 | ui.Button(self.win, layout=(35, 26, 5, 1), text=_("Construct"), |
||
640 | id="vConstruct", action="onConstruct", enabled=0) |
||
641 | # status bar + submit/cancel |
||
642 | ui.TitleButton(self.win, layout=(35, 27, 5, 1), text=_('Close'), action='onClose') |
||
643 | ui.Title(self.win, id='vStatusBar', layout=(0, 27, 35, 1), align=ui.ALIGN_W) |
||
644 |