|
-
Are you still trying to split the world into several smaller .zen files?
If so, you should have placed the waypoints and run
02_LoA_Weltenteilung.zsl
potentially after minor adjustments. It collects all the vobs within the waypoint polygon and saves them to one .zen file. The remainder is saved to a second file. On this second file, you repeat the process...
-
The world is already divided into several smaller zen (by hand). Now I would just like to insert vobs from the bigzen by iterating the zClevelcompo and the vobs inside of them
-
Just to make it clear: You do not want to follow the way that works but want to do it differently and, if it works, save some time.
Are you aware that there are typically objects that are not children of the level-vobs? (e.g. waypoints) And that in some cases many vobs are not children of level-vobs?
If you can write it yourself:
You probably do not need to create another array
Code:
var string smallZens[n];
smallZens[I] = "smalzenI.zen";
that does not have proper values anyway.
Instead, directly iterate through
Code:
foreach level in allLevels
In the loop, you want to get all children of the level-vob (and their children, and their children,...)
Code:
var selection sel = WLD_GetDescendants(level);
Potentially add the level-vob to the selection
(Maybe you want it, maybe you don't. Maybe it is already part of the selection after WLD_GetDescendants; you need to try it yourself. In that case, you could subtract it with -=
Next you want to save that selection:
Code:
WLD_SaveSelection(worldName,sel);
You still need to create the string worldName. You could use a (self-created) counter variable for that, or you use information from the level-vob. The latter, though intuitively nicer, might go wrong since level-vobs could have "lost" information (e.g. visual).
Afterwards, for each zCVobLevelCompo, you have saved the children to a separate file. Next, you could merge those objects with the files you already created. (WLD_Merge) But that is difficult to do in the same script since it is hard to know beforehand which files should go together.
What you do with the remaining vobs (those not descendants of level-vobs) is up to you. It might be advisable to actually create another selection of all objects (WLD_GetAll()) and then in the loop subtract the objects that you already saved to a .zen. Then you may afterwards save the objects that remain in the selection to a separate file, which then only contains the objects not in other files.
-
I made a try both for single zCLevelCompo zens both for multiple ones. They both work but not exactly as I would like.
First, why can I iterate over an object array, but not return a single value from it?
Code:
var object allLevels[] = CVT_SelToArr(WLD_GetVobsOfClass("zCVobLevelCompo"));
foreach level in allLevels
{
Info(level.visual"); /*valid*/
}
Info(allLevels[0].visual); /*not valid*/
This is the code for a single zen (I don't care about those automatism; since they are not so much I prefer the old one-by-one method)
Code:
#include<stdlib.zsl>
func void main ()
{
WLD_Load("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld.zen");
var object allLevels[] = CVT_SelToArr(WLD_GetVobsOfClass("zCVobLevelCompo"));
var selection vobSel1 = WLD_GetDescendants(allLevels[1]);
var selection vobSel2 = WLD_GetDescendants(allLevels[2]);
var selection vobSel3 = WLD_GetDescendants(allLevels[3]);
var selection vobSel4 = WLD_GetDescendants(allLevels[4]);
Info("level has " + vobSel1.size + " descendants");
Info("level has " + vobSel2.size + " descendants");
Info("level has " + vobSel3.size + " descendants");
Info("level has " + vobSel4.size + " descendants");
WLD_SaveSelection("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_TrollArea_01.zen", vobSel1);
WLD_SaveSelection("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_TrollArea_01.zen", vobSel2);
WLD_SaveSelection("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_TrollArea_01.zen", vobSel3);
WLD_SaveSelection("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_TrollArea_01.zen", vobSel4);
}
This is a try for multiple zCLevelCompo zen. It works because it does copy the vobs from a world to another, but it does not copy zCLevelCompos, and it copies the mesh of the whole world too!!
I tried to solve the zClevelCompo problem with:
Code:
vobSel1 += allLevels[1];
vobSel2 += allLevels[2];
vobSel3 += allLevels[3];
vobSel4 += allLevels[4];
But it crashes like the first problem I encountered, so I tried this way:
Code:
vobSel1 += WLD_GetVobsByVisual("NewWorld_Part_TrollArea_01_P01.3ds");
vobSel2 += WLD_GetVobsByVisual("NewWorld_Part_TrollArea_01_P02.3ds");
vobSel3 += WLD_GetVobsByVisual("NewWorld_Part_TrollArea_01_P03.3ds");
vobSel4 += WLD_GetVobsByVisual("NewWorld_Part_TrollArea_01_P04.3ds");
but it cannot find them :/
-
Zitat von Frank-95
I made a try both for single zCLevelCompo zens both for multiple ones. They both work but not exactly as I would like.
First, why can I iterate over an object array, but not return a single value from it?
Code:
var object allLevels[] = CVT_SelToArr(WLD_GetVobsOfClass("zCVobLevelCompo"));
foreach level in allLevels
{
Info(level.visual"); /*valid*/
}
Info(allLevels[0].visual); /*not valid*/
What happens at the last info?
Zitat von Frank-95
This is a try for multiple zCLevelCompo zen. It works because it does copy the vobs from a world to another, but it does not copy zCLevelCompos, and it copies the mesh of the whole world too!!
You already mentioned the function WLD_LoadWithoutMesh yourself. Did you try using it?
Zitat von Frank-95
I tried to solve the zClevelCompo problem with:
Code:
vobSel1 += allLevels[1];
vobSel2 += allLevels[2];
vobSel3 += allLevels[3];
vobSel4 += allLevels[4];
But it crashes like the first problem I encountered,
While not really a great solution, just skip the level-vob and later merge your .zen which contains vobs but no level with a new .zen that only contains a level vob. (Just use the Spacer to compile that part of the world mesh and then save it without adding further vobs.) You may also try to move all vobs to be children of the new level-vob, but that is not necessary, as far as I know. The function that you could try for it is
Code:
external void WLD_MoveToParent(var object obj, var object newParent)
Zitat von Frank-95
so I tried this way:
Code:
vobSel1 += WLD_GetVobsByVisual("NewWorld_Part_TrollArea_01_P01.3ds");
vobSel2 += WLD_GetVobsByVisual("NewWorld_Part_TrollArea_01_P02.3ds");
vobSel3 += WLD_GetVobsByVisual("NewWorld_Part_TrollArea_01_P03.3ds");
vobSel4 += WLD_GetVobsByVisual("NewWorld_Part_TrollArea_01_P04.3ds");
but it cannot find them :/
Level-vobs are in some way different from other vobs. I was also not able to delete them using zSlang.
EDIT: According to the documentation, arrays start at index 0. You might need to adjust
Code:
var selection vobSel1 = WLD_GetDescendants(allLevels[1]);
var selection vobSel2 = WLD_GetDescendants(allLevels[2]);
var selection vobSel3 = WLD_GetDescendants(allLevels[3]);
var selection vobSel4 = WLD_GetDescendants(allLevels[4]);
-
EDIT: According to the documentation, arrays start at index 0. You might need to adjust
I know. I had previously made a list of every zCLevelCompo visuals of the array. And parts of trollarea.zen are at those indexes.
You already mentioned the function WLD_LoadWithoutMesh yourself. Did you try using it?
Yes I did. It crashes after loading the world (when it tries to call WLD_GetDescendants probably).
EDIT: I made another try, calling only WLD_LoadWithoutMesh, and it makes zSpyCrash, so the problem is in that function
What happens at the last info?
Now it doesn't crash anymore, but I swear that yesterday the execution got always aborted.
Anyway it adds to the zen only one levelcompo (the last one).
Code:
#include<stdlib.zsl>
func void main ()
{
WLD_Load("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld.zen");
var object allLevels[] = CVT_SelToArr(WLD_GetVobsOfClass("zCVobLevelCompo"));
var selection vobSel1 = WLD_GetDescendants(allLevels[1]);
var selection vobSel2 = WLD_GetDescendants(allLevels[2]);
var selection vobSel3 = WLD_GetDescendants(allLevels[3]);
var selection vobSel4 = WLD_GetDescendants(allLevels[4]);
Info(allLevels[1].visual);
Info(allLevels[2].visual);
Info(allLevels[3].visual);
Info(allLevels[4].visual);
vobSel1 += allLevels[1];
vobSel2 += allLevels[2];
vobSel3 += allLevels[3];
vobSel4 += allLevels[4]; //this is the only one levelcompo added to the zen and every vob is children of this
Info("level has " + vobSel1.size + " descendants");
Info("level has " + vobSel2.size + " descendants");
Info("level has " + vobSel3.size + " descendants");
Info("level has " + vobSel4.size + " descendants");
WLD_SaveSelection("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_TrollArea_01.zen", vobSel1);
WLD_SaveSelection("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_TrollArea_01.zen", vobSel2);
WLD_SaveSelection("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_TrollArea_01.zen", vobSel3);
WLD_SaveSelection("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_TrollArea_01.zen", vobSel4);
}
Anyway I will try to save vobs list without mesh hoping that I will be able to make WLD_LoadWithoutMesh work
Geändert von Frank-95 (23.05.2015 um 12:30 Uhr)
-
I don't know whether WLD_LoadWithoutMesh itself causes problems or whether your problems can be fixed directly. But if the complete world mesh bothers you, I see two simple options:
1) Continue doing it the way it is now. Afterwards, open the .zen in the spacer and compile the world. Now only the mesh of the level-vobs still in the .zen remains.
2) Create an empty .zen. In zSlang, first load the empty .zen and then use WLD_Merge to add the objects (but not mesh and lightmaps data) from the complete .zen
Now it doesn't crash anymore, but I swear that yesterday the execution got always aborted.
Anyway it adds to the zen only one levelcompo (the last one).
I do not understand this last sentence. What exactly happens? (And what should happen?)
Are you sure the level-vob actually has descendants? Please check that in the Spacer. The fact that vobs geographically exist in the area is not sufficient, they need to be descendants in the vob-tree.
Note that in your script, you call WLD_SaveSelection with the same file four times, so the file will just be overwritten.
-
Note that in your script, you call WLD_SaveSelection with the same file four times, so the file will just be overwritten.
Damn that was the problem. I Thought the selections would have been just merged, thanks
Anyway I can easily fix the whole mesh problem by just recompile it via macros, thank you again
EDIT: Now as far as I understood, after having saved every zen, I will have to use one of these to save also waynet and pfx that are not children of any levelcompo, right?
Geändert von Frank-95 (23.05.2015 um 14:26 Uhr)
-
Zitat von Frank-95
EDIT: Now as far as I understood, after having saved every zen, I will have to use one of these to save also waynet and pfx that are not children of any levelcompo, right?
If that is what you want, yes. It makes it difficult, however, to make changes e.g. to the waynet. That's why the better way would have been to use the function to split a world (e.g. using waypoint polygons), but that's additional work, of course.
-
Ein weiteres Skript, das für LoA notwendig wurde. Aus einem uns nicht näher bekannten Grund gibt es in manchen unserer .zen Dateien Objekte doppelt; in einer Welt waren sogar fast alle Objekte betroffen.
Bei Vobs eher harmlos, kommt es bei Mobs dazu, dass sie teils nicht benutzt werden können; und Items doppelt eingesammelt werden können. (Also nicht Pilze nebeneinander sondern an exakt derselben Position).
Hier ein Skript, das solche doppelten Objekte findet und löscht. ACHTUNG: Es wird nur die Position überprüft! Theoretisch ist es möglich, dass mehrere Objekte (absichtlich oder zufällig) genau dieselben Koordinaten haben, aber trotzdem alle gebraucht werden.
Code:
#include<stdlib.zsl>
/* This function deletes duplicate objects (including waypoints) */
func void main () {
// name of the .zen
var string world = "test.zen";
// load the world
WLD_Load(world);
// merge waypoints
WLD_MergeWaypoints(); // now no duplicate waypoints left, waynet should be fine, too
// select all other objects
var object allVobs[] = CVT_SelToArr(WLD_GetVobs()); // get all vobs
var int numAtStart = allVobs.size;
Warn("Found " + numAtStart + " vobs before deletion.");
// create an (empty) selection to collect vobs to be deleted
var selection selDelete;
// iterate through allVobs, using an explicit index
for (var int ind = 0; ind < allVobs.size - 1; ind += 1)
{
var object obj = allVobs[ind];
if ((ind % 100) == 0)
{
Info("current index: " + ind);
}
// iterate through all vobs AFTER obj and check whether they are "identical" to obj
for (var int ind2 = ind+1;ind2 < allVobs.size; ind2 += 1)
{
var object obj2 = allVobs[ind2];
// now compare obj and obj2
if (obj.pos == obj2.pos)
{
selDelete += obj2; // add the object to the selection of objects that will be deleted in the end
break;
}
}
}
WLD_DeleteGentle(selDelete);
var object allVobs2[] = CVT_SelToArr(WLD_GetVobs()); // get all vobs with this visual
var int numAtEnd = allVobs2.size;
Warn("Found " + numAtEnd + " vobs after deletion.");
// save the world again. Same name, in output folder
WLD_Save(world);
Warn("execution finished");
}
Das Skript ist nicht das schnellste. Bei einem Teil der LoA-Welt (der Stadt) hat es bei mir etwa 8-9 Minuten gebraucht (~ 16.000 Objekte).
Man könnte den Algorithmus beschleunigen, indem man das Array oder die Selektion vorsortiert, z.B. über die Koordinaten oder euklidische Distanz zum Ursprung. Mir war es den Aufwand nicht wert.
-
Es gab bisher in zSlang keine Möglichkeit, etwas anderes als ZENs zu speichern. Das war ein Problem für mich, weil ich (u.a.) zSlang benutzen wollte, um eine Liste von (z.B.) Vobs zu erstellen und es in einem praktischen Format zu exportieren. Die Umsetzung ist etwas ekelig (zSlang schickt das alles an zSpy und ich parse mir aus der Logdatei von zSpy dann die nötigen Sachen und schreibe sie in Dateien).
Das kann dann z.B. so genutzt werden:
Code:
#include <stdlib.zsl>
#include <zslExport.zsl>
func void main() {
Warn("zSpy");
WLD_Load("E:\Gothic 2 LeGo\_work\data\Worlds\NewWorld\DRAGONISLANDASCII.ZEN");
var selection objs;
var string class;
Exp_Open("Output.txt");
class = "oCItem";
objs = WLD_LoadSubclasses(class);
foreach obj in objs {
Exp_WriteLine("Objekt: "+obj.vobName+"("+obj.className+")");
Exp_WriteLine("Position: "+obj.pos[0]+" "+obj.pos[1]+" "+obj.pos[2]);
var string s; s = rotMatToDirectionString(POS_GetRotMat(obj));
Exp_WriteLine("direction: "+s);
Exp_WriteLine("visual: "+obj.visual);
Exp_WriteLine("ItemInstance: "+obj.itemInstance);
Exp_WriteLine("");
}
class = "Mob";
objs = WLD_LoadSubclasses(class);
foreach obj in objs {
Exp_WriteLine("Objekt: "+obj.vobName+"("+obj.className+")");
Exp_WriteLine("Position: "+obj.pos[0]+" "+obj.pos[1]+" "+obj.pos[2]);
var string s; s = rotMatToDirectionString(POS_GetRotMat(obj));
Exp_WriteLine("direction: "+s);
Exp_WriteLine("visual: "+obj.visual);
Exp_WriteLine("");
}
Exp_Close();
}
func selection WLD_LoadSubclasses(var string class) {
var selection sel; sel = WLD_GetVobs();
foreach obj in sel {
if (!(obj.classHierarchy ~= class)) {
sel = sel - obj;
}
}
return sel;
}
func string rotMatToDirectionString(var float mat[3][3] ) {
var string ret;
ret = ""+mat[2][0]+" "+mat[2][1]+" "+mat[2][2];
return ret;
}
Dazu habe ich ein paar Dateien hinzugefügt. Um ein zSlang-Script auszuführen, dass Text exportieren soll, sollte es mit der zslExport.bat ausgeführt werden. Daher empfehle ich für solche Dateien die Erweiterung *.zse ("zSlang-Export), da man diese Erweiterung dann standardmäßig mit der .bat verknüpfen kann (Rechtsklick -> Eigenschaften -> Öffnen mit [ändern]).
Theoretisch kann man auch jedes beliebige zSlang-Script damit ausführen, allerdings töte ich den zSpy sofort, man sieht also keine Logs (kann sie aber in der zSpyOutput.ze nachschauen).
Link zum Repack von zSlang (enthält die originalen Dateien sowie meinen "Exporter" + Beispiel + zslExport.zsl): https://uripura.de/forum/upload/stat...ng_exporter.7z
Quellcode der Java-Anwendung: https://uripura.de/forum/upload/static/zslExport.7z
Könnte ein Mod ggf. im Startpost verlinken?
Edit: Beispiel im Post verbessert.
Geändert von Lehona (15.07.2015 um 13:39 Uhr)
-
Hi
Since my spacer has recently stopped executing big macros without crashing (it can execute macros on small part but not the the whole newworld), I'm asking whether is there a way to accomplish this via zSlang?
I already did soething like this:
Code:
#include<stdlib.zsl>
func void main ()
{
WLD_LoadMesh("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld.zen");
WLD_Merge("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_City_01.zen");
WLD_Merge("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_Farm_01.zen");
WLD_Merge("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_Forest_01.zen");
WLD_Merge("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_GreatPeasant_01.zen");
WLD_Merge("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_Monastery_01.zen");
WLD_Merge("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_Pass_To_OW_01.zen");
WLD_Merge("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_Ship_01.zen");
WLD_Merge("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_Xardas_01.zen");
WLD_Merge("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld_Part_TrollArea_01.zen");
WLD_Merge("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\WP.zen");
WLD_Save("C:\Program Files (x86)\Gothic 2 Gold\_work\data\Worlds\NewWorld\NewWorld.zen");
};
Which is very practical but can only get vobs changes. What if I had modified the levelmesh too?
I could apply mesh level changes via spacer macros to smaller parts, but then as far as I know I can only load one mesh at a time with zSlang, am I wrong?
-
As far as I know, you are right. zSlang has no way of working with the mesh data, and it does not combine (compiled) mesh data of different .zen. You have to use macros to do that.
-
Ich hätte mal eine frager an all die scripter hier, da ich davon leider keine ahnung hab.
Also Ausgangssituation
ich hab 256 verschiedene world koordinaten
an jedem dieser Koordinaten soll ein Vob gesetzt werden, und zwar OHNE kollision, allerdings mit der windanimation des grasses und einer stärke von 0.001
Diese Grässervobs sollten auch einen Vobnamen haben "Grass_Grünfläche"
wie würde da das script aussehen?
-
Keine Ahnung, ob das auch für das Gras gilt, das du meinst:
- Welt laden
- Koordinaten z.B. in einem Array vorliegen haben (im Skript script selbst) oder extern laden (via C-Programmierung)
- Array durch-loopen
- im Loop neue Vobs erstellen und temporär in Variable speichern (im Konstruktur kannst du bereits deinen Wunschnamen und Koordinaten angeben --> damit du die Vobart aussuchen kannst, gibt es den Konstruktor object WLD_NewVobOfClass(var string vobClass, var string name = "",
var float pos[3] = {0, 0, 0})) - cdDyn-Attribut des object / zCVob / Vob setzen (vob.cdDyn = 0 --> keine Kollision mit dynamischen Vobs)
- eventuell gleiches mit cdStatic tun (bestimmt Kollision mit statischen Objekten wie dem WorldMesh, soweit ich weiß)
- Welt speichern
Eventuell musst du auch eine Selection aus allen Vobs erstellen und diese dann noch der Welt tatsächlich hinzufügen / ihr anhängen. Da bin ich nicht mehr firm.
-
gut. ich teste mal bisschen herum und wenn es klappt nimmt es echt extrem viel arbeit ab
-
Ok hat sehr erfolgreich geklappt der erste test. danke dafür
nun möchte ich ans verfeinern gehen..
die objekte brauchen nun auch eine rotation um ihren eigenen mittelpunkt.. da sie selbst verständlich nicht alle gerade auf der achse liegen.
die rotation eines objects hab ich auch als array vor mir liegen, wie müsste dann der code aussehen wenn ich jedes objekt noch eine bestimmte rotation geben muss?
beispiel Rotation x=1 y=2 z=3
mein aktueller code sieht so aus (hier nun ein aussschnitt)
Code:
var object obj1 = WLD_NewVob("Grass_Ost", {44668.6,86.5829,4325.48});
obj1.visual = "G2O_GRASS5X5.3DS";
Geändert von Ska-Ara (28.07.2016 um 12:04 Uhr)
-
-
-
Verstehe ich das richtig, dass du nur drei Einträge für die Rotation hast? Gothic verwendet intern 3x3-Rotationsmatrizen, wobei die drei Spalten jeweils die Drehung in dieser Achse beinhalten. Ich nehme an, dass deine Werte eine Rotation um die jeweilige Achse in Radians sind? Dann kannst du die richtige Trafo-Matrix berechnen, indem du mit
[1 0 0]
[0 1 0]
[0 0 1]
anfängst und dann nach diesem Muster Stück für Stück die Rotation durchführst. Theta würdest du dann jeweils mit dem entsprechenden Wert (x, y oder z) ersetzen.
[Bild: a6821937d5031de282a190f75312353c970aa2df]
zSlang beherrscht Matrixmultiplikation, darum musst du dir also keine Gedanken machen.
Disclaimer: Ich habe nicht viel Ahnung davon und weiß nicht, ob es nicht auch eine einfachere Möglichkeit gibt.
Edit2: Mit "Rotation durchführen" meine ich das multiplizieren der Startmatrix (oder den Zwischenwerten) mit der jeweiligen Rotationsmatrix. Am Ende kannst du die Matrix dann mit dem Befehl POS_SetRotMat(o, m) für dein Objekt speichern.
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
|
|