Schiffskampf-Berechnung

Aus BotE Wiki
Zur Navigation springen Zur Suche springen

Einleitung

Quelle: CombatShip.cpp

Kommt es zu Raumschlachten, findet eine Schiffskampf-Berechnung statt:

maxTick

A combat ends for some reasons:

  • enemies are destroyed or retreat successfully
  • maxTick (m_iTime) is reached
    • if 20 times no one has made an attack (because both are cloaked)
    • if combat lasts too long (MAXSHORT 0x7fff might be 32767 Ticks): weak weapons, strong shields/hulls, or both are unarmed (colony ships for example)


Ablauf der Kampfberechnung

Nachdem der Einfluß der Manövrierbarkeit (siehe unten) berechnet ist, finden die unten folgende Abläufe statt.

Variablen

Einige wenige Variablen:

Variable Erklärung
m_pShip das eigene Schiff (eines nach dem anderen, also jedes einzeln)
m_pTarget das Ziel = gegnerisches Schiff bzw. Außenposten
distance Entfernung
   
   
Shield Schildstärke
toShield Schaden, der auf die Schilde geht
CurrentShield Schildstärke zwischendurch ("current")
   
Hull Hüllenstärke
toHull Schaden, der auf die Hülle geht
CurrentHull Hüllenstärke zwischendurch ("current")
   
toHitBoni Treffergenauigkeits-Boni
toHitMali Treffergenauigkeits-Mali (Verschlechterung)


CalculateNextPosition()

Diese Funktion berechnet den nächsten Punkt auf dem Weg zum Ziel, den das Schiff erreichen wird. (nächste Schußposition?)

Hypothese: Schiffe im Kampf fliegen aufeinander zu bzw. dann aneinander vorbei. Dafür haben Sie programmtechnisch einen Zielpunkt, wohin sie fliegen, unterwegs feuern sie (siehe auch Bild)

Bild CombatSimulator

CombatSimulator.gif

Wenn das Schiff getarnt war und geschossen hat, dann den Tarncounter runterzählen

Kann das "Schiff" nicht fliegen, so gibt es keine neue Position

Wenn noch keine Flugroute berechnet wurde...

...wenn der Schiffsbefehl ANGREIFEN ist...

...und noch kein Ziel ausgewählt ist ...
...dann Zielposition mit mindestens Distanz 10 wählen

...wenn der Schiffsbefehl MEIDEN ist...

...dann zufällige Zielposition im Raum wählen

...wenn der Schiffsbefehl RÜCKZUG ist...

...dann frühest möglichen Rückzugszeitpunkt runterzählen...
...wenn Zähler gleich null ist, eine zufällige Zielposition wählen

Route zur Zielposition berechnen

Abstand berechnen

Beschleunigung berechnen

Bei z.B. einer Manövrierbarkeit von 5 wird bei Speed 1 gestartet und dann immer um 1 erhöht, bis Speed 5 erreicht ist. Genauso wird auch wieder verlangsamt.

Beam-Angriff auf Ziel m_pTarget

Funktion: AttackEnemyWithBeam(const CPoint& beamStart)

nur wenn Distanz größer eins (da sonst ja das Schiff gerammt wurde)

Bonus durch Schiffsspezialeigenschaften besorgen

es wird so viel wie möglich geschossen (Beam)

...unter Berücksichtigung der Beam-Dauer, danach wird die Rechargetime/Wiederaufladezeit abgewarten und dann wieder geschossen

Reichweite = Type(MK)*5 + (Bonus durch Feuer-System) + 50 (um auf 60 bis 160 zu kommen)

Schaden berechnen

Den Schaden wird für jeden Beamstrahl einzeln berechnen. Es wird eine Schleife gleich der Anzahl der Beamstrahlen der Beamwaffe durchlaufen.

Ziel zerstört

Wenn das Ziel keine Hülle mehr hat, wurde es zerstört (HURRA !!!). Es wird ein neues Ziel gesucht und mit dem nächsten Beamstrahl angegriffen.

Torpedo-Angriff auf Ziel m_pTarget

Funktion: AttackEnemyWithTorpedo(std::list<CTorpedo*>* pCT, const CPoint& torpedoStart)

nur wenn Distanz größer drei

wenn das Schiff getarnt ist, dann wird frühestens gefeuert...

...wenn man auf eine Distanz von 2/3 der maximalen Torpedoreichweite rangeflogen ist (weil ? man das getarnte Schiff dann sieht? - in der Zwischenzeit wurde man schon angegriffen???)

Bonus durch Schiffsspezialeigenschaften besorgen

voraussichtlicher Gesamtschaden dieser Torpedoattacke berechnen

Anzahl der verschieden Torpedo-Launcher durchgehen

Jetzt das Ziel des Torpedos berechnen

Dafür den Kurs des Zielschiffes anschauen. Berechnen, nach welcher Zeit der Torpedo sich mit dem Ziel treffen würde. Dorthin muss geschossen werden

Wenn die Distanz nicht größer als 200 ist, werden die Torpedos abgefeuert

Sinn des folgenden Kommentars nicht klar:

// Hier überprüfe ich mit der old_distance. Weil wenn ich die nehmen würde, die wir nach einer bestimmten Zeit erst haben, sind die Schiffe, die schnell fliegen im Nachteil. Deren Gegner würden zuerst schießen, weil die Distanz schneller kleiner wird.

Abgeschaltene Funktion: wenn der voraussichtliche Torpedo-Gesamtschaden zu groß ist

// Wenn der voraussichtliche Torpedogesamtschaden viel größer ist als die noch aktuelle Hülle // plus Schilde des Gegners, dann Abbruch und neues Ziel aufschalten und angreifen. Wir geben // hier die Art und die aktuelle Numer des Beams zurück

Modifikator durch Crewerfahrung

Jedes Erfahrungslevel gibt einen Bonus von 20% auf den Schaden. Außerdem ist die Trefferwahrscheinlichkeit höher.

ActRegShield: stellt vorhandenen regenerativen Schilde auf die feindliche schilddurchschlagende Waffe ein

Funktion: ActRegShield(void)

Angriffsbonus auf Grund ihrer Spezialeigenschaften

Die Funktion GetAccBoniFromSpecials(void) berechnet den Angriffsbonus, den Schiffe auf Grund ihrer Spezialeigenschaften womöglich erhalten.

Wenn getarnt geschossen wurde, gibt es einen 20% Treffer- und Schadensbonus.

Bei Dogfighter/Nahkämpfer Eigenschaft gibt es einen 30% Bonus beim Kampf gegen kleine Gegner (Shipsize=small)

obwohl in der Beschreibung 20% stehen, stehen im Code 30%


Feuerwinkel-Berechnung

Die Funktion: AllowFire(const CFireArc* arc) berechnet, ob ein Feuersystem aufgrund der Position des Schiffes, der Position des Systems auf dem Schiff und dessen Feuerwinkel auch feuern kann.


Besitzt das Schiff eine Flugroute, so ist dessen Ausrichtung der Vektor zwischen aktueller Position und dem nächsten Punkt auf der Flugroute.

Ohne Flugziel richtet sich das Schiff automatisch zum Zentrum aus P(0,0,0)

Trefferwahrscheinlichkeit

Die Trefferwahrscheinlichkeit wird von einer Vielzahl von Faktoren beeinflußt (Thread im Forum: http://forum.birth-of-the-empires.de/viewtopic.php?p=25662#p25662).

Beam: Trefferwahrscheinlichkeit und Schaden

Die Funktion: FireBeam(int beamWeapon, int distance, BYTE boni) berechnet die Trefferwahrscheinlichkeit des Beams und fügt dem Feindschiff wenn möglich Schaden zu.


10% des Schadens gehen immer auf die Hülle, selbst dann, wenn Schilde das feindliche Schiff schützen.

Es wird die Anzahl der Beams pro Schuss beachtet.

Hier kommt die Formel zur Trefferwahrscheinlichkeit ins Spiel. Jeder Schuss wird dafür einzeln beachtet:

Beschreibung:

Acc = 60 - Distance*0.1 + CrewExp(Attacker-Target)*0.1 + Manövriebarkeit(Attacker-Target)*0.2 + Bonus_durch_Feuersystem + BeamType(MK) // distance = [0,16]; CrewExp(att-def) = [-12,12]; Manöver(att-def) = [-15,6]; Feuersystembonus = [5,30]; BeamtypeMK = [1,X] X max. ca. 20


Programm-Code:

short Acc = (short)(60 - distance * 0.1 + (GetCrewExperienceModi() - m_pTarget->GetCrewExperienceModi()) * 0.1 + (GetToHitBoni(m_pShip->GetManeuverability(), m_pTarget->m_pShip->GetManeuverability()) - GetToHitMali(m_pShip->GetManeuverability(), m_pTarget->m_pShip->GetManeuverability())) * 0.2 + m_pShip->GetBeamWeapons()->GetAt(beamWeapon).GetBonus() + m_pShip->GetBeamWeapons()->GetAt(beamWeapon).GetBeamType());


Modifikation durch die Schiffsgröße

  • Shipsize 0: Acc = (short)(Acc * 0.66);
  • Shipsize 1: Acc = (short)(Acc * 1.00); (theoretisch, praktisch: => keine Modifikation nötig!!!)
  • Shipsize 2: Acc = (short)(Acc * 1.33);
  • Shipsize 3: Acc = (short)(Acc * 1.66);

tatsächlicher Schaden ?

if ((Acc + boni) > rand()%100) beamDamage += ((m_pShip->GetBeamWeapons()->GetAt(beamWeapon).GetBeamPower() * (m_iModifier + boni)) / m_pTarget->m_iModifier);


Hier ist rand(), also Zufall im Spiel !

Schaden auf die Hülle ermitteln

schilddurchdringende Beams

wenn wir schilddurchdringende Beams haben und das feindliche Schiff keine auf unsere Beams eingestellten regenerativen Schilde hat, dann kompletter Schaden an der Hülle

modulierende Beams

wenn wir modulierende Beams haben, dann gehen immer 50% auf die Hülle und 50% auf die Schilde, egal was für Schilde an dem Zielschiff sind

dann wird der restliche Schaden ermittelt, der nicht auf die Hülle ging

der geht auf die Schilde

wenn Schilde nur teilweise ausreichen oder gar nicht, geht der Rest auf die Hülle

wenn wir schilddurchdringende Beams haben und das feindliche Schiff regenerative Schilde, so kann es diese auf unsere Waffen einstellen

ja - das kennen wir von den Borg

Einfluß der Manövrierbarkeit

Eine höhere Manövrierbarkeit bedeutet einen Vorteil im Schiffskampf. Dies wird durch einen Bonus umgesetzt.

Die Manövrierbarkeit kennt 10 Abstufungen von 0 (keine, z.B. Außenposten) bis 9 (phänomenal).

Trefferbonus

Für den Trefferbonus liegt zugrunde:

0 00% 00% 00% 00% 00% 00% 00% 00% 00% 00%

1 05% 00% 00% 00% 00% 00% 00% 00% 00% 00%

2 10% 05% 00% 00% 00% 00% 00% 00% 00% 00%

3 15% 10% 05% 00% 00% 00% 00% 00% 00% 00%

4 20% 15% 10% 05% 00% 00% 00% 00% 00% 00%

5 25% 20% 15% 10% 05% 00% 00% 00% 00% 00%

6 30% 25% 20% 15% 10% 05% 00% 00% 00% 00%

7 35% 30% 25% 20% 15% 10% 05% 00% 00% 00%

8 40% 35% 30% 25% 20% 15% 10% 05% 00% 00%

9 45% 40% 35% 30% 25% 20% 15% 10% 05% 00%

Zur Abstufung folgende Hypothese: Für jede Stufe einer besseren Manövrierbarkeit (Mx) gibt es hier einen 5%-Bonus. Hat ein Schiff M3, der Gegner nur M1, beträgt der Bonus 10%. Maximaler Trefferbonus ist 45%.


Verteidigungsbonus (=to hit malus für Gegner)

Hier ist nicht klar, was das ist:

- Verteidigungs-Bonus, weil die Manövrierbarkeit höher ist als die des Gegners und man deshalb schwerer zu treffen ist

- Verteidigungs-Malus, weil die Manövrierbarkeit niedriger ist als die des Gegners und man deshalb leichter zu treffen ist

0 00% 00% 00% 00% 00% 00% 00% 00% 00% 00%

1 04% 00% 00% 00% 00% 00% 00% 00% 00% 00%

2 10% 04% 00% 00% 00% 00% 00% 00% 00% 00%

3 18% 10% 04% 00% 00% 00% 00% 00% 00% 00%

4 28% 18% 10% 04% 00% 00% 00% 00% 00% 00%

5 40% 28% 18% 10% 04% 00% 00% 00% 00% 00%

6 54% 40% 28% 18% 10% 04% 00% 00% 00% 00%

7 70% 54% 40% 28% 18% 10% 04% 00% 00% 00%

8 88% 70% 54% 40% 28% 18% 10% 04% 00% 00%

9 96% 88% 70% 54% 40% 28% 18% 10% 04% 00%