Open siredmar opened 5 years ago
inselbmp
mit Screenshots erzeugt.Stadtfld.bsh
enthält unterschiedlich viele Bilder. Das sollte sich jetzt mit Bsh_leser::anzahl()
leicht überprüfen lassen. Bloß gab es die Funktion nicht von Anfang an, weil die Anzahl in der Datei nicht explizit gespeichert ist.Auf lange Sicht müsste man diese Informationen sowieso aus Haeuser.cod
auslesen. Das sind „verschlüsselte“ Textdateien (Zweierkomplement jedes Bytes), die mit mdcii-codcat
„entschlüsselt“ werden können. Vielleicht kann man da einen Boost-Spirit-Parser für bauen.
Ich hab vor Ewigkeiten mal einen ".cod" Interpreter grbaut, der hat aber eine mieserable Code-Quallität. Ich könnte bei Bedarf den Code in eine private Repo hochladen. Den Code hab ich dann auch noch benutzt um die Daten in eine SQLite DB zu packen. Dazu kommen noch Listen die aus der EXE direkt entnommen wurden. Jene DB könnt ich auch zur verfügung stellen, hier bin ich mir aber nicht sicher ob das erlaubt ist.
Die Listen aus der EXE-Datei will ich schon aus rechtlichen Gründen definitiv nicht sehen.
SQLite halte ich in dem Kontext auch für eher mäßig sinnvoll.
Es dürfte dann wohl besser sein, den Parser neu zu schreiben.
Die notwendigen Indizes der Grafiken in den BSH-Dateien könnte man dann von grafiken.txt
ableiten.
Die Listen aus der EXE-Datei will ich schon aus rechtlichen Gründen definitiv nicht sehen.
Ok, aber ich werde die Offsets zu den Listen (Gebäude IDs) in der EXE irgendwann irgendwo veröffentlichen.
SQLite halte ich in dem Kontext auch für eher mäßig sinnvoll.
Ich hab mich aus analyse Zwecken damals dafür entschieden. Die Daten sind relational, warum also nicht. Ob das für die Engine dann Sinn macht bin ich mir auch nicht sicher.
Es dürfte dann wohl besser sein, den Parser neu zu schreiben.
Hab ich seit Damals vor, komm aber nie dazu. :see_no_evil:
Die notwendigen Indizes der Grafiken in den BSH-Dateien könnte man dann von
grafiken.txt
ableiten.
Die sind in der haeuser.cod
zu finden.
Aber meine Absicht mit meinem Kommentar war eigentlich zu sagen, dass ich eine grafiken.txt
Datei erzeugen könnte.
Ich bin gerade dabei einen COD Parser unter Verwendung von Protobuf zu implementieren. Protobuf deswegen, weil damit die ausgerollte Struktur der COD Dateien ueber sich wiederholende und rekursive Objekte ganz gut darstellen laesst, und es so wie C++ start typisiert ist. D.h. der Umgang damit fuehlt sich wesentlich nativer an als z.b. mit JSON zu arbeiten. Wie dem auch sei, ich habe mich bei der Implementierung anfangs an die von @cmfcmf aus Anno2018-godot gehalten, bin dann aber startk abgewichen. Die Grundiee, die Zeilen per Regex zu parsen, ist aber bstehen geblieben. Nun hab ich quasi meine Objekte auf der Hand, der vollstaendig geparsten COD Datein. Alle relativen Variablen sind berechnet, Wo Konstanten definiert sind, werden diese verwendet, der Objekt Fill fuegt die Variablen des eingefuegten Objekts hinzu. Das Ergebnis sieht dann zumindest von den Dateninhalten der einzelnen Objekte ziemlich aehnlich zu der JSON Variente von @cmfcmf aus. Die Frage ist nun: wir haben z.B. grafiken.txt Wenn ich mir mein erzeugtes Objekt fuer den Galgen mal so ansehe, dann finde ich die die Variable "Gfx" mit Wert 5372 wieder. Dasselbe finde ich auch in z.b. grafiken.txt wieder.
Protobuf Galgen Objekt:
objects {
name: "474"
variables {
variable {
name: "Id"
value_int: 20841
}
variable {
name: "Gfx"
value_int: 5372
}
variable {
name: "Baugfx"
value_int: 376
}
variable {
name: "Kind"
value_string: "GEBAEUDE"
}
variable {
name: "Size"
value_array {
value {
value_int: 1
}
value {
value_int: 1
}
}
}
variable {
name: "Rotate"
value_int: 1
}
variable {
name: "Tuerflg"
value_int: 1
}
variable {
name: "AnimAdd"
value_int: 4
}
variable {
name: "AnimAnz"
value_int: 6
}
variable {
name: "AnimTime"
value_int: 220
}
}
objects {
name: "HAUS_PRODTYP"
variables {
variable {
name: "Kind"
value_string: "GALGEN"
}
variable {
name: "Radius"
value_int: 16
}
variable {
name: "Kosten"
value_int: 20
}
variable {
name: "Bauinfra"
value_string: "INFRA_GALGEN"
}
}
}
objects {
name: "HAUS_BAUKOST"
variables {
variable {
name: "Werkzeug"
value_int: 1
}
variable {
name: "Holz"
value_int: 2
}
variable {
name: "Money"
value_int: 100
}
}
}
}
Auszug aus grafiken.txt
841 5372 galgen
Selbe Frage fuer bebauung.txt
Dieselbe Nummer 841 ist hier fuer den Galgen benutzt.
Auszug aus bebauung.txt
841 1 1 4 6 1 1 1 0 galgen
Jezt die Frage: Woher kommt die Zahlen z.b. 841? Sind diese frei gewaehlt um eine Zuordnung treffen zu koennen oder hat das irgendeine tiefere Bedeutung?
Jezt die Frage: Woher kommt die Zahlen z.b. 841? Sind diese frei gewaehlt um eine Zuordnung treffen zu koennen oder hat das irgendeine tiefere Bedeutung?
So fern ich mich richtig erinnere, werden alle IDs +20k gerechnet. Nur in dem Insel Datei Format sind die Zahlen so klein. Die IDs in den GAD dateien müssten übrigens irgendwo bei +35k liegen.
edit: Um mehr auf deine Frage einzugehn: Die IDs sind in den COD/GAD Dateien definiert. Allerdings sind die nicht frei wählbar, weil in der EXE statische Arrays mit den IDs zwegs Kathegorie sind. (unsauber programmiert)
Ah... Ein Wald mit vielen Bäumen... 🙂 Ok, das reicht mir erstmal um die Grafiken.txt und Bebauung.txt Dateien loszuwerden und die Sachen aus den geparsten cod Dateien zu generieren.
Ich bin gerade dabei einen COD Parser unter Verwendung von Protobuf zu implementieren. Protobuf deswegen, weil damit die ausgerollte Struktur der COD Dateien ueber sich wiederholende und rekursive Objekte ganz gut darstellen laesst, und es so wie C++ start typisiert ist. D.h. der Umgang damit fuehlt sich wesentlich nativer an als z.b. mit JSON zu arbeiten.
Das klingt doch sehr gut! Wenn es statisch typisiert ist, ist es wahrscheinlich auch deutlich effizienter.
Ah... Ein Wald mit vielen Bäumen... slightly_smiling_face Ok, das reicht mir erstmal um die Grafiken.txt und Bebauung.txt Dateien loszuwerden und die Sachen aus den geparsten cod Dateien zu generieren.
Loswerden im Sinne von „nicht brauchen“. Die beiden Dateien sollten trotzdem im Repo bleiben.
Hab noch ein paar Fragen am Beispiel fuer den Galgen:
; _________ ID
; / ________ Breite (d.h. Breite des Gebäudes)
; / / _______ Höhe (d.h. Länge des Gebäudes)
; / / / ______ Richtungen (1 oder 4)
; / / / / _____ Animationsschritte
; / / / / / ____ Grundhöhe (0 oder 1)
; / / / / / / ___ Bauhöhe (0 oder 1)
; / / / / / / / __ Anzahl optisch unterscheidbarer Lagerstände
; / / / / / / / / _ Kategorie (0=keine, 1=Land, 2=Feld, 3=Haus, 4=Betrieb)
; / / / / / / / / /
841 1 1 4 6 1 1 1 0 galgen
Ich kann aus dem Objekt die Breite, Hoehe (Size Array), Richtungen (Rotate), Animationsschritte (AnimAnz), und evtl. die Kategorie (Kind) rausholen. Die Information Grundhoehe, Bauhoehe und Anzahl optisch unterscheidbarer Lagerstaend kann ich nicht zuordnen. Kann mir jemand sagen, ob die ueberhaupt in haeuser.cod zu finden sind? Wie bist du auf diese Namensgebung gekommen?
Auszug bebauung.hpp
struct Bebauungsinfo
{
uint8_t breite;
uint8_t hoehe;
uint8_t richtungen;
uint8_t ani_schritte;
uint8_t grundhoehe;
uint8_t bauhoehe;
uint8_t lagerstaende;
uint8_t kategorie;
};
Also dass der Galgen keinen sichtbaren Lagerstand hat, überrascht mich eher weniger. Die Grundhöhe dient der Berechnung des Y-Versatzes der Grafik auf dem Bildschirm. Es kann gut sein, dass dieser Versatz in den COD-Dateien direkt gespeichert ist. Die Bauhöhe gibt nur an, ob z.B. ein Soldat darauf oder dahinter gezeichnet wird, d.h. ob es Boden oder etwas anderes ist. Als ich mir das ausgedacht hatte, wusste ich noch überhaupt nicht, dass die Verschlüsselung der COD-Dateien so extrem primitiv ist und hatte die folglich noch nie gesehen.
Die Information Grundhoehe, Bauhoehe und Anzahl optisch unterscheidbarer Lagerstaend kann ich nicht zuordnen. Kann mir jemand sagen, ob die ueberhaupt in haeuser.cod zu finden sind?
Hast du ObjFill
schon implementiert?
Schau dir mal das erste Objekt (Nummer: 0) im HAUS
Objekt Array an. Da sind die ganzen Defaults drin, die dann mittels ObjFill: 0,MAXHAUS
angewendet werden.
Als ich mir das ausgedacht hatte, wusste ich noch überhaupt nicht, dass die Verschlüsselung der COD-Dateien so extrem primitiv ist und hatte die folglich noch nie gesehen.
Primitiv ist gut. Das Dateiformat ist gelinde gesagt gefühltes Chaos mit inkonsistent in der Benutzung zwischen verschiedenen cod Dateien. Da haben sich die Entwickler damals echt ein hartes Brett überlegt. Ich würde gerne mal den original source zum cod parsing sehen! 🙂
Die Information Grundhoehe, Bauhoehe und Anzahl optisch unterscheidbarer Lagerstaend kann ich nicht zuordnen. Kann mir jemand sagen, ob die ueberhaupt in haeuser.cod zu finden sind?
Hast du
ObjFill
schon implementiert? Schau dir mal das erste Objekt (Nummer: 0) imHAUS
Objekt Array an. Da sind die ganzen Defaults drin, die dann mittelsObjFill: 0,MAXHAUS
angewendet werden.
Ja, den objfill hab ich implementiert. Mit genau dieser objfill Zeile konnte ich bis dato aber nix anfangen. Ich vermute mal, dass dieses base Objekt in jedes nachfolgende kopiert wird. Also alle Objekte mit ID 0 bis MAXHAUS. Stichwort inkonsistenz: MAXHAUS ist nirgends definiert 🤮 Meine objfill Implementierung kann quasi sich ein Objekt aktiv holen und einbauen. Der oben genannte objfill unterscheidet sich hier ja grundlegend. Muss ich noch einbauen. Wenn das drin ist, dann könnte es sein, dass die fehlenden Parameter in meiner Frage von oben drin sind. Also nochmal ran 👍
Die Dateien im Rahmen von #15 entfernt worden, da es jetzt einen COD Parser gibt.
Es gibt die Dateien grafiken.txt und bebauung.txt, welche Informationen zum mapping zu den Original spieldateien enthalten. Fragen:
Ziel: Ein self contained Binary ohne andere Abhängigkeiten als das original Spiel. D. H. Pflege der bisherigen txt Dateien im Quellcode mit einer Erkennung, welche Variante von Anno (NINA A, Vanilla) installiert ist bzw. mit Kommandozeileparameter zum auswählen.