So, ich habe eine Lösung gefunden.
So, ich habe eine Lösung gefunden.
That's why I am here: Mein Mod
Mehr Technologien, mehr Einheiten, mehr Zivilisationen, mehr Gebäude
Die aktuelle Story zum Mod:
Die Vereinigten Staaten von Amerika
Alte Stories zu alten Versionen:
Alte Storys
Und schon wieder habe ich ein Rätsel bei Python.
Ich habe diesen Code erstellt und auch beinahe erfolgreich getestet:
Seltsamerweise wird allerdings der grüne Teil (eventuell auch der dahinter mit den Gebäuden) in jeder der Städte, die im Testszenario zurückgegeben wurden, dreimal durchlaufen (bei insgesamt 4 zurückgegebenen Städten). Dadurch entstehen 3x soviele kostenlose Einheiten wie geplant. Einen zweiten Durchlauf könnte ich mir sogar noch erklären: Erst erhält der Spieler seine Städte zurück, und dann, als er selbst an der Reihe ist, bekommt er sie noch einmal zurückgegeben. Aber wo liegt mein Denkfehler, dass er sie ein drittes Mal erhält?Code:###Restauration beginn### elif iTechType == gc.getInfoTypeForString("TECH_REACTION"): if (gc.getGame().isOption(gc.getInfoTypeForString("GAMEOPTION_SPAWN_NEW_CIVS"))): DeadCivArray = [] ReturnPlayerID =-1 for iPlayer in range(gc.getMAX_PLAYERS()): pDeadPlayer = gc.getPlayer(iPlayer) if (pDeadPlayer.isEverAlive() ): if (not pDeadPlayer.isAlive() ): DeadCivArray.append(iPlayer) if len(DeadCivArray ) > 0: iMeineZufallszahl = CyGame().getSorenRandNum(len(DeadCivArray), 'IllBeBack') iReturnPlayerID=DeadCivArray[iMeineZufallszahl] if (iReturnPlayerID != -1): pReturnEmpire = gc.getPlayer(iReturnPlayerID ) iReturnTeam = pReturnEmpire.getTeam () pReturnTeam = gc.getTeam(iReturnTeam) for iPlayer2 in range(gc.getMAX_PLAYERS()): pPlayer2 = gc.getPlayer(iPlayer2) if(pPlayer2.getTeam() != iReturnTeam ): if (not gc.getTeam(pPlayer2.getTeam()).isBarbarian() ): gc.getTeam(pPlayer2.getTeam()).makePeace(iReturnTeam) (loopCity, iter) = pPlayer2.firstCity(True) while(loopCity): if not (loopCity.isCapital()): if (loopCity.getOriginalOwner() == iReturnPlayerID): iCityX = loopCity.getX() iCityY = loopCity.getY() pReturnEmpire.acquireCity(loopCity,False,True) ###init Units for i in range(6): Defender = loopCity.getConscriptUnit () pReturnEmpire.initUnit( Defender, iCityX,iCityY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH ) pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_KARABINIERS"), iCityX,iCityY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH ) for i in range(3): pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_FIELD_CANNON"), iCityX,iCityY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH ) pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_WORKER"), iCityX,iCityY, UnitAITypes.UNITAI_WORKER, DirectionTypes.DIRECTION_NORTH ) pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_BASTION"), iCityX,iCityY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH ) pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_CANNON"), iCityX,iCityY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH ) pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_GARDEINFANTERY"), iCityX,iCityY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH ) pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_COASTALFORTRESS"), iCityX,iCityY, UnitAITypes.UNITAI_RANGED_ATTACK, DirectionTypes.DIRECTION_NORTH ) pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_AUFKLAERER"), iCityX,iCityY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH ) pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_BALLON"), iCityX,iCityY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH ) pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_STAR_FORT"), iCityX,iCityY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH ) if loopCity.isCoastal(20): for i in range(3): pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_MISSILE_SHIP"), iCityX,iCityY, UnitAITypes.UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH ) pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_WORKBOAT"), iCityX,iCityY, UnitAITypes.UNITAI_WORKER_SEA, DirectionTypes.DIRECTION_NORTH ) pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_GALIOT_A_BOMBE"), iCityX,iCityY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH ) pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_BRIGG"), iCityX,iCityY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH ) pReturnEmpire.initUnit( gc.getInfoTypeForString("UNIT_DREIDECKER"), iCityX,iCityY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH ) ###init Units ###init Gebäude und Kultur iExtraCulture = loopCity.getCulture(iPlayer2 )/2 loopCity.changeCulture(iReturnPlayerID,iExtraCulture,1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_BEWAESSERUNG"),1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_GRANARY"),1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_STABLE"),1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_MARKET"),1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_BARRACKS"),1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_TRAINING"),1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_LIBRARY"),1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_WAFFENKAMMER"),1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_LAZARETT"),1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_HARBOR"),1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_SCHOOL"),1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_JAIL"),1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_TOWN_CENTER"),1) loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_FORGE"),1) ###init Gebäude und Kultur (loopCity, iter) = pPlayer2.nextCity(iter, true) ###Basisbeförderungen Einheiten (loopUnit, iter) = pReturnEmpire.firstUnit(true) while(loopUnit): loopUnit.changeExperience(7,12,false,false,false) if (loopUnit.getDomainType() == gc.getInfoTypeForString("DOMAIN_SEA")): loopUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_BREITSEITE1"),1) loopUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_COMBAT1"),1) loopUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_COASTGUARD1"),1) elif (loopUnit.getDomainType() == gc.getInfoTypeForString("DOMAIN_IMMOBILE")): loopUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_CITY_GARRISON1"),1) loopUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_DRILL1"),1) # elif (loopUnit.getDomainType() == gc.getInfoTypeForString("DOMAIN_AIR")): # loopUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_COMBAT1"),1) else: loopUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_CITY_RAIDER1"),1) loopUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_PINCH1"),1) loopUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_REITERFALLE1"),1) loopUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_CITY_GARRISON1"),1) loopUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_COMBAT1"),1) (loopUnit, iter) = (pReturnEmpire.nextUnit(iter, true)) ###Basisbeförderungen Einheiten for iPlayer in range(gc.getMAX_PLAYERS()): if gc.getPlayer(iPlayer).isHuman(): popup = PyPopup.PyPopup(-1) popup.setHeaderString(CyTranslator().getText("TXT_KEY_HEADER_RESTAURATION",(-1,-1))) popup.setBodyString(CyTranslator().getText("TXT_KEY_MESSAGE_RESTAURATION",(pReturnEmpire.getCivilizationDescription(0),pReturnEmpire.getCivilizationDescription(0)))) popup.launch(True, PopupStates.POPUPSTATE_IMMEDIATE) ## ###Restauration end###
That's why I am here: Mein Mod
Mehr Technologien, mehr Einheiten, mehr Zivilisationen, mehr Gebäude
Die aktuelle Story zum Mod:
Die Vereinigten Staaten von Amerika
Alte Stories zu alten Versionen:
Alte Storys
Bei dem beschriebenen Problem ist der Code selbst nicht ausreichend. Wissen, wo dieser steht und wann dieser aufgerufen wird, ist genauso wichtig.
Gut, besser, BASE. BASE ist eine Modifikation für Civilization IV: Beyond the Sword, die wie eine größere Erweiterung nah am Originalspiel verbleiben soll.
Habe ich tatsächlich vergessen:
Und dabei habe ich etwas möglicherweise wichtiges gesehen:Code:def onTechAcquired(self, argsList): 'Tech Acquired' iTechType, iTeam, iPlayer, bAnnounce = argsList
Eventuell wird dadurch der Code noch einmal aufgerufen, wenn nämlich der zurückkehrende Spieler die Technologie erhält - weil er sie bei der "Eroberung" einer Stadt miterobert. Das muss ich erstmal testen.Code:isTeamFirst = True iTeam = pPlayer.getTeam() iMaxTeams = gc.getMAX_CIV_TEAMS () for i in range(iMaxTeams): if i == iTeam:continue pCurTeam = gc.getTeam(i) if pCurTeam.isHasTech(iTechType): isTeamFirst = False break
That's why I am here: Mein Mod
Mehr Technologien, mehr Einheiten, mehr Zivilisationen, mehr Gebäude
Die aktuelle Story zum Mod:
Die Vereinigten Staaten von Amerika
Alte Stories zu alten Versionen:
Alte Storys
Das scheint zumindest Auswirkungen gehabt zu haben, jedenfalls erhält der Spieler nach meinen Änderungen nur noch die einfache Anzahl an Einheiten.
That's why I am here: Mein Mod
Mehr Technologien, mehr Einheiten, mehr Zivilisationen, mehr Gebäude
Die aktuelle Story zum Mod:
Die Vereinigten Staaten von Amerika
Alte Stories zu alten Versionen:
Alte Storys
Ich habe eine Frage an die python-Profis out there.
Ich habe ein Scroll-Label und wollte da nun etliche Labels einbauen (Button- und Textlabels). Es sieht grafisch ok aus, aber die Dinger sind nicht im Scrolllabel drin und ich kanns nicht scrollen. Geht das nicht, wenn man mehrere Labels in ein Scrolllabel gibt?
PHP-Code:
# scroll panel for cities
screen.addScrollPanel("ScrollPanelCities", u"", self.X_CITIES, self.Y_CITIES-16, self.W_CITIES, self.H_CITIES-10, PanelStyles.PANEL_STYLE_EXTERNAL)
screen.setActivation("ScrollPanelCities", ActivationTypes.ACTIVATE_NORMAL)
# City status (button)
buttonCityStatus = self.getButtonCityStatus(loopCity)
#screen.setImageButton(self.getNextWidgetName(), buttonCityStatus, iX, iY, BUTTON_SIZE, BUTTON_SIZE, WidgetTypes.WIDGET_GENERAL, 1, loopCity.getID())
screen.addCheckBoxGFCAt("ScrollPanelCities", self.getNextWidgetName(), buttonCityStatus, "",
iX, iY, BUTTON_SIZE, BUTTON_SIZE, WidgetTypes.WIDGET_GENERAL, iPlayer, loopCity.getID(), ButtonStyles.BUTTON_STYLE_LABEL, False)
iX += BUTTON_SIZE + 2
# City name
szText = self.getCityName(loopCity)
#screen.setLabel(self.getNextWidgetName(), "Background", u"<font=3>" + szText + u"</font>", CvUtil.FONT_LEFT_JUSTIFY, iX, iY+2, 0.0, FontTypes.GAME_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
screen.setLabelAt(self.getNextWidgetName(), "ScrollPanelCities", u"<font=3>" + szText + u"</font>", CvUtil.FONT_LEFT_JUSTIFY, iX, iY+2, 0.0, FontTypes.GAME_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
# City properties
szText = self.getCityProperties(loopCity)
#screen.setLabel(self.getNextWidgetName(), "Background", u"<font=3>" + szText + u"</font>", CvUtil.FONT_LEFT_JUSTIFY, iX, iY+21, 0.0, FontTypes.GAME_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
screen.setLabelAt(self.getNextWidgetName(), "ScrollPanelCities", u"<font=3>" + szText + u"</font>", CvUtil.FONT_LEFT_JUSTIFY, iX, iY+22, 0.0, FontTypes.GAME_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
Pie's Ancient Europe (PAE)
Erlebe mit dieser CIV IV Mod(ifikation) hautnah das Zeitalter der Antike bis ins allerletzte Detail!
Mit bahnbrechenden Erweiterungen und vielen ein- und erstmaligen Features, die Spaß machen. Hand drauf!
- Pie's Ancient Europe (VII)
... im Übrigen bin ich der Meinung, dass Karthago wieder aufgebaut werden soll ...
Edit: Kommando retour. Die Höhen-Einstellungen bei normalen Labeln und Scroll-Label sind derart different.... mein Scrollbalken war viel zu weit unten, also aus dem Sichtbereich und wurde nicht angezeigt.... Es funktioniert eh! Sorry.....
Edit2: ups, diese letzen 2 Posts gehören eigentlich in den Pythonthread. sorry.
Geändert von Pie (24. Februar 2025 um 00:34 Uhr)
Pie's Ancient Europe (PAE)
Erlebe mit dieser CIV IV Mod(ifikation) hautnah das Zeitalter der Antike bis ins allerletzte Detail!
Mit bahnbrechenden Erweiterungen und vielen ein- und erstmaligen Features, die Spaß machen. Hand drauf!
- Pie's Ancient Europe (VII)
... im Übrigen bin ich der Meinung, dass Karthago wieder aufgebaut werden soll ...
Ich komme da grad nicht weiter:
Ich habe ein Berater-Fenster, welches aus 2 Unterseiten besteht (Händler und Nachbarstädte). Beim Öffnen wird ganz normal der Inhalt vom ersten Fenster gezeigt (Händler).
Wenn ich unten aber auf Nachbarstädte klicke, zeigt es mir ein leeres Fenster. Der Inhalt wird nicht geladen.
Wenn ich die Datei von außen ändere und speichere und es ingame zu einem "Reload python" kommt, dann geht der Nachbarstädte-Link und ich kann den Inhalt sehen.
Wie das? Wie bekomme ich es hin, dass mir der Inhalt vom 2. Fenster ganz regulär angezeigt wird?
anbei die py-Datei dafür.... könnt ihr leider nicht ingame testen, weil es dafür keine Zuweisungen in BTS gibt und überhaupt alles PAE-spezifisch ist. aber vielleicht seht ihr ja den Fehler im Code.
Pie's Ancient Europe (PAE)
Erlebe mit dieser CIV IV Mod(ifikation) hautnah das Zeitalter der Antike bis ins allerletzte Detail!
Mit bahnbrechenden Erweiterungen und vielen ein- und erstmaligen Features, die Spaß machen. Hand drauf!
- Pie's Ancient Europe (VII)
... im Übrigen bin ich der Meinung, dass Karthago wieder aufgebaut werden soll ...
Könnte es der Aufruf von drawCities in Zeile 518 sein? Der sieht zumindest so aus als wenn er in der Eventloop aber nicht beim Reload aufgerufen wird.
Und beginnt mit self.deleteAllWidgets()
Pie's Ancient Europe (PAE)
Erlebe mit dieser CIV IV Mod(ifikation) hautnah das Zeitalter der Antike bis ins allerletzte Detail!
Mit bahnbrechenden Erweiterungen und vielen ein- und erstmaligen Features, die Spaß machen. Hand drauf!
- Pie's Ancient Europe (VII)
... im Übrigen bin ich der Meinung, dass Karthago wieder aufgebaut werden soll ...
Das Hauptproblem hängt mit self.iActivePlayer zusammen. Die Variable wird bei dir nur in __init__ gesetzt und ist zu dem Zeitpunkt noch -1.
Das if-Statement in drawTAB2 war daher dann ein Workaround/Folgefehler
Weiterhin (habe den Hintergrund vom Screen nicht zeinchen lassen) ist mir noch aufgefallen, dass Tab1 immer noch vorhanden ist, wenn man Tab2 zeichnen lässt, weil keine .hide()-Calls für die Elemente enthalten sind.Code:def drawTAB2(self): #if (self.iActivePlayer < 0): return # Ändern zu => if (self.iActivePlayer < 0): self.iActivePlayer = CyGame().getActivePlayer()
Ist hier kein Problem, und tritt glaube ich auch bei anderen Screens auf, aber ich wollte es mal erwähnen.
aber wofür dann der __init__ wenn das dann beim Klick wieder -1 ist? Aber egal, ich muss das eh nicht verstehen... ich probier das mal und sag Bescheid.
wegen den hide() calls. Ja, das hab ich bei anderen Fenstern auch bemerkt. Manchmal wirds gemacht, manchmal nicht. Da haben wohl verschiedene firaxis-Programmierer verschiedene Fenster gemacht. wenn hide() sauberer ist... obwohl, dann brauchts ja wenigstens kein reload von TAB1... ändert sich ja eh nix, wenn man hin und herschaltet... oder? kann ich das also so lassen deiner Meinung nach? Oder geht das Runde für Runde versteckt im Hintergrund mit?
Pie's Ancient Europe (PAE)
Erlebe mit dieser CIV IV Mod(ifikation) hautnah das Zeitalter der Antike bis ins allerletzte Detail!
Mit bahnbrechenden Erweiterungen und vielen ein- und erstmaligen Features, die Spaß machen. Hand drauf!
- Pie's Ancient Europe (VII)
... im Übrigen bin ich der Meinung, dass Karthago wieder aufgebaut werden soll ...
Es ist nicht wieder -1 sondern die __init__ wird nur beim Spielstart einmalig aufgerufen. Du musst die iActivePlayer daher nach dem Laden des Spielstandes setzen.
Ah! ok und wenn ich die iAcitvePlayer vorher außerhalb von __init__ definiere? Würd mir dann die Kontrolle in drawTAB2 erspart bleiben?
EDIT:
DANKE Ramk! Jetzt gehts!
Wie ist es denn die sauberste Lösung? So wie jetzt oder wirklich eine globale iActivePlayer Variable?
Geändert von Pie (24. Februar 2025 um 17:16 Uhr)
Pie's Ancient Europe (PAE)
Erlebe mit dieser CIV IV Mod(ifikation) hautnah das Zeitalter der Antike bis ins allerletzte Detail!
Mit bahnbrechenden Erweiterungen und vielen ein- und erstmaligen Features, die Spaß machen. Hand drauf!
- Pie's Ancient Europe (VII)
... im Übrigen bin ich der Meinung, dass Karthago wieder aufgebaut werden soll ...
Wenn man mehrere Dinge hat, die man nicht in __init_ definieren kann würde ich eine init()-Methode definieren, die dann einmalig beim ersten Zugriff auf den Screen aufgerufen wird.
Hier würde ich nichts anders machen als du und beim ersten Zugriff auf die Variable den Defautwert setzen.
Kannst du noch testen ob die Variablenzuweisung in __init__ (erneut) aufgerufen wird, wenn man einen anderen Spielstand läd? Das wäre dann offensichtlich auch ein Vorteil gegenüber einer globalen Variable.
Ich habe in Erinnerung, dass die Variablen für die Fx-Screens gerne mal bestehen bleiben, wenn man einen anderen Spielstand läd.