Ergebnis 1 bis 3 von 3

Thema: Globale Erwärmung

  1. #1
    Antiker Benutzer Avatar von BoggyB
    Registriert seit
    21.08.11
    Beiträge
    7.040

    Globale Erwärmung

    Aus gegebenem Anlass hab ich mir mal angesehen, wie genau globale Erwärmung in Civ IV 3.19 eigentlich funktioniert, und da ich das nun sowieso getan habe, kann ich es auch hier niederschreiben.
    Zunächst einmal sind hier für alle, die das interessiert, der Code und die relevanten Parameter (in GlobalDefines.xml):

    Achtung Spoiler:
    PHP-Code:
    void CvGame::doGlobalWarming()
    {
        
    int iGlobalWarmingDefense 0;
        for (
    int i 0GC.getMapINLINE().numPlotsINLINE(); ++i)
        {
            
    CvPlotpPlot GC.getMapINLINE().plotByIndexINLINE(i);

            if (!
    pPlot->isWater())
            {
                if (
    pPlot->getFeatureType() != NO_FEATURE)
                {
                    if (
    GC.getFeatureInfo(pPlot->getFeatureType()).getGrowthProbability() > 0// hack, but we don't want to add new XML field in the patch just for this
                    
    {
                        ++
    iGlobalWarmingDefense;
                    }
                }
            }
        }
        
    iGlobalWarmingDefense iGlobalWarmingDefense GC.getDefineINT("GLOBAL_WARMING_FOREST") / std::max(1GC.getMapINLINE().getLandPlots());

        
    int iUnhealthWeight GC.getDefineINT("GLOBAL_WARMING_UNHEALTH_WEIGHT");
        
    int iGlobalWarmingValue 0;
        for (
    int iPlayer 0iPlayer MAX_PLAYERS; ++iPlayer)
        {
            
    CvPlayerkPlayer GET_PLAYER((PlayerTypesiPlayer);
            if (
    kPlayer.isAlive())
            {
                
    int iLoop;
                for (
    CvCitypCity kPlayer.firstCity(&iLoop); pCity != NULLpCity kPlayer.nextCity(&iLoop))
                {
                    
    iGlobalWarmingValue -= pCity->getBuildingBadHealth() * iUnhealthWeight;
                }
            }
        }
        
    iGlobalWarmingValue /= GC.getMapINLINE().numPlotsINLINE();

        
    iGlobalWarmingValue += getNukesExploded() * GC.getDefineINT("GLOBAL_WARMING_NUKE_WEIGHT") / 100;

        
    TerrainTypes eWarmingTerrain = ((TerrainTypes)(GC.getDefineINT("GLOBAL_WARMING_TERRAIN")));

        for (
    int iI 0iI iGlobalWarmingValueiI++)
        {
            if (
    getSorenRandNum(100"Global Warming") + iGlobalWarmingDefense GC.getDefineINT("GLOBAL_WARMING_PROB"))
            {
                
    CvPlotpPlot GC.getMapINLINE().syncRandPlot(RANDPLOT_LAND RANDPLOT_NOT_CITY);

                if (
    pPlot != NULL)
                {
                    
    bool bChanged false;

                    if (
    pPlot->getFeatureType() != NO_FEATURE)
                    {
                        if (
    pPlot->getFeatureType() != GC.getDefineINT("NUKE_FEATURE"))
                        {
                            
    pPlot->setFeatureType(NO_FEATURE);
                            
    bChanged true;
                        }
                    }
                    else if (
    pPlot->getTerrainType() != eWarmingTerrain)
                    {
                        if (
    pPlot->calculateTotalBestNatureYield(NO_TEAM) > 1)
                        {
                            
    pPlot->setTerrainType(eWarmingTerrain);
                            
    bChanged true;
                        }
                    }

                    if (
    bChanged)
                    {
                        
    pPlot->setImprovementType(NO_IMPROVEMENT);

                        
    CvCitypCity GC.getMapINLINE().findCity(pPlot->getX_INLINE(), pPlot->getY_INLINE());
                        if (
    pCity != NULL)
                        {
                            if (
    pPlot->isVisible(pCity->getTeam(), false))
                            {
                                
    CvWString szBuffer gDLL->getText("TXT_KEY_MISC_GLOBAL_WARMING_NEAR_CITY"pCity->getNameKey());
                                
    gDLL->getInterfaceIFace()->addMessage(pCity->getOwnerINLINE(), falseGC.getEVENT_MESSAGE_TIME(), szBuffer"AS2D_GLOBALWARMING"MESSAGE_TYPE_INFONULL, (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE(), truetrue);
                            }
                        }
                    }
                }
            }
        }

    Code:
    	<Define>
    		<DefineName>NUKE_FEATURE</DefineName>
    		<DefineTextVal>FEATURE_FALLOUT</DefineTextVal>
    	</Define>
    	<Define>
    		<DefineName>GLOBAL_WARMING_TERRAIN</DefineName>
    		<DefineTextVal>TERRAIN_DESERT</DefineTextVal>
    	</Define>
    [...]
    	<Define>
    		<DefineName>GLOBAL_WARMING_PROB</DefineName>
    		<iDefineIntVal>20</iDefineIntVal>
    	</Define>
    	<Define>
    		<DefineName>GLOBAL_WARMING_FOREST</DefineName>
    		<iDefineIntVal>50</iDefineIntVal>
    	</Define>
    	<Define>
    		<DefineName>GLOBAL_WARMING_UNHEALTH_WEIGHT</DefineName>
    		<iDefineIntVal>20</iDefineIntVal>
    	</Define>
    	<Define>
    		<DefineName>GLOBAL_WARMING_NUKE_WEIGHT</DefineName>
    		<iDefineIntVal>50</iDefineIntVal>
    	</Define>


    Insgesamt werden zwei Werte bestimmt, die für den Spieler interessant sind: Zum einen die maximale Anzahl der Felder, auf denen in einer Runde globale Erwärmung auftreten kann, zum anderen die Wahrscheinlichkeit, mit der sie auf einem Feld auftritt.

    Anzahl der Felder

    Es gilt:

    Code:
    NUM_FELDER = (GLOBAL_BUILDING_UNHEALTH * GLOBAL_WARMING_UNHEALTH_WEIGHT / TOTAL_NUM_PLOTS) + (NUM_NUKES * GLOBAL_WARMING_NUKE_WEIGHT) / 100
    GLOBAL_BUILDING_UNHEALTH Die Summe aller in allen Städten aller Spieler durch Gebäude erzeugten . Durch Bevölkerung erzeugte und irgendwie erzeugte spielen keine Rolle, Recycling-Anlagen negieren die .
    GLOBAL_WARMING_UNHEALTH_WEIGHT Entsprechender Wert in GlobalDefines.xml (ungemoddet 20).
    TOTAL_NUM_PLOTS Die Anzahl von Geländefeldern auf der Karte (auch Wasser).
    NUM_NUKES Die Anzahl aller von allen Spielern abgefeuerten ICBMs und Taktischen Nuklearwaffen. Kernschmelzen in Kernkraftwerken zählen ebenso als eine Nuke.
    GLOBAL_WARMING_NUKE_WEIGHT Entsprechender Wert in GlobalDefines.xml (ungemoddet 50).

    Ungemoddet gilt also:

    Code:
    NUM_FELDER = (GLOBAL_BUILDING_UNHEALTH * 20 / TOTAL_NUM_PLOTS) + NUM_NUKES / 2
    Es werden dann vom Spiel NUM_FELDER zufällige Landfelder, auf denen keine Stadt stehen darf, ausgewählt und auf jedem kann mit der unten berechneten Wahrscheinlichkeit globale Erwärmung vorkommen. Die Anzahl in einer Runde betroffener Felder liegt also immer zwischen (einschließlich) 0 und NUM_FELDER.

    Für Modder

    Es geht eigentlich bereits aus der Formel hervor, aber mit den Werten GLOBAL_WARMING_UNHEALTH_WEIGHT und GLOBAL_WARMING_NUKE_WEIGHT lässt sich gewichten, wie stark Gebäudekrankheit und Nukes die globale Erwärmung beeinflussen. Setzt man beide Werte auf 0, ist die globale Erwärmung komplett deaktiviert (man kann aber genauso gut GLOBAL_WARMING_PROB auf 0 setzen, siehe unten).

    Die Wahrscheinlichkeit

    Auch hier erst mal die Formel:

    Code:
    P (in %) = GLOBAL_WARMING_PROB - (TOTAL_NUM_FORESTS * GLOBAL_WARMING_FOREST / TOTAL_NUM_LAND_PLOTS)
    GLOBAL_WARMING_PROB Entsprechender Wert in GlobalDefines.xml (ungemoddet 20).
    TOTAL_NUM_FORESTS Die Anzahl von Wäldern und Dschungeln auf der gesamten Karte.
    GLOBAL_WARMING_FOREST Entsprechender Wert in GlobalDefines.xml (ungemoddet 20).
    TOTAL_NUM_LAND_PLOTS Die Anzahl von Landfeldern auf der Karte.

    Ungemoddet also:

    Code:
    P (in %) = 20 - (TOTAL_NUM_FORESTS * 50 / TOTAL_NUM_LAND_PLOTS)
    (TOTAL_NUM_FORESTS * 50 / TOTAL_NUM_LAND_PLOTS) wird auf eine ganze Zahl abgerundet. Negative Wahrscheinlichkeiten entsprechen 0%
    Auf jedem der zufällig ausgewählten Felder wird dann mit einer Wahrscheinlichkeit von P globale Erwärmung auftreten. Man kann in einer Runde also Glück oder Pech haben, in der Regel kann man aber erwarten, dass pro Runde ungefähr P*NUM_FELDER betroffen sind (dieser Wert gilt global, nicht innerhalb der eigenen Civ).

    Für Modder

    Geht eigentlich auch alles aus der Formel hervor. GLOBAL_WARMING_PROB ist die maximale Wahrscheinlichkeit pro Feld (setzt man sie also auf 0, gibt es keine globale Erwärmung), GLOBAL_WARMING_FOREST gewichtet, wie stark Wälder diese Wahrscheinlichkeit reduzieren.
    Erwähnenswert, aber letztlich ohne ernsthafte Relevanz ist, dass TOTAL_NUM_FORESTS eigentlich nicht die Summer aller Wälder und Dschungel, sondern die Summe aller Geländefelder mit einer Geländeeigenschaft, die sich ausbreiten kann, ist; im ungemoddeten BtS sind das halt nur Dschungel und Wald. Man beachte dazu diesen Abschnitt des Codes, insbesondere den Kommentar.

    Code:
                    if (GC.getFeatureInfo(pPlot->getFeatureType()).getGrowthProbability() > 0) // hack, but we don't want to add new XML field in the patch just for this
                    {
                        ++iGlobalWarmingDefense;
                    }
    Man mag davon halten, was man will

    Auswirkungen

    Tritt nun auf einem Feld globale Erwärmung auf, geschieht Folgendes:

    1. Befindet sich auf dem Feld eine Geländeeigenschaft (Wald, Dschungel, Schwemmland, Oase), wird diese entfernt, Fallout allerdings nicht.
    2. Befindet sich auf dem Feld keine Geländeeigenschaft (und auch nur dann), wird das Geländefeld zu Wüste, sofern der unmodernisierte Gesamtertrag des Feldes ( + + ) größer als 1 ist (Tundra und Eis sind also in der Regel von globaler Erwärmung ausgeschlossen, sofern ihr Ertrag durch Hügel/Fluss/Ressourcen/Events nicht auf 2 oder mehr erhöhrt wurde).
    3. Wenn auf eine der obigen Arten globale Erwärmung eingetreten ist (es passiert immer nur eins), wird immer auch die Modernisierung auf dem Feld entfernt, wenn vorhanden.


    Ein Feld ist also "immun" gegenüber globaler Erwärmung, wenn sich auf ihm Fallout befindet, sein Ertrag ohne Modernisierung 1 oder 0 ist oder wenn es bereits Wüste ist - kurz gesagt, wenn es ohnehin schon nutzlos ist Wird ein solches Feld vom Code ausgewählt, verpufft die globale Erwärmung einfach, es wird kein neues Feld, auf dem sie stattdessen auftritt, bestimmt. Dadurch ist die oben genannte Wahrscheinlichkeit immer etwas geringer, da je nach Beschaffenheit der Karte die Wahrscheinlichkeit, ein Feld zu erwischen, auf dem die globale Erwärmung gar nicht erst wirkt, mehr oder weniger groß ist.

    Für Modder

    Die Geländeeigenschaft, die gegenüber globaler Erwärmung immun ist, ist immer NUKE_FEATURE in GlobalDefines.xml. Es empfiehlt sich also, diesen Wert nicht zu verändern, wenn man nicht will, dass Atomraketen für blühende Wälder sorgen, wo auch immer sie einschlagen
    Schon eher interessant ist da GLOBAL_WARMING_TERRAIN, also die Geländeart, in die sich Felder ohne Geländeeigenschaft verwandeln (ungemoddet Wüste). Wenn man will, könnte man das zu Tundra, Schnee oder einem völlig neuen Terrain ändern, sollte man das irgendwie für sinnvoll halten.

    Konsequenzen

    Rein technisch ist damit alles gesagt, aber auf ein paar Dinge will ich nochmal explizit eingehen.

    • Das Auftreten globaler Erwärmung hängt nicht von der Runden- oder Jahreszahl ab, sondern lediglich von der Anzahl abgefeuerter Nukes/Kernschmelzen, verschmutzender Gebäude und verbliebener Dschungel/Wälder. Schwer, aber nicht unmöglich, nur mit Schmieden globale Erwärmung zu erzeugen.
    • Die Auswahl der Felder, auf denen globale Erwärmung auftritt, ist rein zufällig (man erhält aber nur eine Meldung, wenn es in der Nähe einer eigenen Stadt passiert). Es ist völlig egal, wer die schmutzigen Gebäude gebaut und die Nukes abgeworfen hat, ebenso egal ist es, wo diese Gebäude stehen, wo die Nukes abgeworfen wurden und wo noch viele Wälder sind. Die Gegner werden also die Effekte meiner Verschmutzung genauso abkriegen wie ich die ihrer.
    • Je mehr Felder bereits verwüstet wurden, desto unwahrscheinlicher wird die globale Erwärmung, da dann häufiger Felder ausgewählt werden, auf denen die globale Erwärmung keine Wirkung mehr hat, wodurch sie verpufft. Dadurch ist es in der Regel unwahrscheinlich, dass die gesamte Welt zur Wüste wird (in der Regel wäre das allerdings auch ohne diesen Effekt unwahrscheinlich, trotzdem find ich es erwähnenswert).
    • Verglichen mit dem Effekt von Nukes ist der von recht gering. Eine Continents-Karte auf Standardgröße hat 4.368 Felder, daraus folgt, dass die Zündung einer einzigen Nuke ziemlich genau denselben Effekt hat wie 110 zusätzliche (110 * 20 / 4368 = 1/2).
    • Ganz interessant: Wenn 40% der Landfläche mit Wald oder Dschungel bedeckt sind, kann keine globale Erwärmung auftreten.
    Geändert von BoggyB (09. Mai 2015 um 17:02 Uhr)
    "Only Germans, perhaps, could make a game about economics - a stylish, intelligent and captivating one at that." - The New York Times

  2. #2
    esst mehr Teile Avatar von mauz
    Registriert seit
    27.11.09
    Beiträge
    20.310
    danke bestätigt auch mein Gefühl, dass viele stehengelassene Wälder die Erwärmung iwie reduzieren. Der Code-Kommentar

  3. #3
    Banned Avatar von Megui
    Registriert seit
    21.07.14
    Beiträge
    817
    Zitat Zitat von mauz Beitrag anzeigen
    danke bestätigt auch mein Gefühl, dass viele stehengelassene Wälder die Erwärmung iwie reduzieren. Der Code-Kommentar
    Das bedeutet also man soll in der antike nicht mehr Holzen um die Welt zu schonen? Das ist glaube ich dann ein anderes Spiel


    Daraus schließe ich, dass auf einer Continents-Karte mit 4368 Schwemmländer es schon früh Globale Erwärmung auftritt und die Schwemmländer so langsam zu Wüste werden bis sich ein Optimum aus Wüste & Schwemmland einstellt, oder muss die Welt vorher komplett besiedelt sein?

    An sich schade, dass in Civ4 kein Dschungel durch Globale Erwärmung entsteht, wie damals zu Civ2 - da war das früheste bei mir im Mittelalter mit King Richards Kreuzzug, was ne Megaprodstadt schaffte und schon früh viel Pollution entstand - vor Ingenieure hat es ewig gedauert bis das weggeht

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •