Asterix Gaming Guild Logo GeneralXXLXXL 2XXL 3XXXLOlympic GamesXXL EditorToolsOff-TopicXXL RomasteredXXL 2 RemasteredOther GamesModsCaesar's ChallengeUnfair XXLPatchesFan ArtPersonal ArtSpeedrunningMediaRandomizerBETA RomeHSKALPresence AdrienPresence SPQRPresence Mr. RubinshteinSupport Bot Helpdesk

#editor

mrm.77
This is such a fun feature for XXL2, I wonder if it'll be possible to edit squads in OG at some point :TotalKappa:
deathhound246
With the choreokeys tho. When are they in effect? Are they always happening, or just when the player isn't in the fight zone, for example? Their actual fighting "AI" has to come in at some point too
adrientd
I didn't mention, but some of the improvements also work for OG and Arthur.
adrientd
You can have a choreography for when the enemies are way (they do patrolling for example), anf another for when the fight is happening (the enemies approach the hero). But it's possible that for Alice the choreography keys aren't used much, maybe the enemies just approach the hero, or stay in place.
deathhound246
Interesting Just from playing and speedrunning Alice, the general behaviour is; - when player is out of fight zone, enemies wander small distances aimlessly, or just stand still - when player is in fight zone, enemies will approach player to attack OR will look for and catch Alice (if she is "spawned" at the time) I think you are right though about Alice not using choreo keys much. Out of all of the fight zones and squads i've looked at, only 1 or 2 have had more than 1 choreo key
adrientd
Maybe the choreokeys are just ignored and enemies just do what they need to do.
adrientd
Also I noticed that in Spyro almost no spawn points are defined in a squad, maybe they just use beacons?
deathhound246
I'd say likely the same case for Alice. Spawn Points are basically the save points, where there's set locations for around the game map. I've also seen trigger actions where it's acting on a Hero hook, passing a Beacon as a ref value, which I'm assuming is for teleporting
deathhound246
I don't think they are completely ignored though. As I mentioned, I've seen 1 or 2 squads with more than 1 choreokey, so they must still do *something*
pegperegogaucho
@adrientd I'm finally getting to the XXL2 Events, should we also document Events we are not yet sure of what they do? For example ``` { "name": "CKSrvCamera", "category": 1, "id": 3, "events": [ { "id": "0300", "name": "UNKNOWN", "parameter": "UNKNOWN", "dataType": "UNKNOWN" } } ```
adrientd
It depends. If the event is already used in one level, then we could put it in the json, along with the datatype. However, if you found it in the code, we need to be sure that it actually does something and can actually be used. Normally when using the Trigger action, the event/message is sent with as argument a pointer to a union (of bool, int, float, ptr). However there are some events that treat the argument as an int or ptr to an object directly, and these can't be used by a Trigger, and such events should not appear in the editor.
thetomioka
I've started working on Linux compatibility. Doing it on Windows for now, so I can edit stuff and see everything still works directly. I had issues compiling it at first, but those were resolved by commenting out line 42 in one of the files of the json library. Seems like the question to life, the universe and everything is "Which line to comment out to get the XXL Editor to compile".
thetomioka
The OpenGL renderer just works as is I think. I added the one function it has as TODO, but don't know where I'd be able to see a difference in the rendering. Maybe add an option to switch between D3D and OGL on Windows?
thetomioka
Most WinAPI calls were Message Boxes, which I replaced with SDL Message Boxes. Remaining are now the open file dialog, which could be replaced by ImGui FileBrowser and the resource files, which would either need to be stored as separate files or constant strings. I thought I'd let you decide, in case you want to take the changes into your code.
pegperegogaucho
If you are talking about the setBlendColor method, it sets the color to blend with while rendering (for everything, lines, triangles, etc.). It is used to make the different lines/boxes of detectors or bounding boxes have different colors, because normally they are just white
thetomioka
Yes, that's the one. I didn't read through all the other functions, to see if there are more differences, but the rendering looked just fine.
thetomioka
I've added tinyfiledialogs as a dependency and used it for the file dialogs. Set the PE resource loading and GameLauncher to only compile on Windows. Now it should only be the wstrings and creating a CMake config I need to do.
pegperegogaucho
The PE resources are very important and need to be accessible somehow. I believe the editor falls back on loading it from the resources folder? Does that work, did you try that out?
thetomioka
It does use the xec_resources folder. It works. I also changed the loading function to be an optional vector, instead of a set and added proper error messages to all instances of resources being loaded.
thetomioka
`std::optional> GetResourceContent(std::string_view resName) { namespace fs = std::filesystem; static const auto extResDir = fs::path("xec_resources"); static const bool useExternalDir = fs::is_directory(extResDir); // First check for file presence in customized resources directory if (useExternalDir) { const auto path = extResDir / resName; std::ifstream file(path, std::ios::binary | std::ios::ate); if (file) { std::streamsize size = file.tellg(); file.seekg(0, std::ios::beg); std::vector buffer(size); if (file.read(buffer.data(), size)) { return buffer; } } } #ifdef _WIN32 // WINDOWS ONLY: Use the embedded resources const std::string resNameStr(resName); HMODULE hmod = GetModuleHandleA(nullptr); HRSRC rs = FindResourceA(hmod, resNameStr.c_str(), "DATA"); if (rs) { HGLOBAL gl = LoadResource(hmod, rs); if (gl) { void* dataPtr = LockResource(gl); size_t dataSize = SizeofResource(hmod, rs); if (dataPtr && dataSize > 0) { const char* begin = static_cast(dataPtr); const char* end = begin + dataSize; return std::vector(begin, end); } } } #endif // Empty optional on failure return std::nullopt; }`