Seite 3 von 10 ErsteErste 1234567 ... LetzteLetzte
Ergebnis 31 bis 45 von 136

Thema: fliegende Artillerie :)

  1. #31
    Registrierter Benutzer
    Registriert seit
    29.01.03
    Beiträge
    4.909
    Danke dir... ich beschreibe es so ausführlich, damit ich selbst eine Anleitung habe wie es zu den Veränderungen gekommen ist. Denn sobald ein neuer Patch oder so draußen ist müssen die Veränderungen bei ihm wieder durchgeführt werden um einen evnteullen Mod anzupassen.

    Hey Bello, ich weiß ja aus verschiedenen Diskussionen, dass du bei der Artillerie gleicher Meinung bist wie ich. Wenn das Grundgerüst zum Mod steht und es an Blanacing und Feinanpassungen geht hätte ich dich gerne als Tester dabei. Aber bis dahin wird noch etwas zeit vergehen, ich schreib dich dann einfach an

  2. #32
    Registrierter Benutzer
    Registriert seit
    29.01.03
    Beiträge
    4.909
    Zum Anzeigen von Texten wird übrings die Funktion addMessage benutzt.
    Ich habe mal versucht genau herauszufinden wie man diese korrekt aufruft:

    PHP-Code:
    void CvDLLInterfaceIFaceBase::addMessage(PlayerTypes ePlayerbool bForceint iLengthCvWString szStringLPCTSTR pszSound NULL,
            
    InterfaceMessageTypes eType MESSAGE_TYPE_INFOLPCSTR pszIcon NULLColorTypes eFlashColor NO_COLOR,
            
    int iFlashX = -1int iFlashY = -1bool bShowOffScreenArrows falsebool bShowOnScreenArrows false) = 0
    Prameter:
    ePlayer = Der Spieler der die Nachricht sieht.

    PlayerTypes ist der Varibalentyp zur übergabe. Ich kenne mich mit C++ nicht gut aus und daher weiß ich nicht wie der Typ genau definiert ist. Vielleicht kann mir das jemand sagen? Es ist zumindest so eine Art Pointer oder Handle für einen Spieler im Game.

    Meistens wird eine Nachricht gezeigt, wenn irgendetwas mit einer Einheit oder Stadt gemacht wird. In diesem Falle kann man den Besitzer der Einheit leicht herausfinden mit der Funktion: CvUnit::getOwnerINLINE() und den Besitzer einer Stadt bekommt man so raus: CvCity::getOwnerINLINE().
    Natürlich benötigt man dann ebenfalls einen Pointer oder Handle auf die entsprechende Stadt oder Einheit. Aber dieser ist ja in der Textanzeigenden Funktion oft mitgeliefert.

    Beispiel:
    PHP-Code:
    pBombardCity->getOwnerINLINE() 
    Hier wird der Playerhandle ermittelt, welcher der Besitzer ist von der Stadt, welche im Pointer pBombardCity überliefert wurde.

    eForce = Keine Ahnung was das ist, wer es weiß sagt es mir einfach

    Also wenn ich das auf true setze wird die Textnachricht gleich angezeigt, während auch der Sound abgespielt wird. Setzte ich das auf false wird die Textnachricht erst später angezeigt, nachdem der Sound abgespielt wurde. Eventuell ist dies dazu da um zu bestimmen ob die Textnachricht während der Abarbeitung verschiederner berechnungen angezeigt wird oder erst danach. Z.B. bei einer Stadt die gewachsen ist wird diese Nachricht soweit ich weiß ja auch erst angezeigt nachdem alle Städte bearbeitet wurden oder? Aber genau weiß ich das jetzt nicht...

    iLenght = Gibt in Sekunden an wie lange der Text angezeigt wird.

    Normalerweise sind die Zeitspannen für das Anzeigen eines Textes genau definiert. So eine Definition kann man abfragen und für diese Funktion verwenden indem man folgende Funktion aufruft: GC.getDefineINT

    Beispiel:
    PHP-Code:
    GC.getDefineINT("EVENT_MESSAGE_TIME"
    Damit wird eine Integerzahl zurückgeliefert, welche der unter EVENT_MESSAGE_TIME definierten Anzeigelänge entspricht.

    szString = Das ist der Text der angezeigt wird.

    Die hier übergebene Variable muß vom Typ CvWString. Hier weiß ich jedoch ebenfalls nicht wie dieser Typ definiert ist. Aber man definiert einfach vorher ne Variable vom Typ CvWString, übergibt ihr einen Text und bindet sie hier in die Funktion ein... das geht super

    pszSound = Der Sound der beim Anzeigen abgespielt wird.

    Der Sound wird zeitgleich mit der Textanzeige abgespielt. Daher: wenn man eForce auf true hat sofort, wenn man eForce auf false hat erst verzögert.
    Der Typ LPCTSTR scheint einen String zu erwarten der auf den Sound verweist. Ich habe leider keine Liste mit solchen Soundverweisen und benutzte hier einfach "AS2D_BOMBARDED" der klingt doof genug

    eType = Das gibt den Nachrichtentyp an.

    Hier wird der Typ InterfaceMessageTypes verlangt. Anscheiend kann man hier definieren ob die Nachricht als Log erscheint oder einfach als normale Spielnachricht etc. Ich habe jedoch keine Liste welcher Wert die Nachricht wie beeinflußt. Ich habe hier einfach den Standart MESSAGE_TYPE_INFO verwendet.

    pszIcon = Hier wird das Icon angegeben mit dem die Herkunft der Nacht gekennzeichnet ist.

    Das ist das Icon welches am Bildrand erscheint wenn "Ursprungsort" der Nachricht außerhalb des Sichtbereiches ist glaube ich. Der Typ LPCTSTR erwartet wieder einen String welcher auf das Icon verweist. Gibt man hier NULL an, dann wird wohl keines angezeigt.
    Mit der Funktion GC.getUnitInfo(pUnit->getUnitType()).getButton() könnte man z.B. das Icon der Einheit ermitteln, welche durch den Pointer pUnit übergeben wurde.

    eFlashColor = Die Textfarbe der Nachricht.

    Hier wird der Typ ColorTypes erwartet. Mit der Funktion (ColorTypes)GC.getInfoTypeForString("COLOR_RED") bekommt man z.B. den ColorTypes der Frae Rot zurückgeliefert. Das (ColorTypes) scheint eine Art Typanpassung zu sein, da die Orginalfunktion nur einen ähnlichen Typen aber nicht genau diesen zurück gibt.

    iFlashX = Die X Position des Nachrichten Ursprungortes.

    iFlashY = Die Y Position des Nachrichten Ursprungortes.

    Diese Beiden Parameter geben also an, wohin der blinkende Rote "Nachrichtenpfeil" zeigen soll für den wir ja mit pszIcon das Icon festgelegt haben. Möchte man den Pfeil gar nicht angezeigt haben gibt man einfach 0 ein. Um z.B. die X Position für eine Einheit herauszubekommen benutzt man einfach die Funktion pUnit->getX_INLINE() und für die Y Koordinate pUnit->getX_INLINE(), wobei der Pointer pUnit auf die entsprechende Einheit zeigt.

    bShowOffScreenArrows = Gibt an ob der "Nachrichtenpfeil" auf den Ursprungsort zeigen soll, wenn dieser außerhalb des Bildschirmes liegt.

    bShowOnScreenArrows = Gibt an ob der "Nachrichtenpfeil" auf den Ursprungsort zeigen soll, wenn dieser innerhalb des Bildschirmes liegt.

    gibt man true an, wird der Pfeil angezeigt und bei false wird er nicht angezeigt.

    Übringens gehört die Funktion addMessage zur Klasse CvDLLInterfaceIFaceBase daher kann man die Funktion nur im Zusammenhang mit einem "Interface"-Objekt verwenden. Welche es da so gibt weiß ich nicht genau, ich verwende hier einfach so eine Art Standard-Interface Objekt was ich durch die Funktion gDLL->getInterfaceIFace() zurückgeliefert bekomme.

    Da ich nun wunderbar in der Lage bin alle mir erdenklichen Nachrichten anzeigen zu lassen, kann ich das gleich für meine geänderte Bombardierungsroutine benutzten. Diese bombardiert ja noch nicht richtig, aber damit ich sehe, dass das Interface zur Zielauswahl richtig geht und die Bombardierungsroutine vom Spiel aufgerufen wird programmiere ich sie mir so, dass sie zumindest einen Text als Rückmeldung gibt.

    In der Datei CvUnit in etwa die Zeile 3348 änder ich die Funktion bool CvUnit::bombard() folgendermaßen ab:

    PHP-Code:
    bool CvUnit::bombard()
    {

        
    CvWString szBuffer;
    //! Zeigt die Bombardierungsnachricht an
        
    szBuffer "BOOOOM!! (getroffen) ;) ";
        
    gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), trueGC.getDefineINT("EVENT_MESSAGE_TIME"), szBuffer"AS2D_BOMBARDED"MESSAGE_TYPE_INFOGC.getUnitInfo(getUnitType()).getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), getX_INLINE(), getY_INLINE(), truetrue);

        return 
    true;

    Das Ergebnis könnte ihr auf dem Angefügten Bild gut sehen
    Angehängte Grafiken Angehängte Grafiken

  3. #33
    Ein Platz an der Sonne Avatar von Commander Bello
    Registriert seit
    05.06.05
    Ort
    Nähe Koblenz
    Beiträge
    6.209
    Zitat Zitat von Netbandit
    [...]

    Hey Bello, ich weiß ja aus verschiedenen Diskussionen, dass du bei der Artillerie gleicher Meinung bist wie ich. Wenn das Grundgerüst zum Mod steht und es an Blanacing und Feinanpassungen geht hätte ich dich gerne als Tester dabei. Aber bis dahin wird noch etwas zeit vergehen, ich schreib dich dann einfach an
    Nur zu!

    Bin momentan gesundheitlich ein bißchen gehandicapt, aber wo ich helfen kann, tu ich es gern.


  4. #34
    Registrierter Benutzer
    Registriert seit
    29.01.03
    Beiträge
    4.909
    Da ich überlege, ob ich vielleicht später die Bombardierungsreichweite abhänig von verschiedenen Faktoren mache (ob die Einheit auf einem Hügel steht oder ob sie bestimmte Beförderungen besitzt etc.) füge ich eine eigene Funktion zum ermitteln der Bombardierungsreichweite ein int CvUnit::BombardRange() const

    Dazu füge ich in der Datei CvUnit.cpp folgenden Code ein (bei mir ist er in Zeile 5000)

    PHP-Code:
    int CvUnit::BombardRange() const
    {
    //! Ich benutze ersteinmal den XML Tag iAirRange zum Feststellen der Bombardierungsreichweite
        
    return GC.getUnitInfo(getUnitType()).getAirRange();

    Diese Funktion muss natürlich noch bekannt gemacht werden. Das passiert in der Datei CvUnit.h ca. bei Zeile 242 mit dem Code:

    PHP-Code:
        DllExport int BombardRange() const; 
    Als nächstes änder ich dann die Funktion, welche die Reichweite der Artillerie anzeigt.
    In der Datei CvGame.cpp änder ich bei Zeile 1875 den Codeblock

    PHP-Code:
    //! Hier wird das "Gitter" für Bombardierungseinheiten dargestellt
            
    if (pHeadSelectedUnit->canBombard())
            {

                
    iMaxBombardRange 0;   //! Bombardierungsreichweite auf 0 setzen

    //! Holt die Liste der selektierten Einheiten
                
    pSelectedUnitNode gDLL->getInterfaceIFace()->headSelectionListNode();

    //! Hier geht er die komplette Liste durch und sucht die selektierte Einheit mit der weitesten Bombardierungsreichweite

                
    while (pSelectedUnitNode != NULL)
                {
                    
    pSelectedUnit = ::getUnit(pSelectedUnitNode->m_data);
                    
    pSelectedUnitNode gDLL->getInterfaceIFace()->nextSelectionListNode(pSelectedUnitNode);

                    if (
    pSelectedUnit != NULL)
                    {
                        
    //! Ich benutze eine eigene Funktion zum ermitteln der reichweite
                        
    iMaxBombardRange max(iMaxBombardRangepSelectedUnit->BombardRange());
                    }
                }

                if (
    iMaxBombardRange 0//! wenn bei einer Einheit im selaktierten Stack die Bombardierreichweite > 0 ist dann zeigt er sie an
                
    {
                    for (
    iDX = -(iMaxBombardRange); iDX <= iMaxBombardRangeiDX++)
                    {
                        for (
    iDY = -(iMaxBombardRange); iDY <= iMaxBombardRangeiDY++)
                        {
                            
    pLoopPlot plotXY(pHeadSelectedUnit->getX_INLINE(), pHeadSelectedUnit->getY_INLINE(), iDXiDY);

                            if (
    pLoopPlot != NULL)
                            {
                                if (
    plotDistance(pHeadSelectedUnit->getX_INLINE(), pHeadSelectedUnit->getY_INLINE(), pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE()) <= iMaxBombardRange)
                                {
                                    
    NiColorA color(GC.getColorInfo((ColorTypes)GC.getInfoTypeForString("COLOR_RED")).getColor());
                                    
    color.0.4f;
                                    
    gDLL->getEngineIFace()->addColoredPlot(pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE(), colorPLOT_STYLE_TARGETPLOT_LANDSCAPE_LAYER_BASE);
                                }
                            }
                        }
                    }
                }
            } 
    So dass in Zeile 19 anstatt pSelectedUnit->airRange die Funktion pSelectedUnit->BombardRange benutzt wird.

  5. #35
    Registrierter Benutzer
    Registriert seit
    29.01.03
    Beiträge
    4.909
    Als nächstes will ich die Funktion erarbeiten, welche entscheidet ob das entsprechende Feld überhaupt bombardiert werden kann. Diese Funktion wird beim Anzeigen des Zielwahl Interfaces aufgerufen um zu entscheiden ob der Cursor grün anzeigen soll. Außerdem wird diese Funktion bei der eigendlichen Bombardierroutine aufgerufen um sicher zu gehen, dass überhaupt bombardiert werden darf.

    Dazu muss ich die Funktion CvUnit::bombard in der Datei CvUnit.cpp etwas umschreiben. Es müssen jetzt Parameter übergeben werden, welche das Zielfeld angeben und es muss mit canBombardAt überprüft werden, ob bombardiert werden kann. Dieser Funktion wird das Feld übergeben auf dem sich die Einheit befindet und die beiden Zielkoordinaten.

    Ist das bombardieren nicht möglich wird die Funktion bombard nun abgebrochen und es wird keine Textnachricht ausgegeben.

    PHP-Code:
    bool CvUnit::bombard(int iXint iY)
    {
        
    CvWString szBuffer;

        if (!
    canBombardAt(plot(), iXiY))
        {
            return 
    false;
        }

    //! Zeigt die Bombardierungsnachricht an
        
    szBuffer "BOOOOM!! (getroffen) ;) ";
        
    gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), trueGC.getDefineINT("EVENT_MESSAGE_TIME"), szBuffer"AS2D_BOMBARDED"MESSAGE_TYPE_INFOGC.getUnitInfo(getUnitType()).getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), getX_INLINE(), getY_INLINE(), truetrue);
        return 
    true;

    Da ich nun Parameter für diese Funktion verlange muss das in der Datei CvUnit.h natürlich ebenfalls bekannt gemacht werden.

    Ich änder die Zeile:
    PHP-Code:
        bool bombard(); 
    in:
    PHP-Code:
        bool bombard(int iXint iY); 
    Und zu letzt müssen die Variablen beim Missionsstart mit übergeben werden. Dazu änder ich in der Datei CvSelectionGroup.cpp in der Funktion void CvSelectionGroup::startMission() ca. bei Zeile 891 den Code entsprechend ab.

    Aus:
    PHP-Code:
                    case MISSION_BOMBARD:
                        if (
    pLoopUnit->bombard())
                        {
                            
    bAction true;
                        }
                        break; 
    wird
    PHP-Code:
                    case MISSION_BOMBARD:
                        if (
    pLoopUnit->bombard(headMissionQueueNode()->m_data.iData1headMissionQueueNode()->m_data.iData2))
                        {
                            
    bAction true;
                        }
                        break; 
    Nun muss ich nur noch die Funktion canBombardAt in der Datei CvUnit.cpp so schreiben, dass sie sinnvoll erkennt, wann bombardiert werden kann und wann nicht.
    Derzeit erkennt sie, ob ein Feld innerhalb der Reichweite liegt, dazu sieht so so aus:

    PHP-Code:
    bool CvUnit::canBombardAt(const CvPlotpPlotint iXint iY) const
    {
        
    CvPlotpTargetPlot;    //! Das Zielfeld

    //! Kann die Einheit überhaupt bombardieren?

        
    if (!canBombard())
        {
            return 
    false;
        }

    //! Hier holen wir uns das Zielfeld
        
    pTargetPlot GC.getMapINLINE().plotINLINE(iXiY);


    //! Ist die Entfernung zwischen dem Feld wo die Einheit steht und dem Zielfeld zu weit kann nicht bombardiert werden
        
    if (plotDistance(pPlot->getX_INLINE(), pPlot->getY_INLINE(), pTargetPlot->getX_INLINE(), pTargetPlot->getY_INLINE()) > BombardRange())
        {
            return 
    false;
        }

        return 
    true;

    Und es geht super

  6. #36
    KSV Hessen Kassel Avatar von jok
    Registriert seit
    24.01.02
    Ort
    Kassel
    Beiträge
    3.630
    Auf jeden Fall schon eine Klasse Arbeit, die du da machst. An das SDK hab ich mich bisher nicht wirklich rangetraut, aber das wäre wohl der nächste Schritt, wenn ich nun XML und Python schon fast alles machen kann... Auch interessant hier mitzulesen, was du genau veränderst, und was es bewirkt.


  7. #37
    Registrierter Benutzer
    Registriert seit
    29.01.03
    Beiträge
    4.909
    So ich überlege gerade unter welchen Bedingungen eine Bombardierung möglich ist:

    PHP-Code:
    Befindet sich eine Stadt auf dem Zielfeld?
    ja:
      
    Ist die Stadt feindlich?
      
    nein:
        
    keine Bombardierung möglich!
      
    ja
        
    Bombardierung möglich!

    nein:
      
    Befindet sich eine feindliche Einheit auf dem Zielfeld?
      
    ja:
        
    Bombardierung möglich!
      
      
    nein:
        
    Besitzt das Feld eine Modernisierung?
        
    ja:
          
    Gehört das Feld einer Zivilisation mit der man nicht im Krieg ist?
          
    ja:
            
    Keine Bombardierung möglich!
          
    nein:
            
    Bombardierung möglich!

        
    nein:
          
    Keine Bombardierung möglich
    Was haltet ihr davon? Das sollte ungefähr dem Verhalten von Civ3 entsprechen. Wobei es ganz klar eine Trefferpriorität gibt:
    - Stadt
    - Einheit
    - Modernisierung

    Ist eine Stadt auf dem feld spielt es keine Rolle mehr ob da eine Bombardiertaugliche Einheit ebenfalls drauf steht. Es zählt nur ob die Stadt bombardiert werden kann oder nicht.
    Ist kene Stadt auf dem Feld aber eine feindliche Einheit spielt es keine Rolle wem das Feld gehört oder ob eine Modernisierung drauf ist. Ist keine feindliche Einheit drauf kann das Feld bombardiert werden, solange eine Modernisierung drauf ist welche nicht zufällug einem Freund gehört.

  8. #38
    Registrierter Benutzer Avatar von TheWusel
    Registriert seit
    22.03.03
    Ort
    Oldenburg
    Beiträge
    347
    Ich schlage vor, dass der Titel des Threads geändert werden sollte. Fliegende Artillerie passt ja nicht mehr so gut.

    Deine bisherige Arbeit finde ich beeindruckend. Ich bekomme richtig Lust, selbst (wieder) in solche Arbeiten einzusteigen.

    -TheWusel

  9. #39
    Registrierter Benutzer
    Registriert seit
    29.01.03
    Beiträge
    4.909
    Zitat Zitat von TheWusel
    Ich schlage vor, dass der Titel des Threads geändert werden sollte. Fliegende Artillerie passt ja nicht mehr so gut.

    Deine bisherige Arbeit finde ich beeindruckend. Ich bekomme richtig Lust, selbst (wieder) in solche Arbeiten einzusteigen.

    -TheWusel
    Du bist gerne eingeladen zu helfen Immerhin ist es nicht damit getan, dass wir Menschen bombardieren können. Das müssen wir auch der KI beibringen... und die ist schon ein ganzes Stück komplexer, da könnte ich Hilfe gebrauchen

  10. #40
    Ein Platz an der Sonne Avatar von Commander Bello
    Registriert seit
    05.06.05
    Ort
    Nähe Koblenz
    Beiträge
    6.209
    Zitat Zitat von Netbandit
    So ich überlege gerade unter welchen Bedingungen eine Bombardierung möglich ist:

    PHP-Code:
    Befindet sich eine Stadt auf dem Zielfeld?
    ja:
      
    Ist die Stadt feindlich?
      
    nein:
        
    keine Bombardierung möglich!
      
    ja
        
    Bombardierung möglich!

    nein:
      
    Befindet sich eine feindliche Einheit auf dem Zielfeld?
      
    ja:
        
    Bombardierung möglich!
      
      
    nein:
        
    Besitzt das Feld eine Modernisierung?
        
    ja:
          
    Gehört das Feld einer Zivilisation mit der man nicht im Krieg ist?
          
    ja:
            
    Keine Bombardierung möglich!
          
    nein:
            
    Bombardierung möglich!

        
    nein:
          
    Keine Bombardierung möglich
    Was haltet ihr davon? Das sollte ungefähr dem Verhalten von Civ3 entsprechen. Wobei es ganz klar eine Trefferpriorität gibt:
    - Stadt
    - Einheit
    - Modernisierung

    Ist eine Stadt auf dem feld spielt es keine Rolle mehr ob da eine Bombardiertaugliche Einheit ebenfalls drauf steht. Es zählt nur ob die Stadt bombardiert werden kann oder nicht.
    Ist kene Stadt auf dem Feld aber eine feindliche Einheit spielt es keine Rolle wem das Feld gehört oder ob eine Modernisierung drauf ist. Ist keine feindliche Einheit drauf kann das Feld bombardiert werden, solange eine Modernisierung drauf ist welche nicht zufällug einem Freund gehört.
    Ich halte den Algorithmus für uneffektiv.
    Du prüfst erst im dritten Schritt ab, ob es sich beim Zielfeld um ein feindliches Feld handelt. Das müsste aber der erste Schritt sein, nach meinem Dafürhalten.

    Warum? Weil es:
    a) keine feindliche Stadt auf nicht-feindlichem Gebiet gibt. Das liegt in der Natur des Spieles und kann nicht anders sein
    b) weil es zwar zur Zeit möglich, aber m.E. nicht sinnvoll ist, daß ich feindliche Einheiten auf "neutralem" Gebiet per Bombardierung angreife. Das führt nämlich zu dem gegenwärtig existierenden "Bomber-Exploit", in dem ich meine Bomber in einer Stadt stationiere, an die der Gegner aufgrund mangelnder offener Grenzen nicht herankommt.

    Es müsste m.E. so lauten:
    Ist das Zielfeld feindlich?
    nein: keine Bombardieriung
    ja:
    Stadt?
    ja: ...
    nein: ...

    etc.


  11. #41
    Macht Musik Avatar von Peregrin_Tooc
    Registriert seit
    21.05.05
    Ort
    St. Ingbert
    Beiträge
    11.144
    @Bello:

  12. #42
    Registrierter Benutzer
    Registriert seit
    29.01.03
    Beiträge
    4.909
    Nun das Problem ist jedoch, dass der Kulturradius bei einem Krieg soweit zusammenfallen kann, dass sich feindliche Einheiten auf neuralem Gebiet befinden. Das ist ja z.b. bei Civ3 gang und gebe bei einem massiven Krieg. Auch schützt das nicht vor dem Ausnutzen des von dir beschriebenen "Bomber-Exploit", denn eine feindliche Einheit könnte auf feindlichen Gebiet stehen und du steht mit deiner Artillerie auf befreundeten, aber nicht eigenen Territorium, wo eine feindliche Einheit nicht hinkommt. Also ich sehe das als grundsätzliches Problem des Games und nicht als Problem der Bombenroutinen. Also verstehe mich nciht falsch, ich möchte solch ein "Bomber-Exploit" nicht unterstützen aber ich sehe keine wirksamme Unterbindung dieses Fehlers solange es Fernbombardierungen geben wird.

    Alternativ könnte man schreiben, dass eine Einheit nur dann bombardieren kann wenn das Bombardierungsziel neutral ist (also eine Geländemodernisierung auf neutralen Boden) oder wenn das Bombardierungsziel feindlich ist und mit dem Besitzer des Feldes auf dem die Artillerie steht verfeindet ist.
    Was hälst du davon?

  13. #43
    Registrierter Benutzer
    Registriert seit
    29.01.03
    Beiträge
    4.909
    Edit:
    Ich habe in der Funktion die NULL auf NO_PLAYER nachträglich ändern müssen, da man mit NULL nicht feststellen kann ob kein Team angegeben wurde. Sondern nur mit NO_PLAYER!


    Ich habe jetzt eine Funktion programmiert, welche prüft ob der Besitzer eines Zielobjektes bombardiert werden darf.
    Die Funktion heißt canUnitBombardTeam und ist Teil der Klasse CvUnit.

    In der Datei CvUnit.h muss die Funktion bekannt gemacht werden. Das habe ich in der Zeile 154 getan:

    PHP-Code:
        bool canUnitBombardTeam(TeamTypes TargetTeam) const;    //! Erfragt, ob die Einheit ein Objekt eines Teams bombardiren kann                 // Exposed to Python 
    und in der Datei CvUnit.cpp habe ich bei Zeile 3391 die Funktion hineinprogrammiert:

    PHP-Code:
    //! Ermittelt ob man überhaupt im Krieg mit dem Besitzer des Zielobjektes ist und
    //! und ob der Besitzer des Abschussfeldes auch mit ihm im Krieg ist. Das soll den
    //! Mißbrauch einer Bombardierungseinheit vermeiden.
    //! TargetTeam = gibt den Besitzer des Zielobjektes an.

    bool CvUnit::canUnitBombardTeam(TeamTypes TargetTeam) const
    {
        
    TeamTypes UnitTeam;         //Team welches die Bombardierungseinheit besitzt
        
    TeamTypes UnitPlotTeam;     //Team auf dessen Feld die Bombardierungseinheit steht

        
    UnitTeam getTeam();       // Ermittel das Team dem die Einheit gehört
        
    UnitPlotTeam GC.getMapINLINE().plotINLINE(getX_INLINE(), getY_INLINE())->getTeam(); //Ermittelt das Team dem das Abschußfeld gehört

        
    if (TargetTeam == NO_PLAYER// Gehört das Zielobjekt niemanden?
        
    {
            return 
    true;    // Dann darf bombardiert werden!
        
    }

        if (
    atWar(TargetTeamUnitTeam))   // Ist der Einheitenbesitzer mit dem Zielobjektbesitzer im Krieg?
        
    {

            if (
    UnitPlotTeam == NO_PLAYER)   // Gehört das Abschußfeld niemanden?
            
    {
                return 
    true;    // Dann darf bombardiert werden!
            
    }

            if (
    atWar(TargetTeamUnitPlotTeam))   // Ist der Besitzer des Abschußfeldes mit dem Zielobjektbesitzer im Krieg?
            
    {
                return 
    true// Dann darf bombardiert werden!
            
    }

            if (
    UnitPlotTeam == TargetTeam)   // Gehört das Abschußfeld dem Zielobjektbesitzer?
            
    {
                return 
    true;    // Dann darf bombardiert werden!
            
    }

        }

        return 
    false;   // In allen anderen Fällen darf nicht bombardiert werden!

    Der Funktion wird nur ein Parameter übergeben, und zwar das Team vom Zielobjekt vom Typ TeamTypes. Das kann bei Einheiten oder Städten z.B. mit der Klassenfunktion getTeam() ermittelt werden.

    Beispiel:
    PHP-Code:
    TeamTypes UnitTeam;

    UnitTeam pUnit->getTeam(); 
    Die Funktion schaut zuerst ob das Zielobjekt überhaupt einen Besitzer hat. Z.B. kann es vorkommen, dass eine Modernisierung auf neutralem Boden bombardiert werden soll. In diesem Falle gibt es keinen Besitzer. Solltes es wirklich keinen Besitzer geben kann bombardiert werden, da je niemand geschädigt wird.

    Gibt es doch einen Besitzer wird geguckt ob man mit ihm verfeindet ist, ist das der Fall wird geguckt ob man auf neutralen Boden steht. In diesem Falle kann bombardiert werden.
    Steht man auf dem Boden des Feindes kann auch bombardiert werden. Und ist der Besitzer des Bodens verfeindet mit dem Besitzer des Ziels, kann auch bombardiert werden. (z.B. wenn man auf den eigenen Boden steht oder auf dem Boden eines Freundes der auch gegen ihn Krieg führt).

    In allen anderen Fällen darf nicht bombardiert werden. Das soll verhindern, dass man sich auf befreundeten Territorium versteckt und feindliche Einheiten bombardiert, während einen nicht angreifen können, weil der Freund keine offenen Grenzen mit dem Gegner hat und auch nicht verfeindet ist mit ihm.

    Sinnvoll kann dieses Verhalten erklärt werden, dass eine neutrale Nation meinen Einheiten verbietet von ihrem Territorium einen feindlichen Akt auf meinen Gegner zu starten um nicht selbst in den Krieg hineinzurutschen.
    Geändert von Netbandit (06. Juni 2006 um 23:59 Uhr)

  14. #44
    the cosmos rocks Avatar von Caesium
    Registriert seit
    08.12.03
    Ort
    Faerûn
    Beiträge
    9.104
    Ich versuch es hier ja alles nachzuvollziehen, aber: Schreibst du eine neue Funktion, oder eine alte um?
    Caesium Mod v2.4 (für Civ4 WL v2.13)

  15. #45
    Registrierter Benutzer
    Registriert seit
    29.01.03
    Beiträge
    4.909
    Zitat Zitat von Caesium
    Ich versuch es hier ja alles nachzuvollziehen, aber: Schreibst du eine neue Funktion, oder eine alte um?
    Also die CvUnit::bombard habe ich umgeschrieben, die CvUnit::canBombard auch, die CvUnit::canBombardAt habe ich geschrieben und die CvUnit::canUnitBombardTarget habe ich auch selbst geschrieben.

Seite 3 von 10 ErsteErste 1234567 ... LetzteLetzte

Berechtigungen

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